Simple Pixel Shader Tutorial

From GameStudio Wiki

Jump to: navigation, search

SimplePixelShaderTutorial


The 3DGS-Project can downloaded here: http://freenet-homepage.de/a6world/pst1.zip

If you extend this tutorial please use the same style at the bottom. Please with screenshot. If another screenshot/project is needed i will upload it. Contact "Rigoletto" at the 3DGS-Forum.


Following examples use the project in the pst1.zip

block.jpg shadow.jpg alpha.jpg grass.jpg


Here are our four textures, stone, shadow, alpha and grass. The following code parts are the PixelShaderCode in asm that will shown in the picture beside. Remember we will use the textures in following tex-channels:

stone in Texture 0, which is provided in entSkin1 (the applied level texture in WED) shadow in Texture 1, which is provided in entSkin2 (the rendered shadow by the WED-Compiler) alpha in Texture 2, which must be loaded with bmap grass in Texture 3, which must be loaded with bmap


tx are texture registers (0 - 3)
They are for storing textures.
rx are result registers (0 and 1)
The result in r0 will be rendered.
cx are constant registers (0 - 7)
Can be used to hold an color for an operation.

block.jpg

This and the next code is stupidly, because the engine do this just without shader.

ps.1.0
define the version of the pixelshader that you have the code written for.
tex t0
gets texture data for process.
mov r0, t0
just move the texture in the result register. This result is what you see.
pixelshader = asm
{
      ps.1.0
      tex t0
      mov r0, t0
};

block+shadow.jpg

mul r0, t0, t1
multiply the stone with the shadow texture.
r0 = t0 * t1
stone * shadow
pixelshader = asm
{
      ps.1.0
      tex t0
      tex t1
      mul r0, t0, t1
};

add.jpg

add r0, t0, t2
adding the alpha to the stone texture.
r0 = t0 + t2
stone + alpha
pixelshader = asm
{
      ps.1.0
      tex t0
      tex t2
      add r0, t0, t2
};

sub.jpg

sub r0, t0, t2
subtract the alpha to the stone texture.
r0 = t0 - t2
stone - alpha
pixelshader = asm
{
      ps.1.0
      tex t0
      tex t2
      sub r0, t0, t2
};

mad.jpg

mov r0, t0
because the shader can only use 3 different textures register at the same time we must move t0 into r0.
mad r0, t0, t1, t2
multiply stone with shadow and adding alpha.
r0 = t0
r0 = (r0 * t1) + t2
(stone * shadow) + alpha
pixelshader = asm
{
      ps.1.0
      tex t0
      tex t1
      tex t2
      mov r0, t0
      mad r0, r0, t1, t2
};

block+shadow+alpha+grass.jpg

mul r1, t0, t1
multiply the stone with the grass texture.
mad r0, t2, t3, r1
multiply stone with shadow and adding the result from the operation before.
r1 = t0 * t1
r0 = (t2 * t3) + r1
(stone * shadow) + (alpha * grass)

You can see the shadow is not effecting the grass, because it is not multiplied with it.

pixelshader = asm
{
      ps.1.0
      tex t0
      tex t1
      tex t2
      tex t3
      mul r1, t0, t1
      mad r0, t2, t3, r1
};

lrp.jpg

mov r1, t3
mov grass into r1.
lrp r0, t2, r1, t0
Linear interpolation between the stone and the grass texture. Looks similarly to the code above but the blending is better.
The colors are not changed by the alpha texture.


mul r0, r0, t1

Now you can apply the shadow texture.

pixelshader = asm
{
      ps.1.0
      tex t0
      tex t1
      tex t2
      tex t3
      mov r1, t3
      lrp r0, t2, r1, t0
      mul r0, r0, t1
};

lrp2.jpg

Same as above, just the alpha texture is inverted. Just put an 1- before the register.

You can negate it with an - too.

invert: 1-t2
negate: -t2
pixelshader = asm
{
      ps.1.0
      tex t0
      tex t1
      tex t2
      tex t3
      mov r1, t3
      lrp r0, 1-t2, r1, t0
      mul r0, r0, t1
};

red.jpg

def c0, 1, 0, 0, 0%%%
Define a constant with a rgba value of a color.
...
mul r0, r0, c0%%%
Coloring the result in r0 with the color from c0.
pixelshader = asm
{
      ps.1.0
      def c0, 1, 0, 0, 0
      tex t0
      tex t1
      tex t2
      tex t3
      mov r1, t3
      lrp r0, 1-t2, r1, t0
      mul r0, r0, t1
      mul r0, r0, c0
};

ff_shift.jpg


Shifting the alpha texture with FF

Just put this lines into the pass, and set the values. The number in the square brackets identify the texture.

 TextureTransformFlags[2] = Count2; // Select shifting and set matrix values
 TextureTransform[2] = 	{
			     1.0, 0.0, 0.0, 0.0, // xscale, rotate, ------, ------
			     0.0, 1.0, 0.0, 0.0, // ------, yscale, ------, ------
			     0.0, 0.5, 0.0, 0.0, // xshift, yshift, ------, ------
			     0.0, 0.0, 0.0, 0.0  // ------, ------, ------, ------
			};
Personal tools