sampler2D Lightmap1 : register(s0); sampler2D Lightmap2 : register(s1); sampler2D Lightmap3 : register(s2); sampler2D weightingtex : register(s3); sampler2D detail0bump : register(s4); sampler2D detail1bump : register(s5); sampler2D detail2bump : register(s6); sampler2D detail3bump : register(s7); sampler2D detailbasebump : register(s8); float2 detail0scale; float2 detail1scale; float2 detail2scale; float2 detail3scale; float2 detailbasescale; float detail0distance; float detail1distance; float detail2distance; float detail3distance; float detailbasedistance; float4 fSpecValues; float4 bumpAltNormal; float4 ComputeDot3LightmapLightingSpec(float3 normal, float3 lightDir, float3 eyeDir, float4 lightContrib, float specExp) { float fDot; fDot = max(dot(normal, lightDir) , 0.0); return lightContrib * fDot; } struct PS_IN { float2 UV0 : TEXCOORD0; float2 UV2 : TEXCOORD2; float3 EyeDir : TEXCOORD3; float EyeDist : TEXCOORD4; float Depth : TEXCOORD5; }; float4 ps_main( PS_IN In ) : COLOR { const float3 vLightDir1 = float3(0.816497, 0.000000, 0.577350); const float3 vLightDir2 = float3(-0.408248, 0.707107, 0.577350); const float3 vLightDir3 = float3(-0.408248, -0.707107, 0.577350); // sample all lightmaps float4 cLightmap1 = tex2D(Lightmap1, In.UV2); float4 cLightmap2 = tex2D(Lightmap2, In.UV2); float4 cLightmap3 = tex2D(Lightmap3, In.UV2); // lookup our weightmaps float4 weighting = tex2D(weightingtex, In.UV0); // diffuse color float4 cNormalMap, d0, d1, d2, d3; // lookup basedetail texture if (In.EyeDist < detailbasedistance) { cNormalMap = tex2D(detailbasebump,In.UV0 * detailbasescale); } // lookup detailtextures and mix the color if (In.EyeDist < detail0distance) { d0 = tex2D(detail0bump, In.UV0 * detail0scale); cNormalMap = lerp(cNormalMap, d0, weighting.a); } if (In.EyeDist < detail1distance) { d1 = tex2D(detail1bump, In.UV0 * detail1scale); cNormalMap = lerp(cNormalMap, d1, weighting.r); } if (In.EyeDist < detail2distance) { d2 = tex2D(detail2bump, In.UV0 * detail2scale); cNormalMap = lerp(cNormalMap, d2, weighting.g); } if (In.EyeDist < detail3distance) { d3 = tex2D(detail3bump, In.UV0 * detail3scale); cNormalMap = lerp(cNormalMap, d3, weighting.b); } if (In.EyeDist < detailbasedistance || In.EyeDist < detail0distance || In.EyeDist < detail1distance || In.EyeDist < detail2distance || In.EyeDist < detail3distance) { cNormalMap.xyz = normalize(cNormalMap.xyz * 2.0f - float3(1.0f, 1.0f, 1.0f)); } else { cNormalMap.xyz = bumpAltNormal; } // eye direction vector float3 vEyeNorm = normalize(In.EyeDir); float4 vAccum; vAccum = ComputeDot3LightmapLightingSpec(cNormalMap.xyz, vLightDir1, vEyeNorm, cLightmap1, fSpecValues.y); vAccum += ComputeDot3LightmapLightingSpec(cNormalMap.xyz, vLightDir2, vEyeNorm, cLightmap2, fSpecValues.y); vAccum += ComputeDot3LightmapLightingSpec(cNormalMap.xyz, vLightDir3, vEyeNorm, cLightmap3, fSpecValues.y); return In.Depth * vAccum; }