Skip to main content

GpuRenderer

Struct GpuRenderer 

Source
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

Source

pub async fn new<W>( window: Arc<W>, size: (u32, u32), settings: GpuRendererSettings, ) -> Result<Self, GpuInitError>
where W: HasWindowHandle + HasDisplayHandle + Send + Sync + 'static,

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”.

Source

pub fn new_blocking<W>( window: Arc<W>, size: (u32, u32), settings: GpuRendererSettings, ) -> Result<Self, GpuInitError>
where W: HasWindowHandle + HasDisplayHandle + Send + Sync + 'static,

Synchronous wrapper for hosts that don’t have an async runtime. Internally pollster::block_ons Self::new.

§Errors

See Self::new.

Source

pub fn adapter_info(&self) -> &str

Human-readable adapter description — name + backend + device type. The demo host prints this in the title bar.

Source

pub fn device(&self) -> &Device

Borrow the underlying wgpu device — hosts use this to build chunk uploads (GpuChunkResident::upload(gpu.device(), …)).

Source

pub fn queue(&self) -> &Queue

Borrow the wgpu queue — hosts use this for read-back paths (GpuChunkResident::read_voxel_blocking(gpu.device(), gpu.queue(), …)).

Source

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.

Source

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.

Source

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.

Source

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+.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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).

Source

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.

Source

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.

Source

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.

Source

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.

Source

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).

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,