A Chemistry Performance Inside One Droplet
The story behind The Meniscus
Inspired by Luminol
Built with Three.js · ShaderMaterial · Ping-Pong FBO Simulation · UnrealBloomPass
Techniques Refractive droplet shell (IOR 1.333) · Advection / pressure fluid solve · Reaction-field compositing · Mobile chrome-aware HUD layout
Direction Treat a single droplet as a complete micro-lab where every click writes irreversible state
Result Three one-click reactions with distinct behavior: golden precipitation, Prussian diffusion, and cyan chemiluminescent pulse
The Story
The original reference video works because everything happens in one tiny place. No beaker. No cutaway. Just a droplet acting like a whole laboratory.
That constraint shaped The Meniscus: keep the scene simple, keep interaction direct, and make the chemistry read from inside the water itself. The user should never feel like they are toggling effects. They should feel like they are injecting matter into a system that evolves.
So the interaction model stays minimal: pick a reaction, click once, watch the field develop. If you click again during an active run, you disturb the flow instead of restarting it. That keeps the piece dynamic while preserving causality.
Reaction Design
The experience is built around three distinct behaviors rather than one generic “color fill”:
-
Golden Rain
Two fronts collide and convert into a denser product field that settles downward. The visual target is weighted yellow precipitation, not ambient glow. -
Prussian Bloom
Counter-rotating inputs create broad blue diffusion with visible shearing and braided fronts. This mode emphasizes fluid structure more than particle-like accumulation. -
Luminol Pulse
Delayed oxidizer pulses drive energy in the reaction alpha channel, then translate to cyan interior emission. The challenge here is balancing brightness with shape retention so the center does not clip to white.
Each mode has separate inject patterns, conversion rates, and display mapping, so the outcomes are materially different even inside the same droplet geometry.
Rendering Stack
The render is split into two coupled layers:
-
Physical droplet shell
MeshPhysicalMaterialhandles transmission, water IOR, thickness, and attenuation. This gives the bubble proper optical weight and refracts the chemistry text/paper beneath it. -
Interior reaction plane
A camera-facing shader surface samples the dye/energy simulation texture and maps the fields into reaction-specific color + alpha output. This is where most of the art direction lives.
Underneath that, the fluid sim runs in a ping-pong FBO setup: advection, curl/vorticity, divergence/pressure solve, gradient subtraction, then reaction conversion pass. The reaction pass consumes reagent channels and accumulates product + emission channels.
That separation lets the shell stay physically stable while reaction behavior can be tuned quickly.
The Luminosity Problem
The hardest part of this iteration was luminance calibration.
Early versions were too dim: reactions were technically present, but visually muted inside the bubble. Then compensation overshot and produced white clipping, especially in luminol.
The final balance came from tuning at the source first (reaction energy generation and injection strength), then adjusting the interior shader compression, and only then touching bloom. The key rule was: bloom should support light, not create it.
That same principle was applied to non-luminol modes so Golden Rain and Prussian Bloom can feel luminous during active phases without becoming post-processing artifacts.
Mobile-First Constraints
The global archive shell includes fixed header/footer chrome, so the in-experience HUD now measures available space and adapts around it.
On mobile:
- the control panel collapses to reaction tabs + run action by default
- secondary controls move behind a
More/Lesstoggle - nonessential status text is hidden in compact state
- top and bottom offsets respond to header/footer visibility to avoid collisions
This was required to preserve droplet visibility and interaction area on small screens while still keeping publish controls available.
This blog post was AI generated with Claude Code. Authored by Artificial Noodles.