Prism Light Instrument
A lighting rig you play with a pointer, where the light lands on a height field instead of on empty space. Typed letters, a ruled grid and a fine tooth are pressed into the surface, and every lamp rakes across that relief at a shallow angle, because grazing light is what makes an emboss read. The beam is measured rather than painted: three angular gaussians per lamp, one per wavelength, offset by a fixed chromatic amount around an achromatic core, multiplied by a two-term radial throw and gelled from tungsten through neutral to daylight. Standing on the surface is a real triangle of glass. Rays are traced through it in the vertex shader with a wavelength-dependent index, refracting in one face and out another, following the bounce when a ray hits the far wall too steeply to leave, so the spectrum is the actual dispersion of that geometry and not a gradient laid over it. Each pair of adjacent rays spans a quad rather than drawing a line, so the fan is watertight in a single frame instead of filling in over time, and a flat-topped profile across each slice sums to one however wide it spreads, which is what keeps a widening fan from banding at every seam. The glass casts a soft shadow because the lamp is a disc rather than a point: the penumbra falls out of the silhouette geometry, so it carries no temporal noise at all. Both the direct beams and the refracted spectrum answer to the same baked normal and openness map, so the colour carves the letters and finds the ruling rather than sitting on top of the picture. Letters slide to re-centre and sink to depth on their own clocks, a running average converges the image over twenty-six samples, and an ordered dither keeps the long dark falloff from banding into eight bits. One WebGL2 canvas, no library and no asset required.
npx shadcn@latest add https://ui.aryank.space/r/prism-light-instrument.jsonInstalls from ui.aryank.space. To add it by hand, copy the files in Usage below, or register the @compronents namespace via the docs.
| Prop | Type | Default | Description |
|---|---|---|---|
| text | string | "LIGHT" | Text pressed into the surface. Typing on the focused component edits it live; Escape clears, Enter adds a line. |
| lamps | LampSeed[] | three-point rig | Lamps present on load. Each seed carries fractional x/y, an aimAt target or an aim angle, plus spread, inten, throwR and tint (negative is tungsten, positive is daylight). |
| prism | PrismConfig | { on: true, x: 0.375, y: 0.53, radius: 0.062, rot: 0.62, disp: 6.5, gain: 1, len: 1.9, blur: 2.6 } | The glass triangle. disp pulls the wavelengths apart, gain sets the fan's brightness, len how far it is drawn past the glass, blur how fast a slice softens as it leaves. |
| ramp / rampDepth | boolean / number | true / 5 | Raked letters sink to their own pool floor, each following its own glyph shape, at rampDepth times the stamped depth. Set ramp false for a flat stamp where only the rim catches the light. |
| rayAngles / rayBands | number | 84 / 24 | Angular samples across the glass per wavelength, and wavelength samples. Bands are full-screen overdraw, so this is the main cost dial; while type is animating the component drops to eight on its own. |
| maxLamps | number | 8 | Ceiling on placed lamps, clamped to 8 by the shader's uniform array. Past the cap the oldest lamp is retired. |
| accent | string | "#e8bf4b" | Colour of the gizmo overlay drawn on the 2D layer. |
| mark / showLegend / legend | string / boolean / LegendEntry[] | "blank_graphics" / true / four gestures | The mono signature bottom-left and the affordance legend bottom-right, which fades out after 2.6 seconds without input. |
| allowTyping / autoFocus | boolean | true / false | Keyboard is scoped to the component and needs focus, which a click on the surface grants. Set autoFocus for a full-screen presentation where typing should work immediately. |
texttextThe word embossed into the surface. Up to five lines and ninety characters; it re-centres and sinks to depth on its own clock.
accentcolorColour of the gizmo overlay: the aim line, the cone edges, and the lamp rings.
prismtextThe glass: on, disp, gain, len and blur drive the refracted fan, while position and rotation belong to the pointer once it is on the surface.
lampstextOpening rig, seeded in fractional coordinates so it survives any viewport. Defaults to a three-point key, fill and accent aimed at the word.