Sky Box for DX11 using Terragen
In this article we will look at some of the issues involved in creating a skybox using Terragen Classic. A skybox is just a cube model with a texture mapped applied to it such that the texture appears to be an infinitely distant sky effect when viewed from the center of the cube.
To generate the textures we need to set our renderer to create square images with a 90 degree frustum. This ensures that the texture seamlessly tiles between the different faces. To set the camera in Terragen, go to camera settings and set the Zoom to 1.0
Generate a terrain and sky that you think will integrate nicely with your foreground elements. Think about how this will affect shadows and the like. A low bright sun in the sky will look dramatic in the skybox by maybe hard to work with in game if it is intended to be the primary light source.
I like to add a little haze using the atmosphere controls in Terragen as this results in a softer light which matches more closely the rendering techniques I'm using.
To generate the textures we need to set our renderer to create square images with a 90 degree frustum. This ensures that the texture seamlessly tiles between the different faces. To set the camera in Terragen, go to camera settings and set the Zoom to 1.0
Generate a terrain and sky that you think will integrate nicely with your foreground elements. Think about how this will affect shadows and the like. A low bright sun in the sky will look dramatic in the skybox by maybe hard to work with in game if it is intended to be the primary light source.
I like to add a little haze using the atmosphere controls in Terragen as this results in a softer light which matches more closely the rendering techniques I'm using.
Terragen ScriptingTerragen has a handy scripting feature that takes any guesswork out of setting the cameras. I created a script that renders 5 faces. North, East, South, West and Up. I decided I would not need a ground texture as I will be rendering my own 3D landscape.
The script looks like this: initanim "c:\junk\skyrender_north", 1 :_north Zoom 1.0 CamH 0 CamP 0 CamB 0 frend initanim "c:\junk\skyrender_east", 1 :_east Zoom 1.0 CamH 90 CamP 0 CamB 0 frend initanim "c:\junk\skyrender_south", 1 :_south Zoom 1.0 CamH 180 CamP 0 CamB 0 frend initanim "c:\junk\skyrender_west", 1 :_west Zoom 1.0 CamH 270 CamP 0 CamB 0 frend initanim "c:\junk\skyrender_up", 1 :_up Zoom 1.0 CamH 0 CamP 90 CamB 0 frend |
Rendering
- I generated a simple plane using 2 triangles that is unit length in size and has texture coordinates.
{
-0.5f, 0.5f, 0.5f, 0.0f,0.0f,
0.5f, 0.5f, 0.5f, 1.0f,0.0f,
-0.5f,-0.5f, 0.5f, 0.0f,1.0f,
0.5f, 0.5f, 0.5f, 1.0f,0.0f,
0.5f,-0.5f, 0.5f, 1.0f,1.0f,
-0.5f,-0.5f, 0.5f, 0.0f,1.0f, };
- I transform this plane in code to generate the faces of the cube and render with the correct texture.
g_d3d11DevCon->PSSetSamplers(0, 1, &mTex[3].mSampleState);
g_d3d11DevCon->PSSetShaderResources(0, 1, &mTex[3].mTexture);
m = XMMatrixRotationY(DEGTORAD(-90))*mat; //this is the west face, I have to render all 5 obviously...
mCbPerObj.WVP = XMMatrixTranspose(m);
g_d3d11DevCon->UpdateSubresource( mConstBuffer, 0, NULL, &mCbPerObj, 0, 0 );
g_d3d11DevCon->VSSetConstantBuffers( 0, 1, &mConstBuffer );
g_d3d11DevCon->PSSetConstantBuffers( 0, 1, &mConstBuffer );
g_d3d11DevCon->Draw( 6, 0 );
- Set the Texture wrap mode to clamp, rather than wrap to eliminate seams along the edges of the box
- Set culling to something that makes sense. Typically we look at things from the outside and cull faces that are facing away from the camera, but with a skybox we are inside the geometry so we would want to front face cull. Or just disable culling all together.
- Render without lighting! Use a simple shader with no lighting.
- When you generate your texture maps, use a texture mode without alpha and don't generate mipmaps. These won't be needed so we can gain a little performance and space here.