NewHexen - NHSKY.EXE : Sky Shaders



1. What are they
The sky shaders is a new feature that replaces the original Hexen2 sky. It allows map makers to create their own skies and distribute them with their maps. These new skies are completely different from the original sky in Hexen2. You can make a standard skybox like in Quake2 or Heretic2, or you can make a more complex skybox with mountains, one or more layers of clouds (that can scroll), sun, moon, etc

2. How do they work
The sky shaders written as a text file (in notepad or any other text editor that save plain text .txt files) then compiled with NHSKY.EXE (included with NewHexen) which results in a sky.shader file that goes in skies/mysky.
When making a map, if you sepcify a "skyshader" "mysky" field in worldspawn, it will load skies/mysky/sky.shader.
Substitute "mysky" with whatever name you want.
Use a name not likely to be used by someone else, to avoid having two maps using two different skies that have the same name.
If no "skyshader" key is set, it will take the default sky (skies/default/sky.shader).

3. Shader Syntax
Here is a description of the syntax of the sky shader text file:
In the shader file, whatever follows // in a line is a comment and is ignored by the compiler and whatever enclosed
between /* and */ are comments as well.


//This is a comment
/*and so is this*/

A sky shader consists of one or more texture shaders and one or more objects

3.1 Texture shaders
At least one texture shader is required.
These are used to set the properties of the textures used such as which the .tga file, scrolling speed and direction, etc


shader "shader_name"
{
	{
		//1st texture shader pass definition
	}
	{
		//2nd texture shader pass definition
	}
	//...
}

A texture shader contains 1 to 8 shader pass definitions.
Whenever the engine draws a polygon, it draws it for each of the texture shader passes.
Each shader pass defines a texture, blending (transparency) settings, scrolling options, etc.
A multi-pass texture shader is used to superimpose several textures on one polygon.

3.2 Texture shader pass definition
A pass is defined like this:


{
    texture="filename";         //required

//All the others are optional. Only texture is required.

    scroll='speed_x speed_y';   //cloud scrolling
    blend=src dst;              //blend mode, use the same constants as in OpenGL
                                //like GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA,etc
    blend;                      //same as blend=GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA
    depth=func;                 //depht func. Use openGl constants such as GL_LEQUAL
    depth;                      //same as depth=GL_LEQUAL
    alpha=func ref;             //alpha func. Func takes one of OpenGL constants such as
                                //GL_GREATER, and ref takes a number between 0 and 1
    alpha;                      //same as alpha=GL_GREATER 0.666
    color='r g b a';            //vertex color. To enable it you must use the modulate
                                //parameter below. I am not sure whether i implemented
                                //this one.
    modulate;                   //Vertex color is interpolated accros the polygon surface
                                //and blended with texture color.
                                //Not sure if i implemented it.
}

3.3 Objects
The objects are what is rendered by the sky engine. 3 types of objects are available: cube, face and dome.

3.3.1 Cube
The cube creates a 2x2x2 cubic box centered at the origin.
The cube is composed of 1 to 6 sides (6 make a complete cube, less make an open cube)


cube
{
    side ft{ shader="sft"; }    // front side
    side bk{ shader="sbk"; }    // back side
    side lf{ shader="slf"; }    // left side
    side rt{ shader="srt"; }    // right side
    side up{ shader="sup"; }    // up side
    side dn{ shader="sdn"; }    // down side
}

side xx{...} are the sides of the cube.
The shader="shader_name" part tells which texture shader is used for that side.
Scale the cube to the desired size (see object modifiers below)

3.3.2 Face
Creates a 2x2 horizontal square which is the same as the bottom face as the cube object Translate and rotate it into the desired position (see object modifiers below)


face
{
    shader="shader_name";   //which shader to use
}

//Another variant allows you to have an arbitrary face:

face
{
    shader="shader_name";

    vertex{ xyz='1.2 2.3 3.4'; st='0.0 1.0'; };
    vertex{ xyz='4.5 5.6 6.7'; st='0.0 1.0'; };
    vertex{ xyz='7.8 8.9 9.1'; st='0.0 1.0'; };
}

A face can have any number (at least 3) coplanar vertices forming a convex polygon.
The xyz='...' part in the vertex definition are the x y and z coordinates of the vertex.
st are the texture s and t texture coordinates (they range from 0 to 1)

0 1 ----- 1 1
|           |
|  texture  |
|           |
0 0 ----- 1 0

3.3.3 Dome
The dome object creates a dome, typically used to make clouds.


dome
{
    shader="shader_name";
    polys='x y'             //x = number of vertical slices in the dome
                            //y = number of sections
                            //(like if you were cutting a pie in y parts)
                            //makes x*y polygons for the dome
                            //if omitted, defaults to x=4 and y = 8
    s='u v'                 //texture coordinates. Flatten the dome to a disk,
                            //and put it in
    t='u v'                 //a square. Texture coordinates map that way:
                            //u and v range from 0.0 to 1.0
}

su-tv-----sv-tv
|             |
|             |
|             |
su-tu-----sv-tu


Scale the dome to the appropriate size (see object modifiers below)

3.4 Object modifiers
Object modifiers are used to scale, translate and rotate object into the desired position
Include them in the object definition.
NOTE: The order in which you put them is important.
Rotate and then translate is not the same as translate then rotate.
Same with translate->scale and scale->translate. This is because rotation and scaling is done around
the coordinate system origin, not the object origin.
Works like usual 3D transformation (OpenGL, Direct3D, pov-ray, etc)


scale='x y z';      //or scale=x; (this one is uniform scaling, same for x, y, and z)
translate='x y z';
rotate='x y z';     //x is rotation angle around x axis, y around y axis and
                    //z around z axis
                    //if more than one rotation axis is used, they are porformed
                    //in the x y z order that is, x rotation is done,
                    //then y rotation then z
                    //its like doing rotate='x 0 0' then '0 y 0' then '0 0 z'

4. Conclusion
Not much to say here. Be creative and create cool skies!
But be careful, too many polygons and framerate will drop.
A suggestion to make a nice sky is: