Cg Programming/Unity/Shading in World Space

This tutorial introduces uniform parameters. It assumes that you are familiar with, , and.

In this tutorial we will look at a shader that changes the fragment color depending on its position in the world. The concept is not too complicated; however, there are extremely important applications, e.g. shading with lights and environment maps. We will also have a look at shaders in the real world; i.e., what is necessary to enable non-programmers to use your shaders?

Transforming from Object to World Space
As mentioned in, the vertex input parameter with semantic  specifies object coordinates, i.e. coordinates in the local object (or model) space of a mesh. The object space (or object coordinate system) is specific to each game object; however, all game objects are transformed into one common coordinate system — the world space.

If a game object is put directly into the world space, the object-to-world transformation is specified by the Transform component of the game object. To see it, select the object in the Scene View or the Hierarchy Window and then find the Transform component in the Inspector Window. There are parameters for “Position”, “Rotation” and “Scale” in the Transform component, which specify how vertices are transformed from object coordinates to world coordinates. (If a game object is part of a group of objects, which is shown in the Hierarchy Window by means of indentation, then the Transform component only specifies the transformation from object coordinates of a game object to the object coordinates of the parent. In this case, the actual object-to-world transformation is given by the combination of the transformation of an object with the transformations of its parent, grandparent, etc.) The transformations of vertices by translations, rotations and scalings, as well as the combination of transformations and their representation as 4×4 matrices are discussed in.

Back to our example: the transformation from object space to world space is put into a 4×4 matrix, which is also known as “model matrix” (since this transformation is also known as “model transformation”). This matrix is available in the uniform parameter, which is automatically defined by Unity in this way: Since it is automatically defined, we don't need to define it (actually we must not). Instead we can use the uniform parameter  without definition in the following shader:

Usually, the application has to set the value of uniform parameters; however, Unity takes care of always setting the correct value of predefined uniform parameters such as ; thus, we don't have to worry about it.

This shader transforms the vertex position to world space and gives it to the fragment shader in the output structure. For the fragment shader, the parameter in the output structure contains the interpolated position of the fragment in world coordinates. Based on the distance of this position to the origin of the world coordinate system, one of two colors is set. Thus, if you move an object with this shader around in the editor it will turn green near the origin of the world coordinate system. Farther away from the origin, it will turn dark grey.

More Unity-Specific Uniforms
There are several built-in uniform parameters that are automatically defined by Unity similarly to the  matrix. Here is a short list of uniforms (including ) that are used in several tutorials:

For the official list of Unity's built-in uniforms, see the section “Built-in shader variables” in Unity's manual.

Some of these uniforms are actually defined in the file  which is automatically included since version 4.0 of Unity.

There are also some built-in uniforms that are not automatically defined, e.g., which is defined in. Thus, we have to either define it explicitly (if it is needed): or include the file with its definition: or include a file that includes, e.g: Unity does not always update all of these uniforms. In particular,  and   are only set correctly for shader passes that are tagged appropriately, e.g. with   as the first line in the   block; see also.

User-Specified Uniforms: Shader Properties
There is one more important type of uniform parameters: uniforms that can be set by the user. Actually, these are called shader properties in Unity. You can think of them as user-specified uniform parameters of the shader. A shader without parameters is usually used only by its programmer because even the smallest necessary change requires some programming. On the other hand, a shader using parameters with descriptive names can be used by other people, even non-programmers, e.g. CG artists. Imagine you are in a game development team and a CG artist asks you to adapt your shader for each of 100 design iterations. It should be obvious that a few parameters, which even a CG artist can play with, might save you a lot of time. Also, imagine you want to sell your shader: parameters will often dramatically increase the value of your shader.

Since Unity's description of shader properties is quite good, here is only an example, how to use shader properties in our example. We first declare the properties and then define uniforms of the same names and corresponding types.

With these parameters, a non-programmer can modify the effect of our shader. This is nice; however, the properties of the shader (and in fact uniforms in general) can also be set by scripts! For example, a C# Script attached to the game object that is using the shader can set the properties with these lines: returns the  component. (You could also write (less efficient)  or   .) Use   if you want to change the parameters for all objects that use this material and just   if you want to change the parameters only for one object. (But be aware that  might create a new instance of the material, which is not automatically destroyed when the game object is destroyed!) With scripting you could, for example, set the   to the position of another object (i.e. the   of its Transform component). In this way, you can specify a point just by moving another object around in the editor. In order to write such a script, select +/Create > C# Script in the Project Window and name it ShadingInWorldSpace and copy & paste this code: Then, you should attach the script to the object with the shader (e.g., by dragging & dropping the script over the object) and drag & drop another object to the  variable of the script in the Inspector Window. Now you can change the value of the  variable of the material by changing the position of the other object.

Summary
Congratulations, you made it! We discussed:
 * How to transform a vertex into world coordinates.
 * The most important Unity-specific uniforms that are supported by Unity.
 * How to make a shader more useful and valuable by adding shader properties.