//-------------------------------------------------------------------------------------- // Shader resources //-------------------------------------------------------------------------------------- Buffer g_Height; Texture2D g_Normal; Texture2D g_Diffuse; // Material albedo for diffuse lighting //-------------------------------------------------------------------------------------- // Constant buffers //-------------------------------------------------------------------------------------- cbuffer cbConstant { float4 g_LightDir; // Object space int g_TerrainRes; int g_TerrainQuadRes; }; cbuffer cbChangesEveryFrame { matrix g_World; matrix g_WorldViewProjection; float g_Time; }; cbuffer cbUserChanges { }; //-------------------------------------------------------------------------------------- // Structs //-------------------------------------------------------------------------------------- struct PosNorTex { float4 Pos : SV_POSITION; float4 Nor : NORMAL; float2 Tex : TEXCOORD; }; struct PosTexLi { float4 Pos : SV_POSITION; float2 Tex : TEXCOORD; float Li : LIGHT_INTENSITY; }; struct PosTex { float4 Pos : SV_POSITION; float2 Tex : TEXCOORD; }; //-------------------------------------------------------------------------------------- // Samplers //-------------------------------------------------------------------------------------- SamplerState samAnisotropic { Filter = ANISOTROPIC; AddressU = Wrap; AddressV = Wrap; }; SamplerState samLinearClamp { Filter = MIN_MAG_MIP_LINEAR; AddressU = Clamp; AddressV = Clamp; }; //-------------------------------------------------------------------------------------- // Rasterizer states //-------------------------------------------------------------------------------------- RasterizerState rsDefault { }; RasterizerState rsCullFront { CullMode = Front; }; RasterizerState rsCullBack { CullMode = Back; }; RasterizerState rsCullNone { CullMode = None; }; RasterizerState rsLineAA { CullMode = None; AntialiasedLineEnable = true; }; //-------------------------------------------------------------------------------------- // DepthStates //-------------------------------------------------------------------------------------- DepthStencilState EnableDepth { DepthEnable = TRUE; DepthWriteMask = ALL; DepthFunc = LESS_EQUAL; }; BlendState NoBlending { AlphaToCoverageEnable = FALSE; BlendEnable[0] = FALSE; }; //-------------------------------------------------------------------------------------- // Shaders //-------------------------------------------------------------------------------------- PosTexLi SimpleVS(PosNorTex Input) { PosTexLi output = (PosTexLi) 0; // Transform position from object space to homogenious clip space output.Pos = mul(Input.Pos, g_WorldViewProjection); // Pass trough normal and texture coordinates output.Tex = Input.Tex; // Calculate light intensity float3 n = normalize(mul(Input.Nor, g_World).xyz); // Assume orthogonal matrix output.Li = dot(n, g_LightDir.xyz); return output; } float4 SimplePS(PosTexLi Input) : SV_Target0 { // Perform lighting in object space, so that we can use the input normal "as it is" float4 matDiffuse = g_Diffuse.Sample(samAnisotropic, Input.Tex); return float4(matDiffuse.rgb * Input.Li, 1); } PosTex TerrainVS(uint VertexID : SV_VertexID) { PosTex output = (PosTex) 0; uint quadIdx = VertexID / 6; uint inQuadIdx = VertexID % 6; int2 coords; coords.x = VertexID % g_TerrainQuadRes; coords.y = VertexID / g_TerrainQuadRes; if (inQuadIdx == 1 || inQuadIdx == 4 || inQuadIdx == 5) coords.x++; if (inQuadIdx == 2 || inQuadIdx == 3 || inQuadIdx == 5) coords.y++; output.Tex.x = (float)coords.x / g_TerrainQuadRes; output.Tex.y = (float)coords.y / g_TerrainQuadRes; float height = g_Height[coords.x + coords.y * g_TerrainRes]; output.Pos.x = (float)output.Tex.x; output.Pos.y = (float)output.Tex.y; output.Pos.z = height; output.Pos.w = 1.0F; mul(output.Pos, g_WorldViewProjection); return output; } float4 TerrainPS(PosTex Input) : SV_Target0 { float3 n; n.xy = g_Normal.Sample(samAnisotropic, Input.Tex); n.xy = n.xy * 2 - 1; n.z = sqrt(1.0 - n.x * n.x - n.y * n.y); float3 matDiffuse = g_Diffuse.Sample(samAnisotropic, Input.Tex); float i = dot(n, g_LightDir); i = saturate(i); return float4(matDiffuse.rgb * i, 1); } //-------------------------------------------------------------------------------------- // Techniques //-------------------------------------------------------------------------------------- technique11 Render { pass P0 { SetVertexShader(CompileShader(vs_4_0, TerrainVS())); SetGeometryShader(NULL); SetPixelShader(CompileShader(ps_4_0, TerrainPS())); SetRasterizerState(rsCullNone); SetDepthStencilState(EnableDepth, 0); SetBlendState(NoBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF); } }