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.
You can find the implementation of the
LocalCorrect function in the reflections blog at: http://community.arm.com/groups/arm-mali-graphics/blog/2014/08/07/reflections-based-on-local-cubemaps.
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-44 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 itself.
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 first pass.
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-45 Semi-transparent phoenix refractions
The following figure shows a semi-transparent phoenix wing:
Figure 6-46 Semi-transparent phoenix wing