2025
BA Thesis HLSL Tessellation Unity

Real-Time Fiber Rendering for Carpet Materials

BA Digital Games thesis · Cologne Game Lab, TH Köln · supervised by Prof. Dr. Jonas Zimmer

5.5× Shells faster than fibers in close-ups (288 vs 52 fps)
1.3× Fibers faster than shells at room distance (1414 vs 1063 fps)
<1 MB VRAM for procedural fibers, vs 19–22 MB for shell texture arrays
01

The Question

Carpets are hard to render in real time: millions of thin, dense fibers, strong self-shadowing and anisotropic highlights. Games usually fake them with a flat normal-mapped texture.

I implemented two higher-fidelity techniques in the same Unity framework and compared them on two carpet types, shaggy cut-pile and loop-pile, for visual realism, GPU performance and memory.

Close-up of procedurally generated shaggy carpet fibers
02

Procedural Yarn Model

Each vertex of a flat base mesh spawns one yarn, using a density parameter calibrated per carpet type. Following Wu and Yuksel (2017), each yarn is a hierarchy of helices: plies spiral around the yarn axis, and fibers migrate around each ply.

Geometry is generated on the GPU through hardware tessellation and geometry shaders. No fiber data is stored: every attribute comes from a stable per-vertex seed, which also keeps fibers from shimmering as the camera moves.

A single ply of fibers and a top view of a yarn made of several plies
03

Fiber Shading

A custom per-pixel shading model tuned for textiles:

  • Wrapped diffuse for the soft scattering of fibrous material
  • Kajiya-Kay anisotropic specular with a second, tangent-shifted lobe
  • Subsurface transmission for the glow at fiber edges
  • Yarn-centre ambient occlusion, plus shadow-mapped self-shadowing
Shadow pass output of the fiber renderer
05

Shell Texturing

The second technique stacks 64 offset copies of the base mesh. Shell slices are generated from a single carpet texture with the histogram-based depth method of Ukaji et al. (2012) and stored in one 2D texture array, instead of 64 separate bindings.

The shader alpha-tests with a taper curve and tip fade, adds rim light that grows with shell depth, combines depth- and density-based occlusion, and casts shadows through a matching shadow-caster pass.

Shell-textured loop carpet seen up close
06

Rendered vs Real

Both renderers ran under an identical camera and a fixed 45° directional light, switched by a script so that comparisons stayed fair, then were compared against reference photographs.

Fibers reproduce the chaotic tufts and separated tips of shag carpet very closely. Shells hold up well at normal viewing distance but flatten in extreme close-ups and at grazing angles.

Top row rendered (fiber left, shell right); bottom row reference photos by Francesca Tosolini and Alireza Akhlaghi on Unsplash.

Fiber and shell shaggy carpet renders next to two reference photos
07

Performance

RTX 3070 (8 GB), 1920×1080, 4× MSAA. Frames per second, higher is better.

Method Close-up (0.5 m) Room view (3 m) VRAM
Fiber · shaggy 52 1414 <1 MB
Fiber · loop 32 709 <1 MB
Shell · shaggy 288 1063 22 MB
Shell · loop 140 1005 19 MB

Up close, shells win easily because the fiber renderer has to draw a huge number of small primitives. At medium and long range the result flips: the fiber renderer's dynamic LOD sheds geometry faster than the shells' basic LOD. In a worst-case stress test (screen filled with carpet, no LOD) fibers fell to about 19 fps (shag) and 10 fps (loop), which shows why the LOD matters.

08

What I'd Ship

Neither technique wins everywhere, so the thesis recommends a hybrid: shell texturing for large carpet areas and short, dense loop pile, and procedural fibers for hero objects or when the camera gets close. Natural next steps are compute-based culling and mesh shaders for fiber generation.

Fiber and shell loop carpet renders next to two reference photos

Loop carpet reference photos by Daniel Sturgess and Wolfgang Hasselmann on Unsplash.