simvx.graphics.streaming.scene3d_serializer

Binary serialization of 3D render state for the web export.

Serializes one 3D scene frame into compact binary for the browser-side WebGPU renderer. Resource uploads (meshes, textures) travel over the separate TLV drain channel — see simvx.graphics.web.resource_kinds — so this frame payload now carries only per-frame state.

Wire format per frame::

HEADER (20 bytes):
    frame_id(u32) flags(u32) viewport_count(u32) light_count(u32) draw_group_count(u32)

Per VIEWPORT (136 bytes):
    x(u32) y(u32) w(u32) h(u32) + view_mat(16×f32) + proj_mat(16×f32)

MATERIALS:
    material_count(u32) + material_bytes(material_count × MATERIAL_DTYPE.itemsize)

LIGHTS (light_count × LIGHT_DTYPE.itemsize bytes):
    Raw LIGHT_DTYPE data

DRAW GROUPS (draw_group_count entries):
    Per group (36-byte header):
        mesh_id(u32) index_count(u32) instance_count(u32) pass_type(u32)
        albedo_tex(u32) normal_tex(u32) metallic_roughness_tex(u32)
        emissive_tex(u32) ao_tex(u32)
    transform_bytes(instance_count × 64)  -- 4×4 model matrix per instance, f32
    material_ids(instance_count × u32)
    pass_type: 0=OPAQUE, 1=DOUBLE_SIDED, 2=TRANSPARENT

POST-PROCESS (only if flags bit 0 set, 64 bytes):
    bloom_enabled(u32) bloom_threshold(f32) bloom_intensity(f32) bloom_soft_knee(f32)
    fog_colour(4×f32) — rgb + density packed per Vulkan forward pass convention
    fog_params(4×f32)  — start, end, mode (0/1/2 linear/exp/exp²), enabled (0|1)
    fog_height_params(4×f32) — height, height_density, _pad, _pad

TILEMAPS (only if flags bit 1 set):
    layer_count(u32)
    Per layer:
        tileset_tex(u32) tile_count(u32) tile_w(f32) tile_h(f32)
        tiles(tile_count × 32 bytes)  -- TILE_INSTANCE_DTYPE

Module Contents

Classes

Scene3DSerializer

Serializes 3D scene state into compact binary frames for WebGPU.

Data

API

simvx.graphics.streaming.scene3d_serializer.__all__

[‘FLAG_HAS_POST_PROCESS’, ‘FLAG_HAS_TILEMAPS’, ‘Scene3DSerializer’]

simvx.graphics.streaming.scene3d_serializer.FLAG_HAS_POST_PROCESS

None

simvx.graphics.streaming.scene3d_serializer.FLAG_HAS_TILEMAPS

None

class simvx.graphics.streaming.scene3d_serializer.Scene3DSerializer[source]

Serializes 3D scene state into compact binary frames for WebGPU.

static serialize_frame(frame_id: int, viewports: list[dict[str, Any]], lights: numpy.ndarray, draw_groups: list[dict[str, Any]], materials: numpy.ndarray | None = None, post_process: dict[str, Any] | None = None, tilemap_layers: list[dict[str, Any]] | None = None) bytes[source]

Serialize a 3D scene frame.

Args: frame_id: Monotonic frame counter. viewports: [{x, y, width, height, view_matrix, proj_matrix}] (matrices 4×4 float32). lights: LIGHT_DTYPE structured array. draw_groups: [{mesh_id, index_count, instance_count_implicit_from_transforms,         transforms, material_ids, pass_type, albedo_tex, normal_tex,         metallic_roughness_tex, emissive_tex, ao_tex}]. The texture ids drive per-group bind group selection on the JS side and default to 0 when absent (the JS renderer falls back to a shared 1×1 white texture for id 0). materials: MATERIAL_DTYPE structured array (uploaded every frame; defaults to empty). post_process: {bloom_enabled, bloom_threshold, bloom_intensity, bloom_soft_knee}. tilemap_layers: [{tileset_tex, tile_size (w, h), tiles (TILE_INSTANCE_DTYPE         structured array)}]. Gated behind FLAG_HAS_TILEMAPS; omitted entirely when falsy so tilemap-less scenes pay zero bytes.

Returns: Compact binary frame ready for transmission to the browser.

static deserialize_frame(data: bytes) dict[str, Any][source]

Deserialize a frame back into structured data (for testing).