proxyOcclusion
Analytic occlusion from coarse proxy shapes — grounding for subjects a shadow map does not reach.
proxyOcclusion
Analytic occlusion from coarse proxy shapes — grounding for subjects a shadow map does not reach.
local proxyOcclusion = require("@builtin::systems.proxyOcclusion.proxyOcclusion")
proxyOcclusion.set("boulder", { a = { 0, 2, 0 }, radius = 2 }) -- sphere
proxyOcclusion.set("limb", { a = { 0, 1, 0 }, b = { 0, 3, 0 }, radius = 0.4 })
proxyOcclusion.remove("boulder")
proxyOcclusion.configure({ intensity = 0.8, minDistance = 40 })
proxyOcclusion.count() --> how many proxies are registered
proxyOcclusion.active() --> is the pass running
proxyOcclusion.clear() --> drop every proxy, release the pass
Proxies are capsules, keyed by a caller-chosen string. Re-submitting the same key moves that proxy rather than adding another, which is what lets a component push its shape every frame as its entity travels. A sphere is a capsule whose ends coincide, so one shape covers a boulder and a limb alike.
Cost scales with the number of proxies rather than with scene geometry, so the range a proxy works at is bounded by nothing — which is the point. A shadow map only covers what its cascades reach, and a subject past that range receives no grounding at all.
Occlusion is scaled by how lit a pixel already is, so a surface already sitting in shadow-map shadow cannot be darkened a second time.
For a proxy that should simply follow an entity, author the OcclusionProxy
component instead. This module is for code placing proxies directly: a crowd
system, a destruction event, anything without an entity to hang a component on.
The full description is in the package readme:
guides { path = "systems/proxyOcclusion" }.
Scoped to this part · feeds back into the world's score.