HammeriteLightProbeSet

Core: lighting. Inherits Resource

A map's baked light probes, with a uniform spatial grid for finding the nearest ones.

HammeriteMap.generate_light_probes() fills it and a bake lights it; most code reads it only through HammeriteMap.light_level_at(). Positions are in map space, the coordinates brushes are authored in.

Properties

TypeNameDefault
AABBboundsAABB(0, 0, 0, 0, 0, 0)
floatcell_size64.0
HammeriteLightProbe[]probes[]

Methods

ReturnsMethod
voidadd_probe(probe: HammeriteLightProbe)
boolhas_nearby_probe(pos: Vector3, min_distance: float)
Dictionaryquery(pos: Vector3, max_probes: int, max_radius: float = 512.0)
voidrebuild()

Property descriptions

bounds

var bounds: AABB = AABB(0, 0, 0, 0, 0, 0)

The smallest box holding every probe position, or an empty box at the origin when there are none. Kept by rebuild() and add_probe().

cell_size

var cell_size: float = 64.0

Edge of one grid cell, in map units. Changing it has the grid built again before it is next asked.

probes

var probes: HammeriteLightProbe[] = []

The probes the bake lights. add_probe() adds one; assigning the array, or growing it in place, has the grid built again before it is next asked.

Method descriptions

add_probe()

func add_probe(probe: HammeriteLightProbe) -> void

Add probe to the set, and to the grid as it stands rather than building it again.

has_nearby_probe()

func has_nearby_probe(pos: Vector3, min_distance: float) -> bool

Whether any probe stands within min_distance of pos. What probe generation asks to keep probes from clustering; as many rings of cells are searched as min_distance reaches.

query()

func query(pos: Vector3, max_probes: int, max_radius: float = 512.0) -> Dictionary

The max_probes probes nearest pos, and how far off each one is.

Returns { "indices": PackedInt32Array, "distances": PackedFloat32Array }, nearest first, and they really are the nearest: the fade that weights them - in HammeriteMap.light_level_at(), and in probe_sampling.gdshaderinc - leans on it. It silences whichever probe is farthest on the grounds that it is the one leaving the set, so a set that is only approximately the nearest drops probes while they still carry weight, which is the light popping that the fade exists to prevent.

Probes sit half a cell apart, so the cells around pos hold far more than any caller asks for and the walk stops within a ring or two of it. max_radius only binds where the bake is sparse - the edge of a map, a room the generator could not reach into.

Answered from where the probes were when the grid was last built or added to: a probe moved in place wants rebuild().

rebuild()

func rebuild() -> void

Builds the grid and bounds again from probes and cell_size. The map calls it on load, and a query calls it after the probes change; a probe edited in place - moved - is the one change it cannot see, and wants this called.

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