我在 fragment shader 中以光線追蹤渲染真實鑽石:不用紋理或模型,只用 73 個平面
I ray traced a real diamond in a fragment shader (no textures, no models, 73 planes)
作者在 three.js fragment shader 中逐像素光線追蹤鑽石,利用 73 個平面構成切割外形,不需紋理或模型。光線以 2.418 的折射率進入鑽石,最多反射六次,並在出射時分成紅、綠、紫光,呈現色散火彩。此技術用於可互動的網頁示範,支援圓形、橢圓形和祖母綠形切割。
Most "3D diamonds" on the web are a glass material with a sparkle texture. They look fine in a thumbnail and dead the moment you move the light.
I wanted the real thing: light that enters the stone, bounces around inside it, and leaves as tiny rainbows. So I built it as a ray tracer that runs per pixel in a three.js fragment shader.
Play with it first: the live demo. Move your cursor to swing the studio lights, drag the stone, and push the dispersion slider.
The trick: a diamond is just a list of planes
A brilliant cut is a convex polyhedron. Every convex polyhedron is the intersection of half-spaces, so the whole stone fits in an array of planes, each one n · p <= d:
- 1 table
- 8 stars, 8 bezels, 16 upper halves
- 16 girdle facets
- 8 pavilion mains, 16 lower halves
That is 73 planes. No mesh data in the shader at all.
Entering the stone
For a ray from the camera, every plane facing the ray narrows the entry point and every plane facing away narrows the exit. Keep the largest entry and the smallest exit; if entry beats exit, you missed.
float tin = -1e9, tout = 1e9; vec3 n;
for (int i = 0; i < MAXP; i++) {
if (i >= uN) break;
vec4 p = uP[i];
float dn = dot(d, p.xyz), num = p.w - dot(o, p.xyz);
float t = num / dn;
if (dn < 0.0) { if (t > tin) { tin = t; n = p.xyz; } }
else tout = min(tout, t);
}
if (tin > tout) discard;
The plane that won is the facet you hit, so you get a perfect flat normal for free. Bonus: the gap between the best and second-best entry plane tells you how close you are to a facet edge, which is how the page draws the glowing blueprint view.
Bouncing inside
Refract in with an index of 2.418. Then, up to six times: find the nearest exit plane, try to refract out, and reflect back in if the angle is past diamond's critical angle (24.4 degrees). That total internal reflection is why diamonds look full of light.
Fire is three exits, not three rays
Tracing red, green and violet separately triples the cost. Instead I trace one path and split only at the exit, refracting with three slightly different indices. Diamond spreads red to violet by about 0.044, and that alone produces believable fire. The slider just exaggerates the spread.
The light is fake on purpose
There is no HDR image. The environment is a function: a dark gradient plus four soft rectangular "softboxes" and a thin ring light, rotated by your cursor. Moving the lights is what makes the stone flash, so it had to be cheap and controllable.
Making it a real page
- A tight hull mesh (computed from triple-plane intersections) means only the stone's pixels run the shader.
- Bloom only catches the HDR highlights, so the sparkle glows without washing out the copy.
- A carbon lattice made of real diamond-cubic points, clipped to the cut, assembles into the stone as you scroll.
- Three cuts (round, oval, emerald) are just three plane lists. Oval is the round list scaled through the inverse transpose.
- Pause motion, reduced motion and adaptive resolution are built in, because a beautiful page that melts a laptop is not beautiful.
Try it
It is part of AnimatedWebs, where every template is a playable demo plus a build prompt you can take into Claude Code, Cursor, Lovable, v0 or Bolt. There is a free MCP server so your coding agent can search the library itself, and an agent hub if you build with AI agents.
Also from our team
We are a small studio, Like a King Inc., and we build everything ourselves:
- AnimatedWebs: animated website templates with live demos and AI build prompts
- MotionVault: cinematic website templates and design assets
- RegesCore: a private AI assistant that runs on your own PC
- Reges Code: a free, local-first AI code editor
- RegesARC: a local AI workstation for running your own models
- Millicent: an AI sidekick with personality and memory
- TrustCertia: verifiable trust records for websites
- CreditFixExpert: evidence-linked credit report disputes
- My Little Bots: ready-made jobs for your Grok bot
- Reges Town: a living 3D city run by AI citizens
- LXR Core: game server resources
- davidio.dev: the developer behind it all
What would you ray trace next? I am leaning toward a watch movement.
來源:DEV Community · dev.to



