ShaderLab Tutorial 1, Page 1

Picture

This tutorial is going to assume that you've gained some experience in using the ShaderLab editor (you should easily get to grips with the editor from the documentation and help file), and that now you want some ideas and guidance as to how to write productive shaders.

This tutorial aims to do exactly that - to help you get used to thinking about shaders, how they work, and how you might go about coding your first shaders. It’s designed for the complete beginner, and tries to explain some of the maths involved, as well as telling you how to code it in ShaderLab. Don't worry - the maths needn't be as bad as you think!


SOME TERMS
So you can understand what I’m saying, I’d better explain some things. Throughout this tutorial, I'll be referring to trueSpace as tS, and ShaderLab as SL, simply because it’s easier to type.

In the tutorial text, I'll be using the word "colour", but in any code that I write, I use "color". I'm more comfortable with "colour", since I'm from the UK, but decided to use the US spelling in the code just to keep things consistent with other SL shaders.

Picture

HOW TS RENDERS
It's worth going over how tS renders, tol help you understand when your code runs, what it has access to, and how you can achieve the effects you’re looking for. This is a simple and non-technical explanation, for three reasons :


   1. To make it easier to follow
   2. It's actually all you need to start coding shaders
   3. It's as much as I know myself!
 

I’m fully responsible for any errors in this, and if anyone has any corrections or additions, feel free to e-mail me! Okay, on with the description of how ts renders :

During rendering, tS sends out a ray to find out how to colour the pixel on your screen that tS is currently dealing with. If this ray contacts an object, then code is run to find out what colour that point on the object's surface is. This code is what we call a shader, and it is this code that you can create in SL.

Notice that your shader code is NOT called for the entire object, but is called separately every time a ray contacts a point painted with that shader. This is an important issue. You might think that your shader zooms over the entire object, colouring it all over as it goes, but this is not the case. After all, this would be rather wasteful of processor time, since large parts of the object may not be even be visible in the finished image!

This is rather different from coding graphics in a programming language, as there you can write code that decides WHICH pixel it’s about to colour. In SL, however, you are only ever deciding the colour for the CURRENT point. You do not choose what point on an object's surface is being coloured, nor what pixel on screen is being coloured.

So, your shader code will run whenever tS has to decide the colour of an individual point on an object's surface (including when the point is visible reflected in another object, or visible through a transparent object). If you bear this in mind, it will help you see how to achieve whatever result it is that you are after.

Let’s have a look at a diagram :
 

Illustration of how tS renders.

This diagram shows rays being cast from the camera, for the middle of the screen (if you were to render from the camera’s viewpoint).

As tS renders this line, the first points are going to be the background colour. This is represented by Ray 1, which doesn’t intercept any object, and so will return the background colour (black, in this case).

Then the rays intercept the cube object, as shown by the example Ray 2. The shader code will run for the point on the object’s surface which Ray 2 comes into contact with.

The same shader code runs again for the other points intercepted on the object’s surface, such as for Ray 3. Notice that the code runs separately for Ray 2 and Ray 3. Also notice that Ray 2 can only colour that particular point on the object’s surface - it can’t access colours or other properties from other points on the object.

Keeping these ideas in mind will help when writing your shader code.

Picture

WHAT DO YOU WANT TO CODE TODAY?
Before you start to write your shader, it's worth considering just what sort of shader you want to write. Basically a shader comes down to modifying some attribute of a material in relation to some other value, so let's look at the basics of what you can modify, and what sort of things you can use to control the changes. These lists aren't complete, but cover the ones you're most likely to want to use when just starting out with writing shaders.
 


"INPUT" DATA - INFO AVAILABLE TO YOUR SHADER
When your shader code runs, it will have access to all sorts of information about the point on the object (the current shading point), about the object itself, and about the current frame of the animation.

You can use this sort of information to modify the output from your shader. This section lists the basic sort of "input" information you can use. Note that the term "input data" is just one that I'm using to give you a framework to start thinking about shaders - it's not a term you'll see anywhere else (in the SL documentation, or in other articles about writing shaders, for instance)


Info : Position Of The Current Shading Point In Relation To The Object.
Variables : P and UV
Description : Contains the co-ordinates of the current point in 3D space, in relation to the object.

These are probably the most common variables that you'll use. If you're looking to make a wood texture, or checkers, or random noise, or any sort of pattern across the surface of an object, then these are the variables you'll want to be using.

If you want to work with the UV space, then U and V are the variables to use. These ALWAYS lie between 0 and 1 (that is, U lies between 0 and 1, and V lies between 0 and 1). This is true no matter how much you scale, distort or deform the object.

P stores the current shading point's position with reference to the object itself. P is what’s known as a vector - it’s made up of 3 parts, all contained under the name of P. The three parts have names of their own, and perhaps not surprisingly these parts are called x, y and z, referring to the 3 axes in 3D space.

You access these parts by using the main name, which is P in this case, followed by a dot and then the name of the part, like this :

    P.x accesses the x co-ordinate
    P.y accesses the y co-ordinate
    P.z accesses the z co-ordinate

For simple primitives, all 3 values lie between 0 and 1. If you scale the object equally in all directions, then this remains true. However, for more complex objects, or objects that get deformed, the values in P may not lie between 0 and 1. You don't need to worry about that too much just now, though.

One thing to note here is that since P can change with deformations, animated deformations could cause unwanted results with a shader based on P, as the texturing could change as the object deforms. You'll have to think about the sort of effects you want to create with the shader, and the sort of uses it will be put to, when deciding whether to use U and V or P.



Info : Position Of The Current Shading Point In Relation To The Scene.
Variables : Pw
Description : Contains the co-ordinates of the current point in 3D space, relative to the scene rather than to the object.

Just like P, this is a vector variable, and contains the 3 parts x, y and z, accessed in just the same way :

    Pw.x for the x co-ordinate
    Pw.y for the y co-ordinate
    Pw.z for the z co-ordinate

Because this is based on the world co-ordinates, this means that the texture will change as the object moves about in the scene. With the object in a different place, you'll get a different texture on its surface, as Pw will contain different values depending on the object’s location in the 3D world.



Info : Current Frame In An Animation
Variables : ActiveTime
Description : Contains the number of the current frame.

NOTE : as with all shaders that animate over time, the preview sphere in tS material panel will only show the result of the shader in the current frame when you selected that animated shader.

 


Info : Distance From Camera
Variables : ModI
Description : Contains the distance between the viewpoint and the current shading point.

Naturally, this will change as the camera or object move. It is this variable that is used for Distance Transparency, for example.

Be aware that when calculating transparency for shadow casting purposes, ModI becomes meaningless, as tS is no longer using a ray cast from the viewing location, but a ray cast from a light source. ModI does not have meaningful values in this situation.

Also, bear in mind that the preview sphere in tS material panel won't necessarily show anything meaningful either, and your shader will have a very different result within your scene.

Finally, there may be unpredictable results if used with an orthagonal view - that is, one of the views from directly above, in front or from the side of an object - since these views (unlike a camera or perspective view) do not really have a position in the 3D world of the scene.

Picture

SHADERLAB INTRO PAGE

NEXT PAGE