PS2 Linux Programming
Creating a Sky Box
Introduction
This tutorial will illustrate the creation of a Sky Box to provided the illusion of an outside environment. A textured box will be created with the camera located at the centre of the box. The sky box will always be drawn in the background (infinite z) allowing all other objects in the scene to be rendered in front of the box. Half skyboxes and Sky domes (half sphere) can also be used if it is known that the ground-geometry will obscure the lower part of the world at all times. In typical outdoor scenes there is generally no point of rendering the sky below the ground.
Technical Details
The textures used on the skybox have to fit together to create the illusion of a continuous world. This can be quite a challenge (although it might be possible to find some free skyboxes online). In this tutorial a simple star field texture is used which is easy to match at the edges. The same texture is used on each face of the box for simplicity.
The skybox must not obscure the other geometry in the scene. A good way to accomplish this is to start the scene rendering by drawing the skybox – remember, that at the start of the game loop the z-buffer and the frame buffer are cleared. When the skybox is drawn, z-buffer writing is turned off to make sure that the sky box is drawn at infinite z. The z-buffer is then turned back on to draw the rest of the scene. Since the skybox will not write to the z-buffer it does not matter where it is placed, as long as it is between the near and far clip planes.
A box with sides made from 32 triangles seems to work fine. This gives enough polygon resolution to prevent clipping and other visual artefacts. A suitable skybox is illustrated in the diagram below:
Typically, the camera is placed at the centre of the skybox and the skybox moves along with the camera. This means the sky will not get any closer or further away as the camera moves. The skybox however does not rotate with the camera so that when the camera rotates the sky appears to remain static within the scene giving the correct visual illusion. This arrangement is accomplished by extracting the position of the camera from the camera matrix and using that as the position to render the sky box. The orientation part of the sky box matrix always remains as the identity matrix ensuring that it is static in space.
The Example Code
In the provided code (main.cpp) the 3d model for the sky box (box16.txt) and the skybox texture (stars.bmp) are loaded during the initialisation phase of the program. The first thing that is rendered is the sky box and before this is done, z-buffer writes are turned off using the following code:
VIFDynamicDMA.StartDirect();
VIFDynamicDMA.StartAD();
VIFDynamicDMA.AddAD(TEST_SET(0, 0, 0, 0, 0, 0, 0, 1), TEST_1);
VIFDynamicDMA.EndAD();
VIFDynamicDMA.EndDirect();
This code sends data to the TEST register using Address + Data (AD) in direct mode. The TEST_SET macro is:
TEST_SET(ATE, ATST, AREF, AFAIL, DATE, DATM, ZTE, ZTST)
In this context, the important parameters are ZTE and ZTST. ZTE is set to 0 which turns depth testing off and ZTST is set to 1 which specifies that all pixels pass the depth test.
Next the sky box is rendered with the following code. The sky box world matrix is set to the identity matrix then the positional components of the skybox matrix are extracted from the camera position. This ensures that the camera is located at the centre of the skybox. Note that during the creation of the skybox within the 3D modelling package, the origin of the box is set as the centre of mass of the box.
Matrix4x4 matSkyBox;
matSkyBox = Matrix4x4::IDENTITY;
Vector4 SkyBoxPosition = Pipeline.GetCameraPosition();
matSkyBox(3,0) = SkyBoxPosition.x;
matSkyBox(3,1) = SkyBoxPosition.y;
matSkyBox(3,2) = SkyBoxPosition.z;
Box16.SetWorldMatrix(matSkyBox);
Box16.Render();
Following rendering of the sky box, the z buffer must be re-enabled and this is accomplished with:
VIFDynamicDMA.StartDirect();
VIFDynamicDMA.StartAD();
VIFDynamicDMA.AddAD(TEST_SET(0, 0, 0, 0, 0, 0, 1, 3), TEST_1);
VIFDynamicDMA.EndAD();
VIFDynamicDMA.EndDirect();
In this situation ZTE is set to 1 which turns depth testing on and ZTST is set to 3 which specifies that pixels with z values greater that z buffer values pass the depth test – this being the normal rendering mode for z buffer testing.
Once the sky box has been rendered, the rest of the objects in the scene can be rendered in the normal manner.
Running The Applications
On running the application a sky box is drawn round a race track and car. The car moves round the track under its own control and the sky box illusion is observed.
This is a very basic implementation of a sky box and there are many more developments that can be included. The tutorial does however illustrate the basic rendering requirements for a sky box and it is left up to the reader to expand and extend the application.
Dr Henry S Fortuna
University of Abertay Dundee