Skip to content
Refraction & PressureHectorexperiment

The Hydro-Prismatic Leviathan

A trident where a single transmission material at an index of refraction of 2.42 does all the work, backed by 400 instanced cavitation bubbles it exists to distort.

Built here · no external address

Hector: Solid, honourable, high-craft work.

Why it matters

Glass is the most over-reached-for material in real-time 3D and the most commonly wasted. It is usually applied to an object floating in front of an empty background, where refraction has nothing to refract, and the result is an expensive material that looks like tinted plastic.

This trident is a study in making transmission earn its cost. The material is one MeshPhysicalMaterial shared by every part — shaft, crossbar, three prongs, butt spike — at transmission: 0.95 and ior: 2.42, which is the refractive index of diamond, not of glass. And critically, there is something behind it: four hundred instanced cavitation bubbles rising in a column, positioned behind the weapon specifically so the refraction has content to bend.

Once that relationship is right, the second lesson lands: weight. The trident's buoyancy is two sine waves at unrelated periods, one on vertical position and one on roll. A single sine always resolves into a visible loop; two out of phase never do, and the object reads as suspended in something dense.

Key techniques

  • One material instance shared across seven meshes. Transmission is compiled per material, not per mesh, so sharing keeps it to a single program.
  • ior: 2.42 with attenuationColor: #004b5c at attenuationDistance: 0.5 — attenuation is what makes thickness read as depth of water rather than as a coloured tint.
  • clearcoat: 1 at clearcoatRoughness: 0.05 for a specular layer that survives the tone mapping curve, so the prongs still catch a highlight in a nearly black room.
  • Unlit emissive tips (MeshBasicMaterial, toneMapped: false) at the three prong ends, giving the bloom pass three deliberate anchors instead of a diffuse glow.
  • 400 bubbles as a single InstancedMesh on a 6-segment sphere: one draw call, one geometry, matrices written by a shared Object3D scratch object.
  • Rise rate coupled to scroll velocity, with a modulo wrap so the column is endless without allocation.
  • Buoyancy as sin(t * 0.9) + sin(t * 0.37) on Y and sin(t * 0.61) on roll — deliberately incommensurable frequencies.

What to steal

The transferable part.

Never use transmission without a backdrop. If nothing sits behind the glass, use a cheap specular material instead and spend the difference somewhere visible. Refraction is a relationship, not a finish.

Attenuation over colour. color tints glass uniformly and reads as plastic. attenuationColor plus a short attenuationDistance makes thick regions darker than thin ones, which is what actually communicates volume.

One scratch `Object3D` for instanced updates. Allocating a matrix per instance per frame is 400 allocations per frame and a garbage collection pause you will blame on something else. Reuse one dummy, call updateMatrix, setMatrixAt, and set needsUpdate once.

Two incommensurable sines for anything floating. It is the cheapest known cure for the "animated loop" tell, and it costs one extra sin call.

What not to copy

Context-specific or costly.

Do not raise sphere segment counts for instanced particles. At 0.035 units on screen, a 6×5 sphere and a 32×16 sphere are the same picture and a fifteen-fold difference in vertices.

Do not add a full environment map for reflections unless you are prepared to pay for the download and the memory. Two point lights and an emissive tip gave this object more definition in a dark room than an HDRI did, at zero network cost.

Do not animate thickness or ior per frame. Both trigger material recompilation paths in some Three.js versions, and a shader recompile mid-scroll is a visible hitch.

Inclusion rationale

Admitted for one transferable rule stated as plainly as possible: transmission is a relationship with what is behind it. Most implementations skip that, pay the full cost, and get plastic. This one shows the cost, the backdrop, and the measured budget together.

Technical register

Performance

Transmission is the most expensive thing in the hall: it renders the scene to a secondary buffer for the refracted samples. That is why the bubble count drops from 400 to 140 and multisampling drops to zero in the reduced tier, and why this chamber runs the lowest baseline bloom intensity of the three (0.75) — bloom over transmission is double fill rate on the same pixels.

Measured: 60fps at DPR 1.75 on an M2, 58–60 on an M1 Air, and a stable 60 in the reduced tier on a 2019 Intel MacBook Pro where the full tier could not hold 50.

Mobile

The reduced tier is effectively the mobile tier and is entered by measurement rather than by user-agent sniffing. On touch, the pointer parallax that steers the weapon does not exist, so buoyancy alone must carry the object — which it does, because it was authored to be complete with a motionless pointer.

Accessibility

Under prefers-reduced-motion, buoyancy holds its pose and the bubble rise falls to its floor rate; the object stays legible as an object. The four technical facts a visitor might want — material, attenuation, particle count, buoyancy method — are printed in monospace beside the weapon as DOM text, not baked into the picture.