Graphics Reference
In-Depth Information
12. After the normal and texture sampling, and before the lighting calculations, we can
check if the decal has been applied to this fragment:
// Normal mapping
... SNIP
// Texture sample here (use white if no texture)
... SNIP
// Check if we have a decal .z == 1 means we do
if (pixel.DecalUV.z > 0.5)
{
// Decal normal sample using the pixel.DecalUV and
// apply to the existing normal. Note that we are
// blending the existing normal map sample with the
// decal normal sample
normal = ApplyNormalMap(normal, pixel.WorldTangent,
DecalNormalSample(pixel.DecalUV.xy));
// Decal texture sample
float4 decalDiffuse = DecalDiffuseSample(
pixel.DecalUV.xy);
// lerp the current sample and the decal diffuse, using
// the alpha channel of the decal as 't'.
sample = lerp(sample, float4(decalDiffuse.rgb,
sample.a), decalDiffuse.a);
}
// Final color and lighting calculations
float3 ambient = MaterialAmbient.rgb;
...SNIP
We are nearly done. All we have to do now is create our C# decal constant buffer,
assign it to the appropriate shader stages, load some decal textures, and then
update the decal constant buffer subresource with the location, size, and normals.
13. Within
ConstantBuffers.cs
, add a new structure
DecalBuffer
with the
equivalent properties we used in the HLSL structure. Note that we perform the
appropriate padding to align correctly to 16 bytes:
// The decal constant buffer
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DecalBuffer
{
public float DecalDisplaceScale; // If 0 no decal
public Vector3 DecalNormal; // If 0 no decal
public Vector3 DecalTangent;
public float _padding0;
public Vector3 DecalBitangent;