Creating a Skybox

*Quake III engine* was designed so that the sky could appear to emit light in a natural way. Generally speaking when it comes to skyboxes, thanks to netradiant-custom you only really need two shaders properties.

In the Quake 3 engine, creating a skybox involves the use of shaders to define how the sky should be rendered. A skybox is essentially a textured cube which usually emits light and surrounds the game world seamlessly.

### Skybox Textures

   - First, you need the textures for the skybox. These are typically six separate images, one for each face of the cube (front, back, left, right, top, bottom, i.e. sky\_bk.tga sky\_dn.tga sky\_ft.tga sky\_lf.tga sky\_rt.tga sky\_up.tga). These images should be 1024x1024 or 2048x2048 in size, generally speaking. There are also a lot of skyboxes already available in JKA/MBII as well as some nice resources linked below for either making your own or generating a skybox.

### Shader Script

   - Create a shader script (a text file with a .shader extension) that defines how the skybox textures should be applied. This script is placed in the "shaders " folder. You can also of course add this to a pre-existing .shader if one already exists. Just remember if it is a new .shader you need to update your shaderlist.txt file and refresh your shaders for it to show up.

### Shader Code

Once you have these 6 images you will need to make a shader that will make them display correctly in the game world. Below is a simple sky shader.

```
textures/float/thesky
{
 qer\_editorimage textures/skies/sky
 surfaceparm nomarks
 surfaceparm sky
 surfaceparm noimpact
 surfaceparm nodlight
 surfaceparm nolightmap
 notc
 skyParms textures/float/thesky 1024 -
}

```
**Lines 1-12:** These lines list how it is displayed in the editor and give it its attributes. It is the body of the shader.

**Line 01:** This path is what the game uses to determine what shader to use. This will also affect what texture set this shader gets loaded as. This does not have to be the same name as the texture you are using in the shader.

**Line 02:** This bracket is very important. It opens the main body for the shader commands.

**Line 03:** This line only effects what gets displayed in the editor. It is needed for a sky shader because it shows a small image that says SKY instead of a really big image.

**Line 04:** This will make the it so that no decal marks from explosions and laser blasts are left on the sky box.

**Line 05:** This tells the engine that this is sky.

**Line 06:** This will stop explosions from impacting on this surface. Such as missiles and lasers.

**Line 07:** This line stops dynamic lights from hitting the skybox.

**Line 08:** This will tell the engine that this shader does not have a lightmap stage.

**Line 09:** This will make the texture uncompressed. This is good because skyboxes can look pretty nasty if the images are compressed. I use TGAs which solve the problem entirely but at a cost of texture memory and PK3 space.

**Line 10:** This tells the engine where to find the 6 images. You should put the path to your skybox images here. The next number is the cloud height. This is only used if you have a cloud layer. So leave it at whatever. The last - is non-functional. It was supposed to be like a portalsky kind of but it never got coded.

**Line 11:** This bracket will close the shader. It is very important that you remember this. If you forget it, it will mess up all the shaders that are in front of it.

That explains to you how to make a basic sky shader that does not emit light. Now if you want a sky that emits light then you will need to add a few more lines to the shader.

Lets take a look at the same shader that is shown in above with the added lines to make it emit light.

```
textures/texturedirectory/skyname
{
 qer\_editorImage textures/skies/sky
 surfaceparm nomarks
 surfaceparm sky
 surfaceparm noimpact
 surfaceparm nodlight
 surfaceparm nolightmap
 q3map\_skylight  150 4 0 90 0
 q3map\_sunExt 1 0.84 0.61 200 152 14 2 8
 notc
 nopicmip
 skyparms textures/texturedirectory/texturedirectory 2048 -
}

```

* **Line 04-08** These are surfaceparms to give your shader the right surface properties, things like having blaster fire go through, no dynamic lighting or blaster marks. surfaceparm sky is the most important of these as it lets the compiler know this is a skybox.
* **Line 09 - \_skylight:** This gives additional ambient lighting control for your skybox bake. This is good to use if you are looking to make shadows smoother.
	+ amount - The first # in this shader is the brightness value, similar to what you would use in q3map\_sun. Good values are between 50 and 200.
	+ iterations - An exponential factor. 3 is the best value that balances speed and quality. Values of 4 and 5 are higher quality at the expense of higher compile time. I'll use high levels for a final compile.
	+ horizon\_min horizon\_max - Two spherical angles, defining portion of sphere to emit light from. Default is *0 90*, which is upper hemisphere. *-90 90* would be the whole 'sphere' (meaning the lower part of the skybox emits light as well)
	+ sample\_color - Default = 1: sample color of each individual light from skybox images, if they are present. 0: use shader color, which you would need to set via `q3map_lightRGB`/`q3map_lightImage`
		- Essentially what this does is 'leaks' the color from the skybox textures onto your map. This can really help make a sunset feel realistic in how the colors from the skybox leak onto the map, but sometimes the effect is too much.
* **Line 10 - \_sunExt:** This directive in a sky shader will create the illusion of light cast into a map by a single, infinitely distance parallel light source (sun, moon, hellish fire, etc.). The real trick is to play with the parameters for deviance and samples (the last 2 numbers). If done well, this gives you much more realistic shadows from the sun, especially when trying to simulate a cloudy day or a wide sun. The penumbra effect can also be applied to entity lights (point, spot or sun) with the \_deviance N (distance in world units for point/spot lights and degrees for suns) and \_samples N (number of samples) key/value pairs.
	+ The first 3 values are Red Green Blue color values
	+ The 4th value is the *amount* of light that it casts.
	+ The 5th line is the sun's heading. This is the direction that the light will come from in a degree value.
	+ The 6th line is the sun's altitude. This is also in degrees ranging from 90 to -90, 0 being the horizon and 90 up and -90 down.
	+ The 7th value is the deviance, the number of degrees for the half-shadow. General values up to 2 or 3 are acceptable. The real sun has a solid angle of about half a degree.
	+ The 8th value is the samples, which are the number of random jitters distributed over the solid arc (~16).

### The relationship between sunExt and \_skylight

This is the most important aspect for tweaking the feel of the light.

Higher numerical values in \_skylight will diffuse the lighting more, giving a softer "cloudy" vibe. If you want to have harsh shadows, keep the power of this relatively low. Netradiant Custom has a nice new feature within \_skylight which allows the actual colors of the skybox to blend into the map as well as give you control of which areas of the skybox SHOULD iluminate the map. This takes a bit of guess-and-check to get how you like, but offers much more control than previous map editors had with how you want to light the map. You can even have two \_skylight settings, one for the top part of your map and one for the bottom!

The "sun" gives a strong directional light, but doesn't give the fill light needed to soften and illuminate shadows. Skies with clouds should have a weaker q3map\_sunExt value and a higher q3map\_skylight value. Heavy clouds diffuse light and weaken shadows. The opposite is true of a cloudless or nearly cloudless sky. In such cases, the "sun" or "moon" will cast stronger shadows that have a greater degree of contrast.

Note: older skybox shaders might use q3map\_surfacelight still. This is not necessary for Netradiant-Custom, you can achieve great results with just \_sunExt and \_skylight.