The remaining lighting tiers from the original proposal, all extending the deterministic accumulation core (light.ludic) — no new ECS plumbing: - Light.spot: cone / flashlight lights (direction + spread degrees), with a self-contained integer atan2-in-degrees and a feathered edge. - Light.falloff: a brightness-ramp exponent (1 linear, 2 quadratic, …) via repeated fixed multiply. - Light.soft: soft shadows — an area-sampled light so an occluder edge fades through a penumbra instead of a hard cut. - Light.gel + Light.clear_gel: colour cookies — a light gels from its centre colour to a rim colour. - Light.normal + Light.clear_normals + Light.height: a normal G-buffer so surfaces shade by facing (N·L), not distance alone (tier 3). - Light.time_of_day: a day/night ambient ramp from a single 0..1 value. The engine lighting system (systems_light.ludic) consumes matching optional Light2D fields — direction/spread/falloff/softness/gel — each defaulting off so an older five-field Light2D lights exactly as before. Every tier is integer + Q16.16 fixed, so scenes light identically on every run and headless. Worked example + regression: examples/library/light_tiers.ludic (1 1 1 1 1 1 1 1 1). Nine new docs/language/light pages. Full suite 76 passed, self-host C-free fixpoint intact, no golden drift. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
35 lines
1.7 KiB
Markdown
35 lines
1.7 KiB
Markdown
---
|
|
id: light-spot
|
|
name: Light.spot
|
|
category: light
|
|
kind: namespace-method
|
|
tokens: Light.spot
|
|
sig: Light.spot(x, y, radius, color, energy, direction, spread)
|
|
tip: A cone / flashlight light aimed at a direction with a half-angle spread.
|
|
order: 5
|
|
ns: Light
|
|
member: spot
|
|
---
|
|
|
|
Accumulates a **cone** (spot) light — like <a href="light-point"><code>Light.point</code></a>, but only the wedge aimed at <code>direction</code> degrees (measured from <code>+x</code>, counter-clockwise) within a half-angle of <code>spread</code> degrees receives light. Pixels outside the cone stay dark, and the last few degrees of the edge feather so the boundary is not a hard line. A spot shares every quality control with a radial light — <a href="light-falloff"><code>Light.falloff</code></a>, <a href="light-soft"><code>Light.soft</code></a>, <a href="light-gel"><code>Light.gel</code></a> and the <a href="light-normal"><code>normal buffer</code></a> all apply. Fully deterministic (integer degrees + Q16.16).
|
|
|
|
Parameters:
|
|
- `x`, `y` — the light centre, in screen pixels
|
|
- `radius` — the reach in pixels; brightness is zero at and beyond it
|
|
- `color` — the light colour, `0x00RRGGBB`
|
|
- `energy` — a `fixed` brightness multiplier (`1.0` = full)
|
|
- `direction` — the aim, in whole degrees (`0` = right, `90` = up, `180` = left)
|
|
- `spread` — the cone half-angle, in whole degrees (`180` ≈ omnidirectional)
|
|
|
|
```ludic
|
|
program Demo {
|
|
property Torch { x: int = 0, y: int = 0 }
|
|
model Lamp { Torch }
|
|
handler Render phase Update {
|
|
Screen.clear(0)
|
|
Light.ambient(Color.rgb(24, 24, 32))
|
|
Light.spot(80, 60, 70, Color.rgb(255, 240, 200), 1.0, 0, 30) # a flashlight pointing right
|
|
Screen.show()
|
|
}
|
|
}
|
|
```
|