//=================================================================================================== // Uniform Variables //=================================================================================================== float4x4 ViewProj; float4x4 World; float invMapWidth; float terrainHeightScale; float terrainScaleMinY; float3 positionXZ, positionX1Z, positionXZ1, positionX1Z1; float2 texCoordX1Z, texCoordXZ1, texCoordX1Z1; float3 edge1, edge2, normal; //- heightMapTexture -- texture heightMapTexture; sampler heightMapTextureSampler = sampler_state { texture = ; AddressU = MIRROR; AddressV = MIRROR; AddressW = MIRROR; MIPFILTER = ANISOTROPIC; MINFILTER = ANISOTROPIC; MAGFILTER = ANISOTROPIC; }; //=================================================================================================== // Uniform, Varying, and FrameBuffer Stream Structures - // Used to Communicate between CPU, VertexProcessor, FragmentProcessor, and FrameBuffer //=================================================================================================== struct VertexInput { float4 position : POSITION0; // Position float4 texCoord : TEXCOORD0; // Texture coordinates }; struct VertexOutput { // These values are used directly by the rasterizer float4 position : POSITION; // Position float4 texCoord : TEXCOORD0; // Texture coordinates (example: TEXCOORD0) }; struct FragmentInput { float4 color : COLOR0; // Color (example: COLOR0) float4 texCoord : TEXCOORD0; // Texture coordinates }; struct FragmentOutput { float4 color : COLOR0; // Color for render target n }; //=================================================================================================== // Vertex and Fragment Shaders //=================================================================================================== // Helper functions //-------------------------------------------------------------------------------------------------- float GetTerrainHeight(float2 texCoord) { return (tex2D(heightMapTextureSampler, texCoord).r); } // Generate Terrain Normals Main //-------------------------------------------------------------------------------------------------- VertexOutput VS_GenerateTerrainNormals(VertexInput IN) { VertexOutput OUT = (VertexOutput)0; OUT.position = mul(IN.position, mul(World, ViewProj)); OUT.texCoord = IN.texCoord; return OUT; } FragmentOutput FS_GenerateTerrainNormals(FragmentInput IN) { FragmentOutput OUT = (FragmentOutput)0; // Set up the texture coordinates needed texCoordX1Z = float2(IN.texCoord.x + invMapWidth, IN.texCoord.y); texCoordXZ1 = float2(IN.texCoord.x, IN.texCoord.y + invMapWidth); texCoordX1Z1 = float2(IN.texCoord.x + invMapWidth, IN.texCoord.y + invMapWidth); // Set up the necessary position vectors positionXZ = float3( IN.texCoord.x, GetTerrainHeight(IN.texCoord.xy), IN.texCoord.y); positionX1Z = float3( texCoordX1Z.x, GetTerrainHeight(texCoordX1Z), texCoordX1Z.y); positionXZ1 = float3( texCoordXZ1.x, GetTerrainHeight(texCoordXZ1), texCoordXZ1.y); positionX1Z1 = float3( texCoordX1Z1.x, GetTerrainHeight(texCoordX1Z1), texCoordX1Z1.y); // Calculate edge vectors for first triangle on this fragment edge1 = positionXZ1 - positionXZ; edge2 = positionXZ - positionX1Z1; // Calculate the normal based on these two edges normal = cross(edge2, edge1); OUT.color.xyz = normal; // Calculate edge vectors for the second triangle on this fragment edge1 = positionXZ - positionX1Z; edge2 = positionX1Z - positionX1Z1; // Calculate the normal based on the two new edges normal = cross(edge2, edge1); OUT.color.xyz += normal; // Normalize and then save normal data to texture OUT.color.xyz = normalize(OUT.color.zyx); OUT.color.a = 1.0f; return OUT; } //=================================================================================================== // Techniques //=================================================================================================== // Generate Terrain Normals technique //-------------------------------------------------------------------------------------------------- technique GenerateTerrainNormals { pass Pass0 { VertexShader = compile vs_3_0 VS_GenerateTerrainNormals(); PixelShader = compile ps_3_0 FS_GenerateTerrainNormals(); // Alpha blending AlphaBlendEnable = true; SrcBlend = SrcAlpha; DestBlend = InvSrcAlpha; FillMode = Solid; } }