Simple HLSL Shader Tutorial

From GameStudio Wiki

Jump to: navigation, search

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

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

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

block.jpg 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
 }

block+shadow.jpg

 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
 }

add.jpg 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
 }

sub.jpg 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
 }

mad.jpg 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
 }

block+shadow+alpha+grass.jpg 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
 }

lrp.jpg 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
 }

lrp2.jpg 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
 }

red.jpg 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
 }

ff_shift.jpg 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;
 }
Personal tools