A software light pass over the framebuffer, run in a render phase after drawing the scene: Light.ambient multiplies the scene toward a tint (night/cave mood), Light.point additively accumulates a radial glow with linear falloff clamped per channel, and Light.occlude / Light.clear_occluders cast hard shadows by blocking a light's rays against rectangular occluders. Integer + Q16.16 fixed throughout, so a scene lights identically every run and in a headless render (diffable). Engine in runtime/native/light.ludic, spliced on demand (g_uses_light) like the regex/query runtimes; namespace wired in emit_call.ludic. Ships issue #4 tiers 1 (ambient + additive radial lights) and 2 (hard shadows). Normal-mapped sprites, soft shadows, a day/night directional light, and auto-consuming Light2D/Occluder components are follow-ups (the auto-system hook is tracked by #43). - runtime/native/light.ludic: the light-accumulation engine (isqrt falloff, segment/occluder shadow test, ambient modulate) - examples/library/lighting.ludic: 14 pixel-readback assertions - docs/language/light/: Light.ambient/point/occlude/clear_occluders - tools/x/test.ludic: lighting.ludic in the regression suite Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
33 lines
1.4 KiB
Markdown
33 lines
1.4 KiB
Markdown
---
|
|
id: light-point
|
|
name: Light.point
|
|
category: light
|
|
kind: namespace-method
|
|
tokens: Light.point
|
|
sig: Light.point(x, y, radius, color, energy)
|
|
tip: Add a radial glow that falls off with distance.
|
|
order: 2
|
|
ns: Light
|
|
member: point
|
|
---
|
|
|
|
Additively accumulates a radial point light centred at <code>(x, y)</code>. Brightness is full at the centre and falls off linearly to zero at <code>radius</code> pixels, scaled by <code>energy</code> (a <code>fixed</code> multiplier — <code>1.0</code> is full, <code>2.0</code> over-drives toward white, <code>0.5</code> is dim), and clamped per channel at 255 so overlapping lights add without wrapping. Only the light's bounding box is touched, and any <a href="light-occlude"><code>Light.occlude</code></a> rectangle between the centre and a pixel puts that pixel in shadow. Colours are <code>0x00RRGGBB</code>.
|
|
|
|
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)
|
|
|
|
```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(32, 32, 48))
|
|
Light.point(80, 60, 70, Color.rgb(255, 210, 130), 1.0) # a warm torch
|
|
Screen.show()
|
|
}
|
|
}
|
|
```
|