When you fetch the texel corresponding to the locally-corrected refraction direction, you might want to combine the refraction color with other lighting. For example, reflections that take place simultaneously with refraction.
To combine the refraction color with other lighting, you must pass an
additional view vector to the fragment shader and apply the local correction to it. Use
the result to fetch the reflection color from the same cubemap.
The following code snippet shows how to combine reflection and refraction
to produce the final output color:
// ----------------- Environment reflections ----------------
float3 newReflDirWS = LocalCorrect(input.reflDirWS, _BBoxMin, _BBoxMax, input.posWorld, _EnviCubeMapPos);
float4 staticReflColor = texCUBE(_EnviCubeMap, newReflDirWS);
// ----------------- Environment refractions ----------------
float3 newRefractDirWS = LocalCorrect(RefractDirWS, _BBoxMin, _BBoxMax, input.posWorld, _EnviCubeMapPos);
float4 staticRefractColor = texCUBE(_EnviCubeMap, newRefractDirWS);
// ----------------- Combined reflections and refractions ----------------
float4 combinedReflRefract = lerp(staticReflColor, staticRefractColor, _ReflAmount);
float4 finalColor = _AmbientColor + combinedReflRefract;
_ReflAmount is passed as
a uniform to the fragment shader. Use this coefficient to adjust the balance between
reflection and refraction contributions. You can manually adjust
_ReflAmount to achieve the visual effect you require.
When the refractive geometry is a hollow object, refractions and
reflections take place in both the front and back surfaces.
The following figure shows refraction on a glass bishop based on a local cubemap:
Figure 6-39 Refraction on a glass bishop based on a local cubemap
The image on the left shows the first pass that renders only back faces
with local refraction and reflections.
The image on the right shows the second pass renders only front faces
with local refraction and reflections and alpha blending with the first pass.
In the first pass, render the semi-transparent object in the
same manner that you render opaque geometry. Render the object last with
front-face culling on, that is, only render the back faces. You do not want to
occlude other objects so do not write to the depth buffer.
The color of the back face is obtained by mixing the colors
calculated from the reflection, refraction, and the diffuse color of the object
In the second pass, render the front faces with back face
culling, do this last in the rendering queue. Ensure depth writing is off.
Obtain the front-face color by mixing the refraction and reflection textures
with the diffuse color. The refraction in the second pass adds more realism to
the final rendering. You can skip this step if the refraction on the back faces
is enough to highlight the effect.
In the final pass you alpha-blend the resulting color with the
The following figure shows the result of implementing refractions based on a
local cubemap, on a semi-transparent phoenix in the Ice Cave demo.
Figure 6-40 Semi-transparent phoenix refractions
The following figure shows a semi-transparent phoenix wing:
Figure 6-41 Semi-transparent phoenix wing