Skip to main content

Module render_types

Module render_types 

Source
Expand description

Shared GPU data types used by all rendering backends. Defined here (no #cfg gate) so a future Vulkan backend can import them without pulling in Metal-specific code. metal.rs imports from this module rather than defining its own copies.

Structs§

AreaLightData
One rectangular area light’s extent, indexed by GpuLight.data_index. The centre is the GpuLight’s position and the emitting direction its direction; only the two in-plane edge vectors and the sidedness flag need the extra room.
ClusterParams
Per-frame uniform for the clustered light-binning compute pass and the forward pass that reads the per-cluster lists. The compute kernel unprojects each cluster’s screen tile through inv_view_proj and walks camera rays to the slice’s near/far depth to build a world-space AABB (same convention as the fog froxel kernel), then tests each GpuLight sphere against it. The forward pass reads the grid dims + depth range + screen size to map a fragment to its cluster. 128 bytes; packed_float3 keeps cam_pos / view_forward inside their 16-byte lanes. Must match the ClusterParams struct in the light-cull and forward shaders.
CompositeParams
Fragment constants for the composite pass: the authored post-process tunables plus the scene-transition fade the backend owns. Pushed verbatim to the composite fragment shader, so the layout must stay in sync with the CompositeUniforms struct there. 48 bytes.
CullStatus
The per-object outcomes the GPU cull records in its status buffer. Values mirror the STATUS_* constants in cull.slang; Metal’s ICB encode kernel is told which one to draw rather than declaring them itself.
DirectionalLightData
One directional light entry in LightUniforms. Layout (32 bytes) mirrors DirLight in main_types.slang, which spells each (float3, scalar) pair as one float4 lane.
DrawObject
One renderable object: vertex/index slice within the shared GPU buffers, a model matrix, albedo and normal-map texture slots, and material parameters.
FogFroxelParams
Per-frame uniform consumed by the volumetric-fog froxel compute kernel and the matching fragment-shader sample path. Carries the view matrix (so the compute kernel + the fragment sampler can map between world-space froxel positions and the volume’s Z axis) and the discrete volume dimensions. Used by the froxel-volume fog path; only worlds that declare a VolumetricFog bind it.
FogParams
Per-frame uniform consumed by the volumetric-fog ray-march. Carries the clamped authored tunables plus the view inputs the shader needs to reconstruct world positions from depth and integrate sun-aligned scattering. Pushed verbatim to the fog fragment shader, so the layout must stay in sync with FogParams in metal/shaders/fog.metal. 176 bytes.
GpuDrawArgs
Per-object draw parameters consumed by the GPU-driven compute cull kernel. Parallel to GpuObjectData (one record per DrawObject, same index): GpuObjectData carries the cull bounds the kernel tests, this carries the indexed-draw arguments the kernel encodes into the indirect command buffer (Metal MTLIndirectCommandBuffer / DirectX ExecuteIndirect argument buffer / Vulkan multiDrawIndexedIndirect buffer) when an object survives the cull.
GpuLight
One local light in the per-scene storage buffer the forward pass iterates (bound at Metal fragment buffer(8)). 64 bytes = four 16-byte lanes, so every packed_float3 sits inside one lane with no GPU alignment promotion. Must match the GpuLight struct in the single-source shaders.
GpuObjectData
Per-object record consumed by the Metal “bindless” static main pass.
InstancedCluster
One GPU-instanced draw: a shared mesh slice + material rendered at many world-space transforms in a single drawIndexedInstanced / cmd_draw_indexed (instance_count > 1). The cluster has a single union AABB across all instances; it is frustum-tested as a whole. Cluster culling trades per- instance precision for one draw call instead of N.
InstancedLodBucket
One LOD bucket emitted by InstancedCluster::lod_buckets: the index range for that LOD plus the subset of instance matrices that picked it. Each bucket becomes one drawIndexedInstanced call.
LightUniforms
All scene lights packed into a single GPU buffer pushed at fragment buffer(4). Mirrors LightUniforms in main_types.slang; the layout guard reflects it.
LineVertex
Compact vertex type used exclusively by the line pass. 32 bytes: the expanded ribbon corner in world space, its signed position across the ribbon width (for the shader’s edge fade), and the corner colour.
LodSlice
One LOD level past LOD0 for a DrawObject. Holds the rebased shared-index buffer slice and the camera-distance threshold above which the renderer picks this slice instead of the one stored on the parent DrawObject. LodSlices are stored in ascending switch_distance order; the runtime picks the highest-indexed slice whose threshold is ≤ the current camera distance. The same base_vertex as the parent applies: LOD decimation reuses the LOD0 vertex range, only the index list changes.
MaterialUniforms
A draw object’s material scalars. A CPU record: the cull packs it into the GpuObjectData the GPU-driven pass reads, and no shader declares it.
ParticleParams
Per-frame uniform consumed by the particle compute + render kernels. Carries the resolved emitter tunables (position, direction, gravity, …) plus the dynamic per-frame inputs the compute kernel needs to age + integrate + respawn the pool. Pushed at compute buffer(2) and vertex buffer(1) of the Metal particle passes, so the layout must stay in sync with ParticleParams in shaders/particle_types.slang. 144 bytes.
PointLightData
One point light entry in LightUniforms. Layout (32 bytes) mirrors PointLight in main_types.slang, spelled the same way as DirectionalLightData.
PostProcessParams
Post-process tunables resolved from the PostProcessConfig asset (or its defaults), plus the two display-output flags the backend resolves from the display’s EDR capability at init. Pushed verbatim to the bloom prefilter and composite fragment shaders, so the layout must stay in sync with the PostUniforms struct in those shaders. 36 bytes.
PostProcessTunables
The authored half of PostProcessParams: everything a PostProcessConfig (or a settings slider) resolves to. Carries no display-output flag, so a live push can never disturb the EDR path the backend negotiated at init.
RtGeomEntry
One entry of the ray-tracing geometry table, indexed by the intersector’s instance_id (the instance’s position in the TLAS instance buffer, one entry per instance, in instance order). Lets the RT kernel find the hit triangle’s indices in the shared index buffer, transform its local-space vertices into world space for the geometric normal, and pick a base albedo to shade the hit with. #[repr(C)], 128 bytes: the layout must stay in sync with the RtGeomEntry struct in the shared RT records (rt_types.slang), where tint and emissive are packed_float3 so the field offsets match; a plain float3 there would stride the buffer differently and fault the trace. The _pad tail rounds the struct to 128 bytes so its array stride is a multiple of the 16-byte GPU alignment of the float4x4 model (MSL/HLSL/GLSL round a matrix-bearing struct up to a 16-byte multiple, so a 116-byte Rust struct would stride 116 while the shader strides 128 and faults the trace). The size_eq / offsets unit tests below lock the Rust side. The model matrix is stored here (rather than read from the intersector’s instance transform) so the kernel’s normal math is self-contained.
RtParams
Per-frame uniform for the hardware ray-traced reflection pass. Like SsrParams it carries the clamped intensity / distance, the view-ray scale used to rebuild a view-space position from the SSR pre-pass G-buffer, and the IBL prefilter mip count for the miss fallback. Unlike SSR it traces a world-space ray against an acceleration structure, so it also carries the camera-to-world transform (to lift the view-space hit point + normal into world space), the world camera position (the ray origin), and the sun direction + colour the hit-shading uses. Pushed verbatim to the RT kernel, so the layout must stay in sync with the RtParams struct there. 192 bytes, 16-byte aligned (every vec3 is padded to a float4).
ShadowPassPush
Per-shadow-pass push constant identifying which cascade is being rendered. Used so the shadow vertex shader can index ShadowUniforms.light_vps[i] from a single bound UBO instead of re-binding a different uniform per pass.
ShadowUniforms
Cascaded shadow map view-projection matrices and split depths.
SkinnedDrawObject
One skeletally animated draw: a slice of the shared skinned vertex/index buffers plus the per-joint matrix buffer the vertex shader blends.
SpotShadowData
One shadowed spot light’s slice of the spot shadow map array. Indexed by GpuLight.shadow_index; the index doubles as the array slice. Uploaded once per scene, since local lights are static.
SsaoParams
Per-frame uniform for the SSAO (GTAO) horizon-search kernel. Carries the clamped authored tunables plus the view-ray scale the kernel needs to rebuild a view-space position from the linear depth the SSAO pre-pass writes. Pushed verbatim to the SSAO kernel fragment shader, so the layout must stay in sync with the SsaoParams struct there. 16 bytes.
SsgiParams
Per-frame uniform for the screen-space global-illumination (SSGI) gather + composite. Carries the clamped authored tunables and the view-ray scale the gather pass uses to project a view-space ray point back to a screen UV. Pushed verbatim to the SSGI gather + composite fragment shaders, so the layout must stay in sync with the SsgiParams struct there. 32 bytes.
SsrParams
Per-frame uniform for the screen-space reflection (SSR) ray-march. Carries the clamped authored tunables, the view-ray scale the resolve pass uses to project a view-space ray point back to a screen UV, and the data the resolve needs to sample the IBL prefilter cubemap as a fallback. Pushed verbatim to the SSR resolve fragment shader, so the layout must stay in sync with the SsrParams struct there. 144 bytes.
TextDrawCall
One text draw call: quads for all visible characters sharing one atlas texture.
TextUniforms
Uniforms pushed to the text vertex shader once per text draw call. Carries the framebuffer size so the shader can convert pixel coords to NDC.
TextVertex
Compact vertex type used exclusively by the text render pass. 32 bytes: screen-pixel position, atlas UV, text colour, and sampling mode.

Constants§

CLUSTER_COUNT
Total clusters in the froxel grid.
CLUSTER_GRID_X
Clustered forward lighting froxel grid. The screen is tiled CLUSTER_GRID_X x CLUSTER_GRID_Y with CLUSTER_GRID_Z exponential depth slices; a compute pass bins the local lights into per-cluster index lists the forward pass reads instead of iterating every light.
CLUSTER_GRID_Y
Cluster tiles down the screen. See CLUSTER_GRID_X.
CLUSTER_GRID_Z
Exponential depth slices per cluster column. See CLUSTER_GRID_X.
CLUSTER_LIGHT_LIST_STRIDE
u32 slots one cluster occupies in the light-index buffer: the count plus MAX_LIGHTS_PER_CLUSTER indices.
FALLBACK_TEXTURE_COUNT
Pool entries reserved past the real textures: the flat-normal fallback at texture_count, then the white albedo fallback at texture_count + 1. Every backend appends them in this order, so the two *_pool_index resolvers below agree with each backend’s pool construction.
LIGHT_KIND_AREA
GpuLight.kind for a rectangular area light. See LIGHT_KIND_POINT.
LIGHT_KIND_POINT
GpuLight.kind discriminants.
LIGHT_KIND_SPOT
GpuLight.kind for a spot light. See LIGHT_KIND_POINT.
MAX_AREA_LIGHTS
Capacity of the per-scene AreaLightData table. Area lights are far heavier to shade than point or spot lights (a polygon integral per fragment), so the cap is deliberately well under MAX_LOCAL_LIGHTS.
MAX_CLONE_DRAWS
Runtime-clone cap: how many spawned clones the GPU-driven cull records reserve room for, past the streamed-chunk window.
MAX_DIRECTIONAL_LIGHTS
Capacity of the fixed directional-light array in LightUniforms.
MAX_JOINTS
Maximum number of joints in a single skinned-mesh skeleton. Enforced CPU-side as a clamp on each SkinnedDrawObject.joint_count and on the matching skinned_joint_matrices Vec length. The skinned shaders read the joints buffer through a pointer (constant float4x4 *joints) using vertex-encoded joint indices, so the GPU buffer size and joint count are fully dynamic: this constant just caps how many matrices the per-frame upload may carry per object.
MAX_LIGHTS_PER_CLUSTER
Per-cluster light-index list capacity. Each cluster occupies CLUSTER_LIGHT_LIST_STRIDE u32 slots: slot 0 is the count, slots 1.. are light indices into the GpuLight buffer. Lights past the cap are dropped.
MAX_LOCAL_LIGHTS
Capacity of the per-scene local-light storage buffer the forward pass reads. Distinct from MAX_POINT_LIGHTS, which still bounds the fixed LightUniforms point array consumed by the raymarch / fog / probe paths. Lights past this cap are dropped with a warning.
MAX_POINT_LIGHTS
Capacity of the fixed point-light array in LightUniforms, which the raymarch / fog / probe paths read.
MAX_SHADER_BUCKETS
Upper bound on world shader buckets a cull dispatch can route between (the ICB argument-buffer array length in the Metal encode kernel). Mirrored by MAX_SHADER_BUCKETS in cull_encode.metal, enforced by the world-shape check, and quoted as a number in the Shader asset docs.
MAX_SHADOWED_SPOTS
Slices in the spot shadow map array: the number of spot lights that can cast shadows at once. Spots past this still light the scene with shadow_index left at -1. Hardcoded for the same reason as NUM_SHADOW_CASCADES.
NO_ALBEDO_SLOT
Sentinel albedo texture_slot meaning “this object has no albedo texture.” Slot 0 cannot say that: it is a real handle, held by whichever texture the world declares first, so an unset albedo encoded as 0 sampled that texture and tinted it. usize::MAX collides with no handle and lets a backend substitute the synthesized white fallback, which leaves tint as the object’s colour without a shader branch.
NO_NORMAL_MAP_SLOT
Sentinel normal_map_slot meaning “this object has no normal map.” The texture pool is a single handle-indexed table shared by albedo and normal maps, so a real normal map carries its own texture handle (which may be 0); usize::MAX cannot collide with any handle and lets a backend substitute the synthesized flat-normal fallback (tangent-space (0,0,1)) without a shader branch. Backends map this to the fallback’s reserved pool index.
NUM_SHADOW_CASCADES
Number of cascades the directional shadow pre-pass renders into the shadow map array. Hardcoded because changing N requires re-compiling the shaders (the array length appears in the MSL/HLSL/GLSL source).

Functions§

albedo_pool_index
Resolve an albedo texture_slot to its index in the handle-indexed texture pool. A real albedo addresses its own texture slot (clamped into the real-texture range so a stale slot reads the last valid entry rather than out of bounds); NO_ALBEDO_SLOT addresses the white fallback at texture_count + 1, so an untextured material samples white and shows its tint rather than whichever texture happens to hold slot 0.
clone_reserve
How many clone records a world needs reserved. A clone copies an existing draw object’s geometry slice, so a world with no build-time objects has nothing to clone from and reserves none – which is what keeps cull_count() zero for a world with no geometry at all, and so keeps the GPU-driven path (and the pipelines it builds) off for a menu-only world.
draw_args_bucket_bits
Pack a DrawObject’s shader bucket into the GpuDrawArgs::flags upper bits, clamped to the routing budget the cull kernels implement. A bucket past the budget renders with the world default program rather than reading a command region that does not exist; the world-shape check fails such a world at build time, so the clamp is a backstop.
draw_args_flags
Pack the per-frame cull-decision bits for one DrawObject. Mirrors the CPU visible = BVH(cullable) + always_draw partition: an object draws when it is visible and resident, and is frustum-tested only when it has finite bounds.
instance_object_records
Expand every instance of every cluster into a flat GpuObjectData list for the GPU-driven bindless instanced path, in cluster-then-instance order (so a parallel per-instance draw-args list can be walked in the same order). The texture-pool indices are resolved through albedo_pool_index / normal_pool_index, matching build_object_buffer’s static addressing. texture_count is the pool’s real-texture count (the flat-normal fallback sits at texture_count).
normal_pool_index
Resolve a normal_map_slot to its index in the handle-indexed texture pool. A real normal map addresses its own texture slot (clamped into the real-texture range); NO_NORMAL_MAP_SLOT addresses the flat-normal fallback at texture_count (the first reserved entry past the last real texture), so the shader never needs a “has a normal map?” branch.
pack_object_record
Pack one DrawObject into its GpuObjectData record for the DirectX and Vulkan bindless static pass. The caller supplies the resolved texture-pool indices: albedo_index / normal_index are dense indices into the one handle-indexed pool (a normal-less object’s normal_index points at the pool’s flat-normal fallback slot), identical across all three backends.
pack_skinned_record
Build the GPU-driven cull/draw record for one skinned object, folded into the bindless main pass as rigid geometry. The skin compute kernel deforms the bind-pose vertices into MODEL space, so model is applied after skinning (model -> world) exactly like a static object; the cull bound is the padded bind-pose AABB transformed by model. Mirrors pack_instance_record, sourcing material + flat texture indices from the skinned object.
runtime_reserve_full
Whether the runtime reserve has no record left for another object. Streamed chunks and clones share it, and a retired slot frees its record, so what counts is how many objects past the build-time count are resident now.
spot_shadow_slice_size
Per-slice edge of the spot shadow map array, derived from the authored directional shadow_map_size so one quality knob scales both. Quartered because a spot’s cone covers far less world area than a CSM cascade, and the array multiplies the cost by MAX_SHADOWED_SPOTS.