Render to G-Buffer shader
Language: HLSL
This shader render a mesh by writing to the G-Buffer using multiple render targets.
Code sample
//Matrix used by this shader pass float4x4 World; float4x4 View; float4x4 Projection; //The material properties //The specular coeficients float specularIntensity = 1.0f; float specularPower = 32; //The used textures bool useTexture = false; bool useEmissive = false; bool useNormal = false; //The normal scale float normalScale = 1.0f; //The base diffuse color float4 diffuseColor = {1.0f, 1.0f, 1.0f, 1.0f}; //The material textures //Diffuse texture texture diffuseTexture; sampler diffuseSampler = sampler_state { Texture = (diffuseTexture); MAGFILTER = Linear; MINFILTER = Linear; MIPFILTER = Linear; AddressU = Wrap; AddressV = Wrap; }; //Normal map texture normalTexture; sampler normalSampler = sampler_state { Texture = (normalTexture); MAGFILTER = Linear; MINFILTER = Linear; MIPFILTER = Linear; AddressU = Wrap; AddressV = Wrap; }; //Emissive map texture emissiveTexture; sampler emissiveSampler = sampler_state { Texture = (emissiveTexture); MAGFILTER = Linear; MINFILTER = Linear; MIPFILTER = Linear; AddressU = Wrap; AddressV = Wrap; }; struct VertexShaderInput { float4 Position : POSITION0; float3 Normal : NORMAL0; float2 TexCoord : TEXCOORD0; float3 Binormal : BINORMAL0; float3 Tangent : TANGENT0; }; struct VertexShaderOutput { float4 Position : POSITION0; float2 TexCoord : TEXCOORD0; float3 Normal : TEXCOORD1; float4 PointPosition : TEXCOORD2; float3x3 TangentToWorld : TEXCOORD3; }; //A simple vertex shader VertexShaderOutput VertexShaderFunction(VertexShaderInput input) { VertexShaderOutput output; float4x4 worldViewProjection = mul( mul(World, View), Projection); output.Position = mul(input.Position, worldViewProjection); output.TexCoord = input.TexCoord; //For normal mapping, we need to compute the tangent to world matrix output.Normal = mul(input.Normal,World); output.PointPosition = mul(input.Position, World); output.TangentToWorld[0] = mul(input.Tangent, World); output.TangentToWorld[1] = mul(input.Binormal, World); output.TangentToWorld[2] = mul(input.Normal, World); return output; } struct PixelShaderOutput { // Position float4 MRT1 : COLOR0; // Color and Specular Power float4 MRT2 : COLOR1; // Normal and Specular Intensity float4 MRT3 : COLOR2; // Emissive light float4 MRT4 : COLOR3; }; //This pixel shader write to the G-Buffer using MRT PixelShaderOutput PixelShaderFunction(VertexShaderOutput input) { PixelShaderOutput output; //The world position in the scene float3 position = input.PointPosition.xyz; //The diffuse color (albedo) float3 color; if(useTexture) color = tex2D(diffuseSampler, input.TexCoord); else color = diffuseColor.rgb; //The emissive light color float3 emissive; if(useEmissive) emissive = tex2D(emissiveSampler, input.TexCoord); else emissive = 0.0f; //The world space normal float3 normal; if(useNormal) { //We sample the normal map float3 normalMap = tex2D(normalSampler, input.TexCoord); normalMap = 2.0f * normalMap - 1.0f; normalMap.xy = normalMap.xy * normalScale; normalMap = normalize(normalMap); //And use the TangentToWorld matrix to transform the sample to world space normal = mul(normalMap, input.TangentToWorld); } else normal = input.Normal; normal = normalize(normal); //Finally, writing informations to the ouput output.MRT1.rgb = position; output.MRT1.a = 1.0f; output.MRT2.rgb = color; output.MRT2.a = specularPower / 255.0f; output.MRT3.rgb = normal * 0.5f + 0.5f; output.MRT3.a = specularIntensity; output.MRT4.rgb = emissive; output.MRT4.a = 1.0f; return output; } technique Technique1 { pass Pass1 { VertexShader = compile vs_3_0 VertexShaderFunction(); PixelShader = compile ps_3_0 PixelShaderFunction(); } }