simvx.graphics.renderer.fog_volume_pack

FogVolume3D std430 SSBO packing: backend-agnostic, numpy only.

The per-volume wire/SSBO layout is shared by the desktop Vulkan volumetric_fog_pass (which uploads it to a GPU buffer) and the web export’s scene3d_serializer (which streams it to the browser WebGPU runtime). Keeping the packing here, free of any vulkan import, lets the web export bundle it into Pyodide without dragging in the desktop graphics stack. Both backends march the identical bytes so the same scene fogs identically.

Module Contents

Functions

build_volume_ssbo

Pack FogVolume3D nodes into a flat std430 byte array.

Data

API

simvx.graphics.renderer.fog_volume_pack.__all__

[‘FOG_VOLUME_STRIDE’, ‘MAX_FOG_VOLUMES’, ‘STEP_COUNT’, ‘build_volume_ssbo’]

simvx.graphics.renderer.fog_volume_pack.FOG_VOLUME_STRIDE

112

simvx.graphics.renderer.fog_volume_pack.MAX_FOG_VOLUMES

64

simvx.graphics.renderer.fog_volume_pack.STEP_COUNT

32

simvx.graphics.renderer.fog_volume_pack.build_volume_ssbo(volumes: list[Any]) tuple[numpy.ndarray, int][source]

Pack FogVolume3D nodes into a flat std430 byte array.

Returns (bytes_array, count) where count is clamped to MAX_FOG_VOLUMES. Each record is::

mat4 inv_transform   (world → unit-local, column-major for GLSL/WGSL)
vec4 albedo          (rgb, a unused)
vec4 params          (density, shape, edge_falloff, height_falloff)
vec4 extra           (priority, 0, 0, 0)

inv_transform folds the node’s world transform with a per-axis scale of size * 0.5 so the shape test in the shader is against a unit box / unit sphere / unit cylinder regardless of the volume’s placement.