feat(light): render-quality tiers 3-4 — cones, falloff, soft shadows, gels, normals, day/night (#49)
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>
This commit is contained in:
parent
377b6d1186
commit
382826889f
18 changed files with 7752 additions and 6502 deletions
|
|
@ -273,8 +273,17 @@ function emit_ns_call(ns: pointer, meth: pointer, e: Node) -> Val {
|
|||
if (ns == "Light") {
|
||||
if (meth == "ambient") { bare = "light_ambient"; push(labels, "color") }
|
||||
if (meth == "point") { bare = "light_point"; push(labels, "x"); push(labels, "y"); push(labels, "radius"); push(labels, "color"); push(labels, "energy") }
|
||||
if (meth == "spot") { bare = "light_spot"; push(labels, "x"); push(labels, "y"); push(labels, "radius"); push(labels, "color"); push(labels, "energy"); push(labels, "direction"); push(labels, "spread") }
|
||||
if (meth == "occlude") { bare = "light_occlude"; push(labels, "x"); push(labels, "y"); push(labels, "width"); push(labels, "height") }
|
||||
if (meth == "clear_occluders") { bare = "light_clear_occluders" }
|
||||
if (meth == "falloff") { bare = "light_set_falloff"; push(labels, "exponent") }
|
||||
if (meth == "soft") { bare = "light_set_soft"; push(labels, "radius") }
|
||||
if (meth == "gel") { bare = "light_set_gel"; push(labels, "color") }
|
||||
if (meth == "clear_gel") { bare = "light_clear_gel" }
|
||||
if (meth == "height") { bare = "light_set_height"; push(labels, "height") }
|
||||
if (meth == "normal") { bare = "light_normal_rect"; push(labels, "x"); push(labels, "y"); push(labels, "width"); push(labels, "height"); push(labels, "nx"); push(labels, "ny") }
|
||||
if (meth == "clear_normals") { bare = "light_clear_normals" }
|
||||
if (meth == "time_of_day") { bare = "light_time_of_day"; push(labels, "t") }
|
||||
}
|
||||
# Query.* — ECS spatial queries over the reflection ABI (runtime/native/query.ludic,
|
||||
# spliced on demand). `prop` is a property id (World.prop_id); the spatial forms
|
||||
|
|
|
|||
13540
selfhost/ludicc.seed.ll
13540
selfhost/ludicc.seed.ll
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue