TSE/GettingStarted/Shaders

From TDN

Contents

TGEA Shader Tutorial

I am going to show you the steps of making shaders for Torque Game Engine Advanced (TGEA). This was something that I always

wanted to know, and I am still learning the art of making shaders. As I learn, I will post new shaders you can make. So let’s

start by making the simplest shader possible in TGEA.


The Simplest Shader


1) Setting up

First things first. Let's go into the folder that stores all of the shader files TGEA reads. I don't know where you put the

TGEA root folder, but I will start with the folder TGEA 1.0.3 Demo (This is the root folder). Be aware that you may have changed

the name of the folder to the name of the game you are making.

Since I downloaded the demo, TGEA is found at C:\Program Files\Torque\TGEA 1.0.3 Demo\ on my computer. Okay, so once you find the root folder, click it. After that, you will see a bunch of other folders, and one of them is named

"shaders". Click that one!

You will then see bunches of .hlsl files. These are the shaders, and if you look at their names, you will notice that some names

end with a "V" and some with a "P". There is no need to do this, but it is best because you will know which file is the Vertex

Shader or the Pixel Shader.

2) Getting some knowledge

You can just follow what I say on this tutorial to create a shader, but it would be good if you at least find out what Vertex

and Pixel shaders are and what they are for (if you don't know already :) ). To get more info, I recommend going to the website stated below. It tells you a lot about shaders, and I also helps you with formulas for things like lighting calculations, etc.

http://www.pieterg.com/Tutorials/

3) Writing your first TGEA "Vertex" Shader (or maybe it's not your first :) )

Okay, first you need to go back to the "shaders" folder that I was talking about earlier (if you're not there already). Open up

some sort of text editor like Notepad. You can use any editor you like. Now we get to write some code :) .

Type this in:

//Define the hlsl file
#define IN_HLSL
#include "shdrConsts.h" //Include the constant values of TGEA

// This makes the world view projection matrix to transform the model position.
uniform float4x4 modelView : register(VC_WORLD_PROJ); 



struct VIN //Create a structure for Vertex Input
{
  float4 Position : POSITION0; //Setup the Position input
};

struct VOUT //Create a structure for Vertex Output
{
  float4 Position : POSITION0; //Create the Position Output
};

//Ah yes, here is the heart of the shader
void main(in VIN IN, out VOUT OUT)
{
//The output position is the result of multiplying the modelView matrix by the Input position. This puts your object on the screen.
    OUT.Position = mul(modelView, IN.Position); 
}

And we have made out first vertex shader! Let us run through the code and explain it.

First you have to define the hlsl file like a header file in C++. The next line includes the file called "shdrConsts.h". This file ties variable constants to all of the major world data (camera position, model position, light position, etc).

Next you create the model view matrix, and you tie it to get the value of register(VC_WORLD_PROJ). Without the shdrConsts.h file, you would have to say register(C0). The C0 register holds the matrix for the world view projection. If you dont know what a world view projection matrix is and what it is for, look at the website I outlined earlier.

You then create the structure for the Input vertex data. This struct just allows the shader to input the position data of the vertex.

After that you create a structure for the output data of the shader. Once again, this simple shader only outputs position data.

Now you create the main part of the shader. NOTE: You must name the function that makes the shader work "main" or the shader file won't compile right. As you can see, the function sets the input ("in") to the VIN structure you created. We named this input IN. We then set the output ("out") to the VOUT structure created earlier. We then named the output variable OUT.

Next is a major part. We output the position of the vertex. If you notice though, we don't just output what is inputted. We take the input position and multiply it by the modelView matrix that we defined before then we send the value out. If you don't do this, the model will look all out of whack.

Well, you should now save the file under the name "SimpleShaderV.hlsl". NOTE: Make sure that the ending extension is hlsl. Remember we should put a V in the name just to remind us that this is the Vertex part of the shader and we should save it in the

"shaders" folder. Next up is the Pixel shader!

4) Writing a TGEA Pixel Shader (man it's gettin' shady out here!)

Okay, next is the pixel shader. This shader outputs a color for each pixel on the screen. You can control what it outputs, and for this simple shader, we are going to make the pixel shader turn the object it is applied to pure blue.

Once again, open up a text editor, and type this in:

struct VOUT //We define the vertex out structure again
{
   float4 Position : POSITION0;
};
struct POUT //We define the pixel output
{
   float4 Color : COLOR0;
};
//The heart of the shader
void main(in VOUT IN, out POUT OUT)
{
    OUT.Color = float4 (0.0f, 0.0f, 1.0f, 1.0f); //Output the color blue
}

Now you have just made your pixel shader. Let run through it!

First we redefine the vertex output. This is done so, in the future, we can get data from the vertex shader. The vertex structure in the pixel shader must be the same as in the vertex shader. In this simple shader though, we don't need any data from the vertex shader.

Next we define the pixel output of the shader. In all shaders, the only thing a pixel shader must output is color (pixels just display color anyways).

We then make our "main" function, and we define the input ("in") as a vertex out structure. Also we define the output ("out") as a pixel structure.

Once we setup those variables, we tell the shader to make the output (the "OUT" variable) a float4 color. We define the color values as 0 for red, 0 for green, 1 for blue, 1 for alpha. Since there is no red or green, but there is blue, the color returned is blue.

The complete vertex / pixel shader is done. Save the file as SimpleShaderP.hlsl. Remember to put the P at the end so we know it's a pixel shader.

Next up, we are going to apply it to an object!

5) Applying the shader to some water

Now that we have our shader ready to go, we are going to apply it to an object. In this tutorial, we are going to apply it to some water. This shader doesn't allow all of the great effects such as rippling or reflection, but it's just to show you the process of making a shader, and importing it into TGEA.

Go back to the TGEA root folder, and this time, click the "demo" folder. Next, click the folder named "client". Click "scripts", and open up the file named "shaders.cs".

Once you open that file, you will see tons of different shader datablocks. At the very top, we are going to add our shader.

Type this in anywhere in the file (it might be better to put it on top so you can have quick access):

new ShaderData(SimpleShader)
{
   DXVertexShaderFile = "shaders/SimpleShaderV.hlsl";
   DXPixelShaderFile    = "shaders/SimpleShaderP.hlsl";
   pixVersion = 1.1;
};

This will allow TGEA to compile and import the shader for your use. Next, we are going to make the water material set your newly made shader as it's shader for rendering!

Go back to the TGEA root folder and once there, click "demo", then "data", then "water", and open the file called "materials.cs".

When you open this file, you will see all of the material datablocks that are used to display some really sweet looking water. Scroll down the file until you see a CostomMaterial called "Water" (right above it should be a comment saying ("Main 2.0 water surface"). You will see a variable in the material called "shader". Change this from "WaterReflectRefract" to your shader "SimpleShader". After that, change the variable called "version" from "2.0" to "1.1". This is done because our shader is pixelshader 1.1 (1.1 instead of 2.0 will allow the shader to show on older graphics cards). After all of this, that material datablock should look something like this:

// Main 2.0 water surface
new CustomMaterial( Water )
{
   texture[0] = "noise02";
   texture[1] = "$reflectbuff";
   texture[2] = "$backbuff";
   texture[3] = "$fog";
   texture[4] = "$cubemap";
   cubemap = Sky_Day_Blur02;
   shader = SimpleShader;
   specular = "0.75 0.75 0.75 1.0";
   specularPower = 48.0;
   fallback = WaterFallback1_1;
   version = 1.1;
};

Yay! Now we get to open TGEA and see our shader. Go into the mission editor, and create a new water object. If everything went well, the water should just be pure blue. I know this may seem corny, but this is the foundation of better shaders you will make in the future. I hope this tutorial helped a lot. Hopefully I or, since this is a wiki, somone else will be able to add some more shader methods to this tutorial.

Until then, Happy Torquing!