Specular effects in the Ice Cave demo

This section of the guide describes the specular effects that are used in the Ice Cave demo. Specular effects are an efficient technique that produce good results.

The specular effects that are used in the Ice Cave demo are implemented using the Blinn technique. The following code shows you how to implement specular effects with the Blinn technique:

// Returns intensity of a specular effect without considering shadows
float SpecularBlinn(float3 vert2Light, float3 viewDir, float3 normalVec, float4 power)
{
	float3 floatDir = normalize(vert2Light - viewDir);
	float specAngle = max(dot(floatDir, normalVec), 0.0);
	return pow(specAngle, power);
}

A disadvantage of the Blinn technique is that it can produce incorrect results in certain circumstances. For example, specular effects can appear in regions that are in shadow.

The following image shows an example of a shadowed region with no specular effects:

The following image shows an example of specular effects in a shadowed region, which are incorrect because the shadows are represented incorrectly:

The following image shows an example of specular effects in a lit region, which are correct:

The shadows make the specular effects intensity either stronger or weaker, depending on the light that is reaching the specular surface. All of the information that is required to correct the intensity of the specular effects is already in the Ice Cave demo, so fixing the specular effect is relatively simple.

The environment cubemap texture that is used for reflection and shadow effects contains two types of information:

  • RGB: The RGB channels contain environment colors that are used for reflections.
  • Alpha channels: The alpha channel contains opacity, which is used for shadows.

You can use the alpha channel to determine the specular intensity. This is because the alpha channel represents holes in the cave that let light into the environment. The alpha channel is, therefore, used to ensure that the specular effect is applied only to surfaces that are lit.

To use the alpha channel to correct the specular effect, calculate a corrected reflection vector in a fragment shader to make the reflection effect. Use the corrected reflection vector to fetch the RGBA texel from a cubemap texture. This is shown in the following code:

// Locally corrected static reflections
const half4 reflColor = SampleCubemapWithLocalCorrection(
ReflDirectionWS,
_ReflBBoxMinWorld,
_ReflBBoxMaxWorld,
input.vertexInWorld,
_ReflCubePosWorld,
_ReflCube);

Note: For more information about creating the corrected reflection vector, or what the SampleCubemapWithLocalCorrection() function is, see Local cubemap rendering

The reflColor value is in RGBA format where the RGB components contain color data for reflections and the alpha channel (A) contains the intensity of the specular effect. In the Ice Cave demo, the alpha channel is multiplied by the specular color, which is calculated with the Blinn technique. This is shown in the following code:

half3 specular = _SpecularColor.rgb *
SpecularBlinn(
input.vertexToLight01InWorld,
viewDirInWorld,
normalInWorld,
_SpecularPower) *
reflColor.a;

The specular value represents the final specular color. You can add the specular value to your lighting model, which is shown in the following code:

half3 pixCol = specular + reflections + diffuse + ambient;
Previous Next