A standalone browser tool for exploring simple top-down 2D light fields. It compares omni lights and projector-style lights, supports multiple emitters, and shows how opaque objects are illuminated around their perimeters.
The app is intentionally static: no build step, no package install, and no runtime dependencies.
- Top-down 2D heatmap of combined light contribution.
- Omni lights with editable position, intensity, radius, and color.
- Projectors modeled as 2D camera/frustum projectors with:
- position and direction
- beam angle and softness
- distance falloff
- line-of-sight occlusion
- optional color-strip projection across the beam
- Opaque circle and rectangle objects that cast shadows.
- Perimeter samples that show surface illumination using surface normals.
- Interactive editing:
- drag lights and objects in the canvas
- rotate projectors with their direction handle
- add/delete lights and objects
- resize and rotate objects
- hide/show omni lights, projectors, objects, samples, and heatmap
- Editable scene JSON for direct parameter tweaking.
Because the app uses ES modules, serve it with a local static server instead of opening index.html directly from the filesystem.
From the repository root:
python3 -m http.server 4173Then open:
http://127.0.0.1:4173/
Any other static file server should work as well.
The app is published as a static site on GitHub Pages:
https://sonycslparis.github.io/lightfields2d/
Because the project is a no-build static site that uses only relative paths, it runs directly from GitHub Pages with no extra configuration.
The site is served straight from the main branch:
- Push your changes to
main. - In the repository, go to Settings → Pages.
- Under Build and deployment, set Source to Deploy from a branch.
- Choose the
mainbranch and the/ (root)folder, then Save.
GitHub publishes the site within a minute or two, and every push to main
redeploys it automatically. No build step is required.
.
├── index.html # HTML shell and controls
├── styles.css # Layout and UI styling
└── src
├── main.js # Browser entry point
├── app.js # Scene state, lighting, rendering, and interactions
└── presets.js # Built-in scene presets
Use the preset buttons to switch between simple scenes, then edit the setup interactively:
- Add omni lights or projectors from the Lights panel.
- Drag light centers to move them.
- Drag a projector's direction handle to rotate it.
- Select a light to edit its color or delete it.
- Add circles or rectangles from the Objects panel.
- Drag objects to move them.
- Select an object to resize, rotate, or delete it.
Objects are kept on top for interaction, so overlapping projector cones or light gizmos should not prevent object dragging.
Projectors can use a 1D strip of colors, similar to a row of pixels. Choose the strip pixel count, edit each color picker, and apply it to the selected projector. The strip is mapped across the projector output from left to right.
In scene JSON this is stored as:
{
"type": "projector",
"texture": "colorStrip",
"colorStrip": ["#ff4d4d", "#ffd166", "#6ee7ff", "#a78bfa"]
}The scene editor exposes the full state. Coordinates are normalized world coordinates, where x and y typically sit between 0 and 1.
Common light fields:
type:"omni"or"projector"x,y: positionintensity: brightness multiplierradius: rangecolor: fallback color
Projector-specific fields:
direction: degrees, where0points right and90points downbeamAngle: frustum angle in degreessoftness: edge featheringaspect: projector frustum aspect scaletexture:"softWindow","verticalBars","checker","gradient", or"colorStrip"colorStrip: array of colors for strip projectionvignette: edge dimming amountfalloffDistance: calibrated distance falloff control
Object fields:
- Circle:
type,x,y,radius,rotation,samples - Rectangle:
type,x,y,width,height,rotation,samples
This is a lightweight exploratory model, not a physically complete renderer. It includes direct illumination, projector frustums, surface-angle falloff, and hard line-of-sight occlusion, but it does not simulate full global illumination, glossy reflection, participating media, or true volumetric beams.