Hatching Shader

From GameStudio Wiki

Jump to: navigation, search

This shader needs 6 grayscale hatch patterns ranging from very sparse (well-lit) to very dense (unlit) as input. you have to save them in the color channels of the two tgas like described here:

hatch123.tga

  • r - 1 (very sparse)
  • g - 2
  • b - 3

hatch456.tga

  • r - 4
  • g - 5
  • b - 6 (very dense)

the light comes from the sun direction.

bmap bmp_hatch123=<hatch123.tga>;
bmap bmp_hatch456=<hatch456.tga>;

function mtl_hatch_init
{
	bmap_to_mipmap(mtl.skin1);
	bmap_to_mipmap(mtl.skin2);
}

material mtl_hatch
{
	skin1=bmp_hatch123;
	skin2=bmp_hatch456;
	event=mtl_hatch_init;
	effect
	"
	texture mtlSkin1;
	texture mtlSkin2;
	matrix matWorldViewProj;
	matrix matWorld;
	vector vecSunDir; 

	technique hatch
	{
		pass p0
		{
			texture[0]=<mtlSkin1>;
			texture[1]=<mtlSkin2>; 

			vertexShaderConstant[16]=<matWorldViewProj>;
			vertexShaderConstant[20]=<matWorld>;
			vertexShaderConstant[32]=<vecSunDir>; 

			vertexShaderConstant[48]=(2.0,2.0,0.0,0.0); // u_scale, v_scale, 0, 0
			vertexShaderConstant[49]=(6.0,6.0,6.0,1.0); // brightness 

			vertexshader=
			decl
			{
				stream 0;
				float v0[3]; // position
				float v3[3]; // normal
				float v7[3]; // uv
			}
			asm
			{
				vs.1.1 

				def c0,0,0,0,0
				def c1,1,1,1,1
				def c2,2,2,2,2
				def c3,3,3,3,3
				def c4,4,4,4,4
				def c5,5,5,5,5
				def c6,6,6,6,6
				def c7,7,7,7,7 

				m4x4 oPos,v0,c16	// transform position to clip space  

				mul oT0.xy,v7.xy,c48.xy	// output scaled uvs
				mul oT1.xy,v7.xy,c48.xy	// output scaled uvs 

				m3x3 r3,v3,c20		// transform normal to world space
				dp3 r3,r3,-c32		// normal.light -> light factor
				mul r3,r3,c4		// brightness 

				mov r5.x,c5.x		// seed blend weights
				mov r5.y,c4.x
				mov r5.z,c3.x
				mov r5.w,c0.x 

				mov r6.x,c2.x
				mov r6.y,c1.x
				mov r6.z,c0.x
				mov r6.w,c0.x 

				sub r5,r3,r5	// sub each weight's initial value from the light factor
				sub r6,r3,r6 

				max r5,r5,c0	// ged rid of everything below zero
				sge r7,c2,r5	// flag weights that are <= 2
				mul r5,r5,r7	// zero out weights > 2
				sge r7,r5,c1	// flag weights that are >= 1
				mul r7,r7,c2	// subtract all weights that are greater than or equal to one from 2
				sub r5,r7,r5
				slt r7,r5,c0	// flag all weights that are < 0 and negate
				sge r8,r5,c0	// flag all spots that are >= 0
				add r7,-r7,r8	// add the flags
 				mul r5,r5,r7	// should negate negatives and leave positives

				max r6,r6,c0	// repeat for second set of weights
				sge r7,c2,r6
				mul r6,r6,r7
				sge r7,r6,c1
				mul r7,r7,c2
				sub r6,r7,r6
				slt r7,r6,c0
				sge r8,r6,c0
				add r7,-r7,r8
				mul r6,r6,r7

				sge r8,c1,r3	// check for total shadow and clamp on the darkest texture
				mov r7,c0
				mov r7.z,r8.z
				add r6,r6,r7
				min r6,r6,c1 

				mov oT2.xyz,r5	// output 123 weights to uv3
				mov oT3.xyz,r6	// output 456 weights to uv4
			};
	 		pixelshader=
			asm
			{
 				ps.1.1
				tex t0			// sample t0
				tex t1			// sample t1
				texcoord t2		// get 123 weights
				texcoord t3		// get 456 weights
				dp3_sat r0,1-t0,t2	// t0.t2_weights
				dp3_sat r1,1-t1,t3	// t1.t3_weights
				add_sat r0,r0,r1	// r0+r1
				mov_sat r0,1-r0		// complement and saturate
			};
		}
	}
	";
}
Personal tools