Shell Texturing

April 27th, 2025
Unreleased Project

Motivation

I'm currently studying different techniques to simulate depth on surfaces. When it comes to rendering fluffy materials, such as fur, moss or carpet, there is a classic technique known as Shell Texturing that's been used for decades in the game industry for its efficiency and simplicity. In this article, I will cover how it works and show examples of different materials feautring it.

Off On
Shell Texturing Off vs On

Implementation

Shell texturing consists of stacking layers of polygons with different clipping thresholds based on a height map. With enough resolution, this sells an illusion of depth that works especially well for certain materials such as hair, moss, carpets, etc.

For each triangle, several copies are generated uniformly spaced along the vertices normals. Each layer will have a different height value that will act as a clipping threshold to discard fragments below the layer height. In a planar surface, a similar visual result could be achieved using parallax occlusion mapping, maybe even better and at a lower cost. However, the advantage of shell texturing is that it is actual geometry, meaning that it adapts better to curved surfaces, correctly writes to depth without extra work, and is more stable at grazing angles.

Off On
Shell Texturing Off vs On

Layer generation

I have implemented two ways of generating layers:

Shading

Doing all the work of layering the material to then shade it uniformly is a bit of a waste. If the shading does not resemble the depth of the surface, it is hard to actually appreciate it. In order to efficiently address this, I just multiply the color of the surface by a factor of its layer height. Therefore, deep zones seem darker than higher parts of the surface. The strength and exponent of this function can be adjusted by the artist via material parameters.

Occlusion Off Occlusion On
Occlusion Off vs On

Shadows

It is important to prevent the shell textured materials from casting shadows on themselves. In the case of geometry shaders, the shadow caster pass simply does not run the geometry step, so only the base layer casts shadows. For surfaces with pregenerated layers, they are pushed back down along their normal to match the base layer exactly. This is not realistic in any way, but shell texturing is meant to be used on very thin surfaces, so in practice the absence of shadows coming from the upper layers is not noticeable.

Aliasing

At grazing angles, the effect breaks heavily as the empty space between layers becomes wider in screen space. This is obviously solved using more layers to minimize that space. However, you would theoretically need an infinite number of layers to fully hide the gaps in extreme cases. This is why I consider this technique only valid for very thin surfaces, as this aliasing problem is less noticable there.

Aliasing
Aliasing

If you are developing a game with a fixed camera angle, you can ignore the aliasing problem altogether and just set the number of layers to something that looks good in your game. However, it is a problem in any game with a dynamic camera perspective.

It must be noted that using many layers has a high performance cost, even without using a geometry shader. Each overlapping layer will be processed for every fragment, so each addtitional layer means that each pixel the surface covers is rendered one more time in terms of per-pixel cost. This causes a performance problem known as overdraw that leads to high memory bandwidth consumption, which is especially problematic in low-end GPUs.

Results

Off On
Shell Texturing Off vs On
Off On
Shell Texturing Off vs On
Off On
Shell Texturing Off vs On
Off On
Shell Texturing Off vs On
Off On
Shell Texturing Off vs On
Off On
Shell Texturing Off vs On
Off On
Shell Texturing Off vs On
Off On
Shell Texturing Off vs On
Off On
Shell Texturing Off vs On
Off On
Shell Texturing Off vs On
Off On
Shell Texturing Off vs On
Off On
Shell Texturing Off vs On

Conclusion

Shell texturing is a classic technique that can still be used effectively to provide depth to certain materials. In the past, it's been used in critically acclaimed games such as Dark Souls, Mario Galaxy and more recently Genshin Impact. While there are more modern techniques to render fur, moss, carpets, and similar materials, the simplicity of shell texturing makes it a strong option even today, especially when targetting lower-end GPUs.

In my opinion, the effect still looks really good on thin surfaces as demonstrated by Genshin Impact. It is very easy for artists to understand and set up per material and does not impact performance heavily when used cautiously.

Going forward

There isn't really much more to add to this technique, but maybe there are still some optimizations that could be explored further down the line: