# 12 · Two Shadows

One layered, terracotta-colored solid sits between two plaster walls. Lamp A casts the blush profile from *Quiet Face I* on the right wall. Lamp B casts the blue curl from *The Listener* on the left, with a cutout where the ochre comma sits in the painting. Both lamps can be on at once. Moving the camera leaves the sculpture and lamp directions fixed.

[Both lamps](cover.png) · [Quiet Face I wall](quiet-wall.png) · [The Listener wall](listener-wall.png) · [Layer plan](layer-plan.svg)

## Construction

The contours are manually traced from local photographs of the two paintings by Iana Kochu. A shared height and slight crop of the tips of the profile ensure that both traces have support in all 88 horizontal rows. The aperture in *The Listener* is part of the trace.

In an 82 × 88 × 82 cubic grid, a voxel survives the intersection when its projection falls inside both traces. In the convention used here, lamp A is on the positive Z axis and the right wall is at negative Z. Lamp B is on the positive X axis and the left wall is at negative X. The left wall's horizontal image coordinate runs opposite Z so that its photograph-derived curl reads correctly from the room. The 6-neighbor flood fill from the base retains 63,339 voxels and drops a detached fragment of 54 voxels. The 88 tiles in the layer plan follow the resulting sculpture from bottom to top. Each tile has +X to the right and +Z down.

The room uploads the 25,978 exposed voxel quads as a single Three.js mesh and uses it to cast both directional-light shadows. The source photos and proof silhouettes are displayed only below the room. Ambient fill, a stylized plaster surface, and a soft contact tint at the pedestal make the room legible.

## Projection check

An occupancy pass marks every cell occluded by a voxel along each axis. A separate pass marks the visible projection of the exposed mesh faces and produces the same two masks. Intersection over union compares those masks with the corresponding rasterized trace. [Geometry verification](geometry-verification.json)

| Trace | Trace cells | Projected cells | Intersection over union |
| --- | ---: | ---: | ---: |
| Quiet Face I | 2,076 | 2,076 | 100% |
| The Listener | 2,943 | 2,942 | 99.966% |

The check measures resemblance to the registered motif traces at grid resolution. The rendered wall shadows include soft sampling, ambient fill, and the camera's oblique view. Chrome also samples interior and neighboring pixels in both wall shadows and checks that contrast disappears on the wall whose lamp is off. [Browser verification](browser-verification.json)

## Studio limits

The directional lamps idealize perfectly parallel beams. Finite or diffuse lamps alter magnification, registration, and edge sharpness. The layer plan is a geometric cross-section reference. Mounting, registration tolerances, physical material, and structural stability still need a fabrication study.

Aldo Laurentini's visual-hull construction motivated the intersection of the two extruded silhouettes. Fred Eerdekens describes changing the illumination to reveal different shadow texts from the same installation. [Laurentini, 1994](https://doi.org/10.1109/34.273735) · [Author paper copy](https://www.researchgate.net/publication/3192242_The_visual_hull_concept_for_silhouette-based_image_understanding) · [Eerdekens, Installations](https://www.fred-eerdekens.be/work/installation)

## Run locally

From the repository root, serve the studio and open `http://127.0.0.1:4387/light-experiments/two-shadows/`.

```sh
python3 prototypes/kochu-studio/serve.py --port 4387
```

Run the geometry check and regenerate the proof SVGs and layer plan with Node.

```sh
node prototypes/kochu-studio/light-experiments/two-shadows/export.mjs
```

Use the adjacent browser verifier with Chrome and an available Playwright package. The script accepts `PLAYWRIGHT_PATH` for a bundled installation and `STUDIO_URL` for a different preview server. Add `--capture` to regenerate the three art-only room stills.

```sh
node prototypes/kochu-studio/light-experiments/two-shadows/verify-browser.cjs
```
