Simple HLSL Shader Tutorial
From GameStudio Wiki
SimpleHLSLShaderTutorial The 3DGS-Project can downloaded here: http://people.freenet.de/a6world/SimpleHLSLShaderTutorial.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 SimpleHLSLShaderTutorial.zip
Here are our four textures, stone, shadow, alpha and grass. The following code parts are the HLSL code 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
This and the next code is stupidly, because the engine do this just without shader.
PS_OUT ps( PS_IN In )
{
PS_OUT Out = ( PS_OUT ) 0; // Declare your output
float4 color; // Declare your needed variables
color = tex2D( sBase, In.Base.xy ); // Get color of the texture sBase at the position In.Base.xy
Out.Color = color; // Write the output
return Out; // and give it back
}
PS_OUT ps( PS_IN In )
{
PS_OUT Out = ( PS_OUT ) 0; // Declare your output
float4 color; // Declare your needed variables
float4 shadow;
color = tex2D( sBase, In.Base.xy ); // Get color of the texture sBase at the position In.Base.xy
shadow = tex2D( sShadow, In.Shadow.xy ); // ..
color = color * shadow; // and apply the shadow
Out.Color = color; // Write the output
return Out; // and give it back
}
Adding the alpha to the stone texture.%%%
PS_OUT ps( PS_IN In )
{
PS_OUT Out = ( PS_OUT ) 0; // Declare your output
float4 color; // Declare your needed variables
float4 alpha;
color = tex2D( sBase, In.Base.xy ); // Get color of the texture sBase at the position In.Base.xy
alpha = tex2D( sAlpha, In.Alpha.xy ); // ..
color = color + alpha; // and add the alpha
Out.Color = color; // Write the output
return Out; // and give it back
}
Subtract the alpha to the stone texture.
PS_OUT ps( PS_IN In )
{
PS_OUT Out = ( PS_OUT ) 0; // Declare your output
float4 color; // Declare your needed variables
float4 alpha;
color = tex2D( sBase, In.Base.xy ); // Get color of the texture sBase at the position In.Base.xy
alpha = tex2D( sAlpha, In.Alpha.xy ); // ..
color = color - alpha; // and subtract the alpha
Out.Color = color; // Write the output
return Out; // and give it back
}
Multiply stone with shadow and adding alpha.%%%
PS_OUT ps( PS_IN In )
{
PS_OUT Out = ( PS_OUT ) 0; // Declare your output
float4 color; // Declare your needed variables
float4 shadow;
float4 alpha;
color = tex2D( sBase, In.Base.xy ); // Get color of the texture sBase at the position In.Base.xy
shadow = tex2D( sShadow, In.Shadow.xy ); // ..
alpha = tex2D( sAlpha, In.Alpha.xy ); // ..
color = (color * shadow) + alpha; // multiply stone with shadow and adding alpha
Out.Color = color; // Write the output
return Out; // and give it back
}
Multiply the stone with the grass texture, and adding the multiply from stone with shadow.
You can see the shadow is not affecting the grass, because it is not multiplied with it.
PS_OUT ps( PS_IN In )
{
PS_OUT Out = ( PS_OUT ) 0; // Declare your output
float4 color; // Declare your needed variables
float4 shadow;
float4 alpha;
float4 grass;
color = tex2D( sBase, In.Base.xy ); // Get color of the texture sBase at the position In.Base.xy
shadow = tex2D( sShadow, In.Shadow.xy ); // ..
alpha = tex2D( sAlpha, In.Alpha.xy ); // ..
grass = tex2D( sGrass, In.Grass.xy ); // ..
color = (color * shadow) + (alpha * grass); //
Out.Color = color; // Write the output
return Out; // and give it back
}
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. Then you can apply the shadow texture.%%%
PS_OUT ps( PS_IN In )
{
PS_OUT Out = ( PS_OUT ) 0; // Declare your output
float4 color; // Declare your needed variables
float4 shadow;
float4 alpha;
float4 grass;
color = tex2D( sBase, In.Base.xy ); // Get color of the texture sBase at the position In.Base.xy
shadow = tex2D( sShadow, In.Shadow.xy ); // ..
alpha = tex2D( sAlpha, In.Alpha.xy ); // ..
grass = tex2D( sGrass, In.Grass.xy ); // ..
color = lerp( color, grass, alpha); // Interpolates between color and grass via alpha
color = color * shadow; // and apply the shadow
Out.Color = color; // Write the output
return Out; // and give it back
}
Same as above, just the alpha texture is inverted. Just put an 1- before the variable.%%%
You can negate it with an - too. invert: 1-variable negate: -variable
PS_OUT ps( PS_IN In )
{
PS_OUT Out = ( PS_OUT ) 0; // Declare your output
float4 color; // Declare your needed variables
float4 shadow;
float4 alpha;
float4 grass;
color = tex2D( sBase, In.Base.xy ); // Get color of the texture sBase at the position In.Base.xy
shadow = tex2D( sShadow, In.Shadow.xy ); // ..
alpha = tex2D( sAlpha, In.Alpha.xy ); // ..
grass = tex2D( sGrass, In.Grass.xy ); // ..
color = lerp( color, grass, 1-alpha); // Interpolates between color and grass via inverted alpha
color = color * shadow; // and apply the shadow
Out.Color = color; // Write the output
return Out; // and give it back
}
Coloring your output.
PS_OUT ps( PS_IN In )
{
PS_OUT Out = ( PS_OUT ) 0; // Declare your output
float4 color; // Declare your needed variables
float4 shadow;
float4 alpha;
float4 grass;
float4 modcolor;
modcolor = float4(1,0,0,0); // Set your color
color = tex2D( sBase, In.Base.xy ); // Get color of the texture sBase at the position In.Base.xy
shadow = tex2D( sShadow, In.Shadow.xy ); // ..
alpha = tex2D( sAlpha, In.Alpha.xy ); // ..
grass = tex2D( sGrass, In.Grass.xy ); // ..
color = lerp( color, grass, alpha); // Interpolates between color and grass via alpha
color = color * shadow; // and apply the shadow
color = color * modcolor; // and modify with your color
Out.Color = color; // Write the output
return Out; // and give it back
}
Shifting the alpha texture with vertexshader
Just add the line Out.Alpha.y to the vertexshader.
VS_OUT vs( VS_IN In )
{
VS_OUT Out = ( VS_OUT ) 0; // Declare your output
Out.Pos = mul( In.Pos, matWorldViewProj ); // Transform the ouput to the view
Out.Shadow = In.Shadow; // Get the shadow texture for the current position
Out.Base = In.Base; // Get the level texture for the current position
Out.Alpha = In.Base; // Cause alpha/grass texture have no current positions (they ar not applied to level geo)
Out.Grass = In.Base; // we use the positions of the level texture
Out.Alpha.y = In.Base.y - 0.5; // Shift the alpha to the bottom
return Out;
}
