uniform extern float4x4 WorldViewProj : WORLDVIEWPROJECTION; uniform extern float4x4 ViewProj : WORLDVIEWPROJECTION; uniform extern float Time; uniform extern bool Rippling; uniform extern float LightLevel; uniform extern float Light0Brightness; uniform extern float3 Light0Position; uniform extern float Light1Brightness; uniform extern float3 Light1Position; uniform extern float Light2Brightness; uniform extern float3 Light2Position; uniform extern float Light3Brightness; uniform extern float3 Light3Position; uniform extern texture DiffuseTexture; uniform extern texture LightMapTexture; uniform extern texture ColourMap; struct WorldVsOutput { float4 Position : POSITION; float2 DiffuseTextureCoordinate : TEXCOORD0; float2 LightMapTextureCoordinate : TEXCOORD1; float3 SourcePosition: TEXCOORD2; }; sampler DiffuseTextureSampler = sampler_state { texture = ; mipfilter = POINT; mipmaplodbias = -1; magfilter = POINT; addressu = WRAP; addressv = WRAP; }; sampler LightMapTextureSampler = sampler_state { texture = ; mipfilter = LINEAR; minfilter = LINEAR; magfilter = LINEAR; addressu = CLAMP; addressv = CLAMP; }; sampler ColourMapSampler = sampler_state { texture = ; addressu = CLAMP; addressv = CLAMP; }; WorldVsOutput WorldTransform(float4 Position : POSITION0, float2 DiffuseTextureCoordinate : TEXCOORD0, float2 LightMapTextureCoordinate : TEXCOORD1) { WorldVsOutput Out = (WorldVsOutput)0; // Transform the input vertex position: Out.Position = mul(Position, WorldViewProj); // Copy the other values straight into the output for use in the pixel shader. Out.DiffuseTextureCoordinate = DiffuseTextureCoordinate; Out.LightMapTextureCoordinate = LightMapTextureCoordinate; Out.SourcePosition = Position; return Out; } float4 WorldApplyTexture(WorldVsOutput vsout) : COLOR { // Start with the original diffuse texture coordinate: float2 DiffuseCoord = vsout.DiffuseTextureCoordinate; // If the surface is "rippling", wobble the texture coordinate. if (Rippling) { float2 RippleOffset = { sin(Time + vsout.SourcePosition.x / 32) / 8, cos(Time + vsout.SourcePosition.z / 32) / 8 }; DiffuseCoord += RippleOffset; } // Apply Quake-style dynamic lighting. float Brightness = 1 - ( (tex2D(LightMapTextureSampler, vsout.LightMapTextureCoordinate).r * LightLevel) + (Light0Brightness / distance(vsout.SourcePosition, Light0Position)) + (Light1Brightness / distance(vsout.SourcePosition, Light1Position)) + (Light2Brightness / distance(vsout.SourcePosition, Light2Position)) + (Light3Brightness / distance(vsout.SourcePosition, Light3Position)) ); // Calculate the colour map look-up coordinate from the diffuse and lightmap textures: float2 ColourMapIndex = { tex2D(DiffuseTextureSampler, DiffuseCoord).a, Brightness, }; // Look up and return the value from the colour map. return tex2D(ColourMapSampler, ColourMapIndex).rgba; } technique World { pass P0 { vertexShader = compile vs_2_0 WorldTransform(); pixelShader = compile ps_2_0 WorldApplyTexture(); } }