pub struct GpuRenderer { /* private fields */ }Expand description
WGPU-backed renderer. Owns the device, queue, and surface
bound to the host’s window. Self::render is the GPU.1
clear-to-colour path; Self::render_chunk is GPU.3’s
single-chunk DDA marcher.
The window is consumed only at construction — wgpu’s
Surface<'static> keeps its own Arc clone of the handle, so
the renderer holds no window field of its own.
Implementations§
Source§impl GpuRenderer
impl GpuRenderer
Sourcepub async fn new<W>(
window: Arc<W>,
size: (u32, u32),
settings: GpuRendererSettings,
) -> Result<Self, GpuInitError>
pub async fn new<W>( window: Arc<W>, size: (u32, u32), settings: GpuRendererSettings, ) -> Result<Self, GpuInitError>
Stand up the device + surface + swapchain on window. Async
because wgpu::Adapter/Device requests are.
window is any raw-window-handle provider (winit, SDL,
GLFW, …) wrapped in an Arc; size is its initial physical
framebuffer size in pixels — passed explicitly so the renderer
stays decoupled from any one windowing library’s size API.
§Errors
Returns GpuInitError if surface creation, adapter
selection, or device request fails. Hosts treat any error as
“fall back to the CPU path”.
Sourcepub fn new_blocking<W>(
window: Arc<W>,
size: (u32, u32),
settings: GpuRendererSettings,
) -> Result<Self, GpuInitError>
pub fn new_blocking<W>( window: Arc<W>, size: (u32, u32), settings: GpuRendererSettings, ) -> Result<Self, GpuInitError>
Sourcepub fn adapter_info(&self) -> &str
pub fn adapter_info(&self) -> &str
Human-readable adapter description — name + backend + device type. The demo host prints this in the title bar.
Sourcepub fn device(&self) -> &Device
pub fn device(&self) -> &Device
Borrow the underlying wgpu device — hosts use this to build
chunk uploads (GpuChunkResident::upload(gpu.device(), …)).
Sourcepub fn queue(&self) -> &Queue
pub fn queue(&self) -> &Queue
Borrow the wgpu queue — hosts use this for read-back paths
(GpuChunkResident::read_voxel_blocking(gpu.device(), gpu.queue(), …)).
Sourcepub fn set_sky_panorama(&mut self, rgba: &[u8], width: u32, height: u32)
pub fn set_sky_panorama(&mut self, rgba: &[u8], width: u32, height: u32)
GPU.8 — upload an equirectangular panorama as the scene’s
sky texture. rgba is row-major, width × height pixels,
4 bytes per pixel (R, G, B, A). The shader samples it with
u = atan2(dir.x, dir.y) / (2π) + 0.5 (azimuth) and
v = acos(-dir.z) / π (elevation), matching standard
equirectangular layout (top of image = zenith for voxlap’s
+z = down basis).
§Panics
If rgba.len() != (width * height * 4) as usize.
Sourcepub fn set_fog(&mut self, color: [f32; 3], near: f32, far: f32)
pub fn set_fog(&mut self, color: [f32; 3], near: f32, far: f32)
GPU.8 — set the fog blend. color is per-channel [0, 1];
near/far are world-space ray distances in voxel units.
Hits with t < near show their full colour; hits with
t > far show color exclusively; in between is a
smoothstep blend.
Sourcepub fn resize(&mut self, width: u32, height: u32)
pub fn resize(&mut self, width: u32, height: u32)
Re-configure the swapchain to a new physical size. Call from
WindowEvent::Resized. Drops the chunk-DDA storage texture
so Self::render_chunk rebuilds it at the new size.
Sourcepub fn render(&mut self)
pub fn render(&mut self)
GPU.1 render: single render pass clearing the swapchain to a slowly drifting colour, then presenting. Voxels arrive in GPU.3+.
Sourcepub fn render_chunk(
&mut self,
resident: &GpuChunkResident,
camera: &Camera,
max_scan_dist: u32,
)
pub fn render_chunk( &mut self, resident: &GpuChunkResident, camera: &Camera, max_scan_dist: u32, )
GPU.3 single-chunk render. Dispatches chunk_dda.wgsl
against resident’s storage buffers, then blits the
low-res storage texture to the swapchain. camera.position
is in chunk-local voxel units (host translates from
world coords). max_scan_dist caps the per-pixel DDA loop —
scene-demo wires + / - through this each frame.
§Panics
Internally expects the chunk-DDA resources to be built —
they are constructed at the top of this function if missing.
Cannot fire in normal control flow.
Sourcepub fn render_grid(
&mut self,
grid: &GpuGridResident,
camera: &Camera,
max_outer_steps: u32,
)
pub fn render_grid( &mut self, grid: &GpuGridResident, camera: &Camera, max_outer_steps: u32, )
GPU.4 render — outer DDA over chunk indices + inner DDA into
non-empty chunks. camera.position is in grid-local
voxel units. max_outer_steps caps how many chunks the
outer DDA may traverse per ray (scene-demo wires + / -
through this).
§Panics
Internally expects the grid-DDA resources to be built;
they are constructed at the top of this function if missing.
Sourcepub fn render_scene(
&mut self,
scene: &GpuSceneResident,
cameras: &[Camera],
sprite_camera: &Camera,
fov_y_rad: f32,
max_outer_steps: u32,
)
pub fn render_scene( &mut self, scene: &GpuSceneResident, cameras: &[Camera], sprite_camera: &Camera, fov_y_rad: f32, max_outer_steps: u32, )
GPU.5 render — multi-grid scene marcher. cameras[i] is the
world camera transformed into grid i’s local frame
(caller-supplied; see scene-demo’s redraw_gpu for the
glam-based transform). fov_y_rad is the shared vertical
FOV; max_outer_steps caps per-ray chunk-DDA work for each
grid.
§Panics
If cameras.len() != scene.grid_count or
scene.grid_count > MAX_SCENE_GRIDS.
cameras[i] is grid i’s world camera transformed into that
grid’s local frame (the grid marcher works in grid-local space).
sprite_camera is the world camera: instanced sprites carry
world-space positions/transforms, so they must project through
the untransformed world camera — not cameras[0], which is only
the world camera when grid 0 is at identity.
Sourcepub fn render_clear_deferred(&mut self)
pub fn render_clear_deferred(&mut self)
Like Self::render (clear to colour) but deferred: stashes
the frame for Self::present / [Self::paint_egui] instead of
presenting. The facade uses this before any grid is resident so a
HUD can still be painted over an empty scene.
Sourcepub fn present(&mut self)
pub fn present(&mut self)
Present the frame stashed by the last deferred render
(Self::render_scene / Self::render_clear_deferred). No-op
if nothing is pending (e.g. the surface was lost mid-render).
Sourcepub fn read_depth_pixel(&self, x: u32, y: u32) -> Option<f32>
pub fn read_depth_pixel(&self, x: u32, y: u32) -> Option<f32>
Read back the per-pixel world-t depth at window pixel (x, y)
from the last rendered frame, for screen→world picking. Returns
the distance t along the (normalised) view ray to the nearest
scene-grid surface, so the host reconstructs the world hit as
cam.pos + t * normalize(ray_dir). None for out-of-bounds
pixels, sky / no-hit (the T_INF sentinel), or when no scene
frame has been rendered.
The depth buffer is the SCENE pass’s output (terrain + grids), untouched by the sprite pass (which reads it read-only), so a cursor sprite under the pointer does not occlude the pick.
Synchronous: copies the depth buffer to a mapped staging buffer
and blocks on device.poll(Wait). Cheap enough for click-time
picks; do not call it every frame.
Requires the last frame to have written depth, which happens
when sprites are present (write_depth). The pick demo always
has a cursor sprite, so this holds.
Sourcepub fn pixel_ray(
&self,
right: [f64; 3],
down: [f64; 3],
forward: [f64; 3],
x: f64,
y: f64,
) -> Option<[f64; 3]>
pub fn pixel_ray( &self, right: [f64; 3], down: [f64; 3], forward: [f64; 3], x: f64, y: f64, ) -> Option<[f64; 3]>
World-space view-ray direction (un-normalised) for window pixel
(x, y), under the GPU marcher’s projection — the canonical GPU
unproject, mirroring scene_dda.wgsl’s render_scene
(vertical-FOV pinhole). Uses the last-rendered frame’s target
size + FOV; None before the first scene render. Pair with
Self::read_depth_pixel for screen→world picking.
Sourcepub fn set_sprite_instances(
&mut self,
registry: &SpriteModelRegistry,
instances: &[SpriteInstance],
)
pub fn set_sprite_instances( &mut self, registry: &SpriteModelRegistry, instances: &[SpriteInstance], )
GPU.10.1 — upload a sprite model registry + its instances for the DDA path. An empty instance slice clears all sprites.
Sourcepub fn set_sprite_lod_px(&mut self, px: f32)
pub fn set_sprite_lod_px(&mut self, px: f32)
GPU.10.4 — set the LOD pixel threshold: a sprite steps to the
next mip once a mip-0 voxel would project below px screen
pixels. 1.0 is the natural “no sub-pixel voxels” default;
larger values force LOD in closer (useful for inspection).
Clamped to ≥ 0.25.
Sourcepub fn set_scene_mip_scan_dist(&mut self, dist: f32)
pub fn set_scene_mip_scan_dist(&mut self, dist: f32)
GPU.11.1 — set the scene-grid LOD scan distance (world units).
A chunk entered at world-t t is marched at mip
floor(log2(max(t, msd) / msd)), clamped to its grid’s mip
ladder. 0 disables LOD (always mip-0). Larger values push
the coarser mips farther out — the axis-aligned-mip-beams
mitigation lever (GPU.11.2). Default 64 (matches CPU
mip_scan_dist).