Monday 16 April 2018

Fancy Shaders - Part 2: Shell Rendering

Cg Fur Shader with different parameters in Unity.

It's been a while since my last post, but I have something interesting for you:) You will see another cool trick that is easy to do with shaders anywhere you want. We will talk about fur in real-time computer graphics!

Obviously, rendering realistic fur in real-time is not a trivial task. Just think about it: somehow we need to create a huge number of fibers on the surface and also control them dynamically (for wind, gravity, external forces, etc.) Several solutions exist for that problem, so let's analyze them!

First of all, we can use a "brute-force" approach, which is creating primitives for every single fiber, such as a line or triangle strips and then manipulating them. Our fur then will be super realistic, but very inefficient to compute. Although we can use geometry or tessellation shaders, our performance is going to be really poor even on modern machines with high specs. Actually, something similar is being used in CGI, as real-time simulations are not required for that.

The second approach is billboarding. Even if you are not familiar with this technique, you will get the idea pretty quickly. Game developers have been using this method for ages when grass or objects in distance are to be efficiently rendered. Even these days billboarding is the main approach for rendering grass (that is similar to fur) in most of the games. We just create 2D sprites of textures in 3D world space and rotate them according to our camera position. Developers can achieve really decent results while rendering grass that way and save a lot of resources, of course. But what about fur? Unfortunately, it will be problematic to render fur with billboards. Fur can be spread on very rough surfaces, like the skin of an animal, and not on a "plane" terrain as grass. That is why billboards may have incorrect angles and players can notice those artifacts. However, I'm sure that some teams can get pretty cool results with that technique if it is set properly.

The last approach that I can think about is the "classical" way of rendering fur in real-time applications. A technique is quite old, but still can be noticed in modern games. It's called shell rendering that is a form of volumetric rendering.

"Conker: Live & Reloaded" (2005)

The idea behind shell rendering is also easy to understand and to implement.  We basically make bigger copies of our mesh which is similar to normal extrusion. It is also not that difficult to control the length of our fur! For example, we can use a mask texture and store information in it. What I did in the scene (top image) was just use a grayscale noise texture that functioned like a heightmap. I'm pretty satisfied with the result, however, you can also do that with a control mask texture and get the values from an alpha channel. Because the mask is created from your pattern texture, your fur won't be random anymore. Instead, you will have distinct regions of fur or its absence. For instance, some animals' skin has certain patterns so it will add realism to your application. Down below is the logic of our Cg shader:


Taken from XBDev.net

Without a doubt, this method is not perfect. As you may have thought, we are dependent on the number of copies of our model. That means the more we instantiate, the more resources we spend and higher quality we achieve. For example, fur from the top image was created by making 20 passes and still has the evidence of those shells.  On the other hand, it requires a lot fewer computations compared to a "brute-force" approach. I'd repeat myself again: there are other industry solutions, such as NVIDIA HairWorks or AMD TressFX, but they do require resources and not every machine can run them these days. Although these approaches are way more realistic and flexible, on mobile platforms we are still limited to shell rendering.

Finally, I want to show you how fur quality has changed over the last 10-15 years in video games. I have specifically chosen an example of a game that uses a lot of fur in it. It is called "Shadow of the Colossus" and was originally developed by Team Ico for PlayStation 2 in 2005. It definitely used shell rendering at that time. However, in 2018 Bluepoint Games released a remastered version of that beautiful game for PlayStation 4. They combined modern technologies with powers of the system and, of course, changed the look of fur in the game. I'm not even sure what was the approach that they'd used, but probably it was not shell rendering. My guess: they did some tricks with something that is similar to billboarding. What do you think?

"Shadow of the Colossus" (2018 - top, 2005 - bottom)

Links:
1) http://www.xbdev.net/directx3dx/specialX/Fur/index.php
2) http://developer.download.nvidia.com/SDK/10.5/direct3d/Source/Fur/doc/FurShellsAndFins.pdf
3) https://dl.acm.org/citation.cfm?id=617876
4) https://forum.unity.com/threads/fur-shader.4581/
5) http://hhoppe.com/fur.pdf

Other useful resources:
1) "Unity 5.x Shaders and Effects Cookbook" by A.Zucconi and K.Lammers
2) "Implementing Fur Using Deferred Shading" by D.Revie, from "GPU Pro 2"
3) "Animated Characters with Shell Fur for Mobile Devices" by A.Girdler and J.Jones, from "GPU Pro 6"