simvx.graphics.renderer.reflection_probe_pass¶
Reflection-probe capture: desktop (Vulkan) backend for ReflectionProbe3D.
Captures a local environment cubemap per probe and feeds the engine’s existing split-sum IBL precompute (irradiance + GGX-prefiltered specular,
- class:
IBLPass) so meshes inside a probe’s influence box pick up the local room reflection instead of the global skybox IBL.
Pipeline (per probe, run once on enter + on explicit request_update()):
Render the scene six times from the probe’s
capture_positioninto a square offscreen target (GameViewportRenderer), one per cube face, with a 90° FOV perspective camera. After each face,vkCmdCopyImagethe colour image into face f of a per-probe source cubemap.Record :meth:
IBLPass.record_convolutionon that source cube (using a per-probe descriptor bundle) into the same cmd → irradiance + prefiltered specular for this probe (reusing the global IBL compute shaders).vkCmdCopyImagethe probe’s irradiance cube (6 layers) and prefiltered cube (6 layers × N mips) into the shared cubemap arrays at the probe’s array slice (slice =probe_index * 6).
The shared arrays + a probe-box SSBO are bound to the forward set (bindings
10/11/12). The fragment shader tests each fragment’s world position against the
probe boxes (bounded loop, MAX_PROBES) and, when inside, samples that
probe’s maps (optionally box-projected) instead of the global IBL.
Capture records into the PRIMARY frame command buffer (the cmd passed to the
app’s pre_render hook): the six face renders, the per-probe IBL convolution,
and the cube-array copy are all recorded inline with intra-cmd image barriers,
so an always-mode probe no longer submits-and-waits its own buffer every frame.
Each probe owns its source cubemap and its IBL descriptor bundle, so several
always-mode probes convolved in one frame never cross-contaminate (the
convolution reads each probe’s own cube; vkUpdateDescriptorSets mutates a set
at record time, so a shared bundle’s last write would otherwise win for all).
Module Contents¶
Classes¶
Owns the shared probe cubemap arrays + box SSBO and drives per-probe capture. |
Data¶
API¶
- simvx.graphics.renderer.reflection_probe_pass.__all__¶
[‘ReflectionProbePass’]
- simvx.graphics.renderer.reflection_probe_pass.log¶
‘getLogger(…)’
- simvx.graphics.renderer.reflection_probe_pass.FACE_SIZE¶
128
- class simvx.graphics.renderer.reflection_probe_pass.ReflectionProbePass(engine: Any)[source]¶
Owns the shared probe cubemap arrays + box SSBO and drives per-probe capture.
Initialization
- set_face_size(size: int | None) None[source]¶
Set the per-face capture resolution.
Nonemeans the built-in default (:data:FACE_SIZE), so an unsetWorldEnvironment.probe_face_sizekeeps the exact historical path. A change tears down the capture scratch (shared face target + per-probe source cubes; the fixed-size IBL machinery survives) and schedules a full recapture of every active probe. Rare transition: device-wait-idle is acceptable.
- disable_probes() None[source]¶
Zero the probe-box SSBO so the forward blend loop is a no-op.
Called per frame while
WorldEnvironment.probe_blend_count == 0(capture is skipped upstream). Hash-gated: after the first call this is a dictionary lookup per frame.
- update_probes(cmd: Any, adapter: Any, tree: Any, probes: list) bool[source]¶
Capture any probe that is new or has
_update_requestedset, into cmd.All capture work (face renders, IBL convolution, array copy) records into the primary frame command buffer cmd: no separate submit/wait. Returns
Trueif at least one probe captured this frame (the caller must then re-submit the main scene, since face rendering clobbers the renderer’s per-frame submission lists: same contract as SubViewports).