When you are tasked to create a 3D game that offers unrestricted player movement in unlimited vistas, you will need to come up with ways to provide that open, outdoors perception. A technique that works well is to provide a static background sky that contains elements of the sky that we often take for granted, like clouds, and a color gradient that changes as you move farther away from the horizon. We do this using a construct known as a skybox.
A skybox is a cube that surrounds the game player. The player stands inside the box, and no matter which way he turns, he will see some part of the box as long as it isn't obscured by other in-game objects. The box never rotates, and the sides are always the same distance away from the player no matter how far or how fast he moves. Because of the way the images on the faces of the skybox are created, the player does not have the feeling that he is inside a big cube. The skybox images are on the inside faces of this cube, as you can see in Figure 18.2. The back view has been left out to help illustrate the point.
Figure 18.2: A pictorial skybox.
When using skyboxes, we treat them as if they are infinitely large. Only objects that the player can never reach will look correct, like clouds in the sky or distant mountains. If you limit a player's movement to just viewing from a fixed location, you could even use a skybox for nearby scenery.
Figure 18.3 shows an exploded view of the skybox images and how they relate to each other. Note that the image for the bottom is a black field. If you were depicting an area with a usable view in that direction, you would of course include an appropriate image.
Figure 18.3: An exploded skybox.
To create the illusion that the player is embedded in a large and seamless world, there are two things that you must get right when creating a skybox: seamless, matching adjacent edges and correct perspective.
The edge matching issue is one we are already familiar with from previous texture endeavors.
The perspective issue is a little less obvious when you first consider making skyboxes—but take a look at Figure 18.4. Remember that the skybox is always the same distance away from the player, and the orientation is fixed. The front face, if it happens to be facing north, will always face north, no matter which way the player is facing or looking. This causes a visual problem when viewing the images on the skybox faces.
Figure 18.4: Skybox edge distances.
The image areas that are on the face closest to the player will appear larger than the portions of the image nearest the corners, because the corners are farther away. Figure 18.5 simulates what that would look like.
Figure 18.5: Distorted image.
In order to remove the distortion when the image is viewed in game, we need to distort its appearance outside the game environment in such a way that when the perspective comes into play in game, the image looks natural. Figure 18.6 shows such a predistorted image.
Figure 18.6: Predistorted image.
Each of the six square skybox images should be created with the same resolution. The most common resolution to use is 256 by 256 pixels. The higher the resolution, the better the skybox will look in most cases, but there is a limit beyond which higher skybox image resolution doesn't help the appearance. Because we are always worried about memory used and processing time consumed, we want to make sure we don't go higher than the maximum. If you are interested in using larger skybox images, there is a way to calculate the maximum resolution to use as your upper limit, using this mathematical formula:
maxSkyboxResX = maxScreenResX * 1/tan(FOV/2) maxSkyboxResY = maxScreenResY * 1/tan(FOV/2)
The basic concept is that the smaller the Field of View (FOV), the higher the resolution you will need for the skybox. This is because as the FOV gets smaller, you are looking farther and at a smaller portion of the skybox image. This smaller portion fills the view, and therefore the pixels are larger. Typical first-person point-of-view games use a 90-degree FOV and often have a 60-degree (or even smaller) zoomed-in view for sniper scopes or binoculars.
For example, if our screen resolution is 800 by 600 pixels and our FOV is 90 degrees, then applying our formula yields this:
maxSkyboxResX = 800 * 1/tan(90/2) maxSkyboxResX = 800 * 1/1 maxSkyboxResX = 800
It also follows that we don't need to recompute the Y resolution because it will scale proportionally. So for this 800 by 600 pixel display with a 90-degree FOV, the highest resolution we should use for the skybox images is 800 by 600 pixels, by happy coincidence!
However, if we want to know the deal for the 60-degree FOV that our player's binoculars provide, we need to recompute that value as follows:
maxSkyboxResX = 800 * 1/tan(60/2) maxSkyboxResX = 800 * 1/ 0.57735 maxSkyboxResX = 800 * 1.732 maxSkyboxResX = 1386
For the Y resolution, the value is 1,039. So if you decide to create a high-resolution skybox, you should probably go with nothing larger than 1,280 by 1,024 pixels. (Most games, including Torque, need the image resolution values to be powers of two.)
Personally, I would go with 1,024 by 1,024 as a reasonable compromise for a maximum resolution. These dimensions would apply to all of your skybox panels in a given skybox. The size you eventually choose for your game will in the end be a judgment call, but by using the previous calculations, not just a hopeful stab in the dark.
As with other texture-related issues, there is always the question of where to obtain source material. Once again, you have the option of creating your own by using a digital camera or a camera and scanner combination or by simply drawing your own images.
In this section I will walk you through drawing some clouds on the horizon for your skybox—this is a common sunny-day sort of scene. Low cumulus clouds in the distance peek just above the horizon, all around you.
Open Paint Shop Pro and create a new image by selecting File, New. Fill in the dialog box with 256 for both the height and width of the blank image. Make sure that the color depth is set to 16 million colors (24 bit).
Save this blank file as C:\aEmaga6\control\data\maps\front.png.
Select the Fill tool.
Over in the Materials palette, select the Foreground and Stroke Properties check box, just to the right of the color picker (see Figure 18.7).
Figure 18.7: Foreground and Stroke Properties check box.
When the Materials dialog box opens, click the Gradient tab.
Make sure the value in the Angle window is set to 0, and then click the Edit button.
Set the Gradient scale to have two color markers (they look like little pens) on the bottom side of the scale to approximate the settings shown in Figure 18.8. Do the same for the range modifier (the little diamond on the top).
Figure 18.8: The Gradient scale.
Click the leftmost color marker, and then click in the color picker window to its left.
In the Color dialog box, enter the RGB values as 215, 215, 255, respectively.
In the same manner, set the right-hand marker to 0,0,192.
Click OK and then OK again to close the windows and accept the settings.
Now click the Fill tool in the image to get a gradient like that shown in Figure 18.9.
Figure 18.9: Image with gradient.
Change the Foreground and Stroke Properties check box out of gradient mode and into color mode. Then use the Eye-dropper to set its color to pure white.
Next select the Air Brush tool and set the size to 8, the Hardness and Density to 70, and the Opacity to 15.
Now draw some cloudlike shapes between about half and two-thirds of the way from the top of the image so that you get something like Figure 18.10.
Figure 18.10: Some clouds.
Create three more versions of this image, naming the others "left.png", "right.png", and "back.png" in the same place you saved front.png. Go ahead and make each one different in its own way, if you like.
Make a fifth image that is solid blue, with RGB values of 0,0,192. This color matches the darkest blue in the gradient we made. Name this file "top.png".
Make the sixth and final image and fill it in with black. Name this one "bottom.png".
Now it's time to test out your images.
Locate the file in your Emaga6 map folder called C:\aEmaga6\control\data\maps\sky_day.dml. Make a copy of this file in the same directory and name the copy "sky_book.dml".
Open the sky_book-.dml file with UltraEdit. Change the first six lines to read as follows:
skyfront skyright skyback skyleft skytop skybottom
Save the file.
Open C:\aEmaga6\control\data\maps\book_ch6.mis and locate the line that looks like this:
materialList = "./sky_day.dml";
and replace it with this:
materialList = "./sky_book.dml";
Save the file.
Launch the Emaga6 sample program and enter into the game. Take a look around. Notice the corners? See how your clouds become distorted?
You already know how to fix up the textures so that they join seamlessly, so I'll leave you to do that. Note that you probably don't have to worry about the top edges, because the top image and the top edges of the side images all have the same RGB value—0,0,192.
Also, the bottom doesn't need to be blended either, because it's not going to be visible beneath our terrain. So that just leaves the perspective distortion to fix.
Although we are going to be adjusting for perspective distortion, we aren't going to use the built-in perspective tools in Paint Shop Pro. Instead, we will use the Warp tool.
Open up one of your side images, like the front one, for example.
Choose Effects, Distortion Effects, Warp. Your image will be distorted as shown in Figure 18.11.
Figure 18.11: Applying perspective-correcting warp.
Repeat the warping for all three of the other image files so that you've corrected all of the lateral view images, left, right, front, and back.
Run Emaga6 and check your work.
Now you might find that after you've done the distortion you now have seams again in your skybox. If so, go back and fix the edges.
There you have it! Your very own do-it-yourself skybox!