HammeriteBrushEntityLighting

Core: lighting. Inherits RefCounted

The handover for brushwork that is baked into the world and then moves.

A secret door is built flush with the wall it hides in and has to be lit as that wall, which means being in the bake (HammeriteLightingProperties.key_bake_static()). The moment it slides, that bake is a photograph of somewhere it no longer is - the shading is of the wall's surface, in the wall's place - so it hands over to the light probes, which is how everything else that moves in this engine is lit. Neither half alone is right, which is why this is a BLEND rather than a swap. Swapped outright, the surface changes appearance in one frame while the eye is on it; blended over the first moment of movement, the change happens under the motion, where nobody reads it. Every brush entity base has one, which drives itself, so a door needs only to say when it moves:

func open() -> void:
hand_over_to_probes()   # HammeriteBrushEntityNode3D.hand_over_to_probes, and the bodies' alike

One made with create(node) instead is driven by its owner calling update(). Costs nothing until hand_over_to_probes() is called: brushwork that never moves keeps its lightmap, and its shader's probe branch is never taken.

Methods

ReturnsMethod
floatblend_seconds() static
HammeriteBrushEntityLightingcreate(node: Node3D, drives_itself: bool = false) static
floatget_blend()
voidhand_back_to_lightmap()
voidhand_over_to_probes()
boolis_baked_static()
voidrefresh_materials()
floatregather_distance() static
voidupdate(delta: float)

Method descriptions

blend_seconds()

static func blend_seconds() -> float

How long the handover takes, in seconds. Short enough to be over before a door has swung far, long enough not to be a cut.

create()

static func create(node: Node3D, drives_itself: bool = false) -> HammeriteBrushEntityLighting

A handover for node, the brush entity's own node - one of the HammeriteBrushEntity* bases, whose meshes this lights; where new(node, drives_itself) went. With drives_itself it follows the frame while it is blending or probe-lit, and update() is not called; the bases make theirs so (HammeriteBrushEntityNode3D.get_lighting()).

get_blend()

func get_blend() -> float

How far over to the probes the shaders are, from 0 (the lightmap) to 1 (the probes).

hand_back_to_lightmap()

func hand_back_to_lightmap() -> void

Go back to the lightmap, for brushwork that returns exactly where it was baked. Only true of something that closes flush again. A door left ajar is not where its bake says it is, and asking for the lightmap back would light it as though it were.

hand_over_to_probes()

func hand_over_to_probes() -> void

Light this from the probes from now on, blending over blend_seconds(). Call it as the movement STARTS, not when it finishes: the blend wants the motion to hide under.

is_baked_static()

func is_baked_static() -> bool

Whether the brushwork this lights was baked into the world at all. An entity that was never baked has nothing to hand over FROM: it is unlit brushwork wearing the ambient minimum, and probes are strictly better. Such an entity may still call hand_over_to_probes() - and should.

refresh_materials()

func refresh_materials() -> void

Collect the materials again, after anything that rebuilds the entity's meshes.

regather_distance()

static func regather_distance() -> float

How far the brushwork moves before its probes are gathered again, in world units. The probe grid is coarser than this is precise, and a gather is a query plus a visibility test per probe.

update()

func update(delta: float) -> void

Drive from the entity's _process, for one that does not drive itself. Does nothing while the lightmap is what lights it.

Hammerite 2.0 · built from 6d57ab2d, 2026-10-17