Materials that need Forward Shading

Materials that need Forward Shading

The new standard shader that I’m seeing everywhere is GGX distribution plus Schlick Fresnel plus Smith Visibility. By switching to this model we’re getting much better shading than in the past.

The question that always comes up is: “Do we need a separate forward pass?” Since our base specular model is so much improved over the last generation of games do we still need special case lighting functions for certain materials? I’m a strong proponent that the answer is YES!

Here is my subjective list of materials that can not be handled by the standard specular models and require some kind of custom shading. One counter argument I often hear is that we could still do deferred but with a flag to switch the BRDF model. But for most of these models you would need some kind of extra data in your G-Buffer to handle them as deferred.

If you look at any one of these materials, you could probably get away with some kind of special case trick. There’s no way you could do all of them though. It’s probably not worth rewriting your whole renderer just for better glitter, but they add up. The point of this post is to have a cursory list so that you can see all the cool things that a pure deferred renderer is missing out on.

On to the list:


1. Skin SSS

Skin is probably the most common one. The texture space approach was originally used in the Matrix Sequels and developed in realtime for ATI demos. But it was really popularized in the NVIDIA Human Head. Since then it’s been used in screen-space as well (Jimenez/Sundstedt/Gutierrez).

For the specular, the standard model is pretty good (GGX). The NVIDIA chapter had 4 lobes to try to create soft tails. GGX has softer tails so we don’t need 4 lobes anymore. Still, I think you could make the argument for doing two lobes of GGX instead of one.

2. Cheap Skin Approximations

In addition to the correct way of doing skin, we also have a need for cheaper, lower-quality ways of rendering skin. I’m a proponent of calculating diffuse for both the geometry normal and normal-mapped normal and blending the results. In the image above, the left is doing proper texture-space SSS and the right is using the blended approach. Other approaches include Preintegrated Skin Shading and using separate normals for Red/Green/Blue diffuse lighting.

3. Eyes

There are lots of issues with eyes. The main one is that specular light reflects off the cornea while the diffuse light refracts in weird ways before hitting the iris. The iris also has subsurface scattering.

4. Teeth

Teeth are really hard to get right. There was a stage in the GDC demo where literally every person that I talked to said “The demo looks great…except the teeth”. Teeth also have substantial subsurface scattering and I had to hack in some wrapped models. Yes, I still feel dirty.

5. Hair

Hair is a lot of work. Your two main options are the Two Kajiya-Kay Lobes popularized by ATI demos versus Marschner. Marschner is the “correct” solution but for most games I’d advocate two lobes of Kajia-Kay.

As a side note, hair is the material that breaks deferred shading the most. First, it has a custom lighting model. Second, you would need a huge number of extra parameters on the G-Buffer to do it deferred (two specular colors, tangent vector, and tangent distance). Third, you need alpha blending. I’ve done some crazy hacks to make hair work with light prepass lighting but I think you’re out of luck with fat G-Buffer deferred.

6. Cloth

Cloth doesn’t reflect light like most other objects. In almost every lighting model out there the specular highlight is at the peak when the reflection vector points straight at the light. The image above shows a render of the MERL BRDF (from the Ashikhmin dBRDF Paper). Cloth actually reflects more light back at silhouette angles due to fuzz. You can do this with an inverted gaussian which you can see in the course notes on Physically Based Rendering in The Order 1886.

7. Brushed Metals/Anisotropic Cloth

You need a special case material to handle true anisotropic BRDFs such as brushed metal and certain types of cloth. The cylinders above show different cuts (anisotropic directions) from the evaluation of MERL BRDFs. Anisotropic Ward is probably your best option but I still think we need something extra for that Purple Satin.

8. Leaf/Plant SSS

This one was taught to me by Bruce Straley at Naughty Dog. When light hits leaves, the diffuse color reflected back is more blue-ish. But when the light passes through and you see it from behind the color is more yellow-ish. When he told me I didn’t believe him so we crawled around outside on the grass at the Water Garden. I’ve wondered for a long time if we could use this knowledge to better simulate low grass but I don’t have an answer yet.

9. Sparkles! Glitter!

Glitter is easy to render with forward shading but hard to do deferred. You want to have sparkles appear and disappear as the view changes slightly. You can do it with two normals maps: A standard normal map and a super high frequency normal map with a very high exponent. Essentially, you are trying to create specular aliasing.

10. Sand

The sand in U3 is a bit stylized, but all sand needs some kind of custom shading. The grains are too fine to represent with a normal map so you need to use shader tweaks to make it look right.

11. Snow/Ice

Snow has definite subsurfacy characteristics. Ice is similar but slightly different. In theory I think Screen-Space SSS might work well for this but the cost would be pretty high. Cheap hacks are probably the way to go.

12. Car Paint

Car paint has been refined and well studied for many years. You have the base coat (standard color). The clear coat (makes it nice and shiny). Sparkles in the clear coat (glitter). And you have colored flakes in the clear coat which block certain types of light at certain angles and causes the color-changing effect.

13. Shaped Highlights

Here is another image from the Analysis of MERL BRDFs. The two images show chrome-steel and acrylic-blue. They both have a streaky, shaped highlight. It’s subtle but it makes a huge perceptual difference.

14. Anything Wet

Anything wet affects surfaces in a similar way to the cornea on the eye. Specular light bounces off the water but diffuse light refracts into the water and hits the underlying solid surface. At a minimum your diffuse and specular normals will be different. I.e. your diffuse normal comes from the pavement and the specular normal comes from the water on top (which fills those little crevices).

15. Clear Structures

We can include car headlights but also crystals and diamonds in this category. When light hits a reflective surface with a strong structure it keeps bouncing around. So we need some kind of shader to fake those extra bounces.

16. Futuristic Synthetics

Finally, in addition to simulating real objects, we also need to simulate fake objects that can’t actually exist. The above screenshot is from the NVIDIA Luna Demo (not to be confused with the Nalu Demo which was a mermaid). Sometimes we want to convey that a material is special and could not have been made on this planet via normal means. We can create this impression by giving it an impossible lighting model and biasing the lighting to certain colors at certain angles.

comments powered by Disqus