GLSL Programming/Unity/Two-Sided Surfaces

This tutorial covers two-sided per-vertex lighting.

It's part of a series of tutorials about basic lighting in Unity. In this tutorial, we extend to render two-sided surfaces. If you haven't read, this would be a very good time to read it.



Two-Sided Lighting
As shown by the figure of the algebraic surface, it's sometimes useful to apply different colors to the two sides of a surface. In, we have seen how a fragment shader can use the built-in variable  to determine whether a fragment is part of a front-facing or a back-facing triangle. Can a vertex shader also determine whether it is part of a front-facing or a back-facing triangle? The answer is a clear: no! One reason is that the same vertex can be part of a front-facing and a back-facing triangle at the same time; thus, whatever decision is made in the vertex shader, it is potentially wrong for some triangles. If you want a simple rule to remember: “Fragments are either front-facing or back-facing. Vertices are bi.”

Thus, two-sided per-vertex lighting has to let the fragment shader determine, whether the front or the back material color should be applied. For example, with this fragment shader: On the other hand, this means that the vertex shader has to compute the surface lighting twice: for a front face and for a back face. Fortunately, this is usually still less work than computing the surface lighting for each fragment.

Shader Code
The shader code for two-sided per-vertex lighting is a straightforward extension of the code in. It requires two sets of material parameters (front and back) and deactivates culling. The vertex shader computes two colors, one for front faces and one for back faces using the negated normal vector and the second set of material parameters. Then the fragment shader decides which one to apply. Again, this code consists of two passes, where the second pass is the same as the first apart from the additive blending and the missing ambient color.

Summary
Congratulations, you made it to the end of this short tutorial with a long shader. We have seen:
 * Why a vertex shader cannot distinguish between front-facing and back-facing vertices (because the same vertex might be part of a front-facing and a back-facing triangles).
 * How to compute lighting for front faces and for back faces in the vertex shader.
 * How to let the fragment shader decide which color to apply.