vidar.games

Iris remap on pupil dilation

2026-11-01 ยท Discuss on X

The pupil grows from 3.5 mm to 7.8 mm on both eyes.
Left: the iris stays put and a bigger black disc covers it.
Right: the iris is remapped, so its fibres bunch up toward the edge.

The problem

Most eye shaders dilate the pupil by drawing a bigger black disc. The iris texture stays fixed, so a dilated pupil just covers the inner iris. On a real eye the iris tissue moves and bunches up toward the edge. With the camera held still, the difference shows.

How it works

The remap from zulubo/EyeShader works on the distance r from the eye centre, in 2 pieces:

r < pupil: map [0, pupil] onto [0, base pupil] of the texture
pupil < r < iris edge: map [pupil, edge] onto [base pupil, edge]

Then the UV is rescaled along that radius. The texture's own pupil always lands exactly on the current pupil, and the whole iris ring is squeezed or stretched to fit between the pupil and the edge. Nothing is covered.

The dashed ring marks the same spot in the iris pattern, at 62% of the iris radius. On the left it never moves. On the right it slides outward as the pupil opens.

My build

The whole eye is ray-traced in 1 fragment shader in three.js 0.170: an eyeball sphere, a cornea that refracts the ray (index 1.376) onto a recessed iris plane, sclera with faint veins, and a key highlight. The iris is procedural: fibres from angle-periodic noise, a jagged collarette ring, dark crypts and a limbal ring. Base pupil 0.30 of the iris radius, animated to 0.66. The readout assumes an 11.8 mm iris, so the pupil goes from 3.5 mm to 7.8 mm.

What I hit

My first iris colours were too saturated and the fibres too faint, so the squeeze was hard to see. Raising fibre contrast fixed that more than any overlay did.

The remap is linear. Real iris tissue does not compress evenly, so this is an approximation.

Trade-offs

When to use it

Any close-up eye: character portraits, dialogue cameras, creature eyes reacting to light.

New breakdowns go out on X first: @vidar_0208. If this one helped, you can buy me a coffee.

Source and credits

Technique: radial iris remap for pupil dilation, from zulubo/EyeShader ("apply pupil dilation" in Eye.shader).
Repo: github.com/zulubo/EyeShader (MIT license), commit f5e4a63

Code: I ported the two-segment remap (r inside the pupil, and r between pupil and iris edge) from HLSL to GLSL. The eye, iris pattern, lighting and scene are my own procedural build; no textures or assets from the repo.

Topic from a question by @silic2023.