Peeling Off the Gray Plastic with Toon Shading
When I first dropped the rabbit and the tunnel in with the default MeshStandardMaterial, the impression was, in a word, "gray plastic." PBR materials give you realistic light response, but realistic doesn't mean cute.
For a storybook tone, having the shading roll off smoothly was actually working against me.
So I switched to toon shading.
The key idea is to break the shading into a few discrete steps instead of a continuous gradient.
I built a 3-step gradient ramp as a DataTexture and had every material share that single texture as its gradientMap. MeshToonMaterial reads the ramp and quantizes light into three bands.
// components/game/materials.ts
cached = new THREE.DataTexture(
new Uint8Array([110, 190, 255]), // 3-step shading — dark/mid/bright
3, 1, THREE.RedFormat,
);
cached.minFilter = THREE.NearestFilter;
cached.magFilter = THREE.NearestFilter;
NearestFilter is the important part.
If you don't turn off interpolation, the three values blend smoothly and you're right back to a gradient.
You have to keep the bands crisp to get that distinctively cartoonish toon surface.
The material alone wasn't enough.
I melted the far end of the tunnel into an amber glow with a gradient fog, then layered bloom on top so the amber crystals shimmer softly.
Once all three came together, the "cozy twilight burrow" mood finally clicked.

Even with the same geometry, the way you paint it changes the entire mood.
The difference between gray plastic and a twilight burrow wasn't in the polygons — it was in the shading.
Next time: the React 19 rabbit hole, where I thought the visuals were all locked in and then the whole screen went dead.