Terrain Multitexturing

From GameStudio Wiki

Jump to: navigation, search

terrain multitexturing shader

image:tnmultitexturing0kp.jpg

the terrain needs three textures:

  1. colormap1 - tiling can be specified with entity skill41(u) and skill42(v)
  2. colormap2 - tiling can be specified with entity skill43(u) and skill44(v)
  3. macromap - not tiled - this texture's alpha channel specifies how the first two textures get blended. (the pixelshader additionally adds (signed) this texture's color channels but you could comment out this line if you don't need this.)

with some changes it would also be possible to blend the textures depending on the terrain's slope instead of the alpha channel. adding an additional detailmap or similar things wouldn't be difficult either...

action terrain
{
	my.skill41=float(10);
	my.skill42=float(20);
	my.skill43=float(5);
	my.skill44=float(10);

	my.flare=off;
	my.transparent=off;
	my.material=mat_terrain_multitexture;
}

material mat_terrain_multitexture
{
	effect=
	"
		texture entSkin1;
		texture entSkin2;
		texture entSkin3;

		matrix matWorldViewProj;
		matrix matWorld;
		matrix matWorldView;

		vector vecSunDir;
		vector vecDiffuse;
		vector vecAmbient;
		vector vecLight;
		vector vecFog;
		vector vecSkill41;

		technique multitexture
		{
	 		pass p
			{
				texture[0]=<entSkin1>; // colormap1
				texture[1]=<entSkin2>; // colormap2
				texture[2]=<entSkin3>; // macromap

				magFilter[2]=linear;
				minFilter[2]=linear;
				mipFilter[2]=linear;

				zWriteEnable=true;
 
				vertexShaderConstant[0]=<matWorldViewProj>;
				vertexShaderConstant[4]=<matWorld>;
				vertexShaderConstant[8]=<matWorldView>;

				vertexShaderConstant[16]=<vecSunDir>;
				vertexShaderConstant[17]=<vecDiffuse>;
				vertexShaderConstant[18]=<vecAmbient>;
				vertexShaderConstant[19]=<vecLight>;
				vertexShaderConstant[20]=<vecFog>;

				vertexShaderConstant[64]=<vecSkill41>; //  u_scale1,v_scale1,u_scale2,v_scale2
				vertexShaderConstant[95]=(0.0f,0.0f,0.0f,0.0f);

				vertexShader=
				decl
				{
					stream 0;
					float v0[3]; //position
					float v3[3]; //normal
					float v7[2]; //uv
				}
 				asm
				{
					vs.1.1
					m4x4 oPos,v0,c0			// transform position to clip space

					mul oT0.xy,v7.xy,c64.xy		// output scaled uvs - colormap1
					mul oT1.xy,v7.xy,c64.zw		// output scaled uvs - colormap2
					mov oT2.xy,v7.xy		// output uvs - macromap

					m3x3 r0,v3,c4			// transform normal to world space
					dp3 r0.w,r0,r0			// renormalize it
					rsq r0.w,r0.w
					mul r0,r0,r0.w

					dp3 r0,r0,-c16			// normal.light -> lighting constant
					mul r0.xyz,r0,c17		// modulate against material diffuse color
					add oD0.xyz,r0,c19		// add environment light

					mov r1.w,c20.w			// r1.w=1
					dp4 r0,v0,c10			// distance to camera position
					add r0,r0,-c20.x		// distance-fog_start
					mad r0.x,-r0.x,c20.z,r1.w	// 1-(distance-fog_start)*(1/(fog_end-fog_start))
					max oFog.x,r0.x,c95.w		// clamp with custom max value
				};
				pixelShader=
				asm
				{
					ps.1.3
					def c0,0,0,0,1
					tex t0			// sample colormap1
					tex t1			// sample colormap2
					tex t2			// sample macromap

					lrp r0.rgb,t2.a,t0,t1	// blend t0 with t1 using the alpha channel of t2
					+mov r0.a,c0

					//add r0.rgb,r0,t2_bias	// add(signed) rgb of t2

					mul r0.rgb,r0,v0	// modulate with diffuse vertex lighting
				};
			}
		}
	";
}

another multitexturing example, this time with three tiled textures and with pixel shader version 1.1 for geforce3 compatibility. the blue channel of the macro map controls where the third texture appears.

material mtl_multitexture
{
	effect=
	"
	texture entSkin1;
	texture entSkin2;
	texture entSkin3;
	texture entSkin4;
	matrix matWorldViewProj;
	matrix matWorld;
	matrix matWorldView;
	vector vecSunDir;
	vector vecFog;
	technique multitexture
	{
		pass p0
		{
			Texture[0]=<entSkin1>; // colormap1
			Texture[1]=<entSkin2>; // colormap2
			Texture[2]=<entSkin3>; // colormap3
			Texture[3]=<entSkin4>; // macromap
			magFilter[2]=linear;
			minFilter[2]=linear;
			mipFilter[2]=linear;
			magFilter[3]=linear;
			minFilter[3]=linear;
			mipFilter[3]=linear;
			zWriteEnable=true;
			vertexShaderConstant[0]=<matWorldViewProj>;
			vertexShaderConstant[4]=<matWorld>;
			vertexShaderConstant[8]=<matWorldView>;
			vertexShaderConstant[16]=<vecSunDir>;
			vertexShaderConstant[20]=<vecFog>;
			vertexShaderConstant[64]=(16.0f,32.0f,36.0f,60.0f);	// u_scale1,v_scale1,u_scale2,v_scale2
			vertexShaderConstant[65]=(8.0f,16.0f,0.0f,0.0f);	// u_scale3,v_scale3
			vertexShaderConstant[95]=(0.5f,1.0f,2.0f,0.0f);

			vertexShader=
			decl
			{
				stream 0;
				float v0[3]; //position
				float v3[3]; //normal
				float v7[2]; //uv
			}
			asm
			{
				vs.1.1
				m4x4 oPos,v0,c0 		// transform position to clip space

				m3x3 r0,v3,c4			// transform normal to world space
				dp3 r0.w,r0,r0			// renormalize it
				rsq r0.w,r0.w
				mul r0,r0,r0.w

				dp3 oD0,r0,-c16			// normal.light -> lighting constant

				mov r1.w,c20.w			// r1.w=1
				dp4 r0,v0,c10 			// distance to camera position
				add r0,r0,-c20.x 		// distance-fog_start
				mad r0.x,-r0.x,c20.z,r1.w 	// 1-(distance-fog_start)*(1/(fog_end-fog_start))
				max oFog.x,r0.x,c95.w		// clamp with custom max value

				mul oT0.xy,v7.xy,c64.xy		// output scaled uvs - colormap1
				mul oT1.xy,v7.xy,c64.zw		// output scaled uvs - colormap2
				mul oT2.xy,v7.xy,c65.xy		// output scaled uvs - colormap3
				mov oT3.xy,v7.xy		// output uvs - macromap
			};

			pixelShader=
			asm
			{
				ps.1.1
				def c0,1,1,1,1
				tex t0			// sample colormap1
				tex t1			// sample colormap2
				tex t2			// sample colormap3
				tex t3			// sample macromap

				mov r1,t1
				lrp r0.rgb,t3.a,t0,r1	// blend t0 with t1 depending on t3 alpha
				+mov r0.a,c0

				mov r1.a,t3.b
				lrp r0.rgb,r1.a,r0,t2	// blend the result with t2 depending on t3 blue
				+mov r0.a,c0

				mul r0.rgb,r0,v0	// modulate with diffuse vertex lighting
			};
		}
	}
	technique fallback { pass p0 { } }
	";
}
Personal tools