Skip to main content

ViewportRenderer

Struct ViewportRenderer 

Source
pub struct ViewportRenderer { /* private fields */ }
Expand description

Renderer wrapping all GPU resources and providing prepare() and paint() methods.

Implementations§

Source§

impl ViewportRenderer

Source

pub fn pick( &self, click_pos: Vec2, viewport_size: Vec2, view_proj: Mat4, mask: PickMask, ) -> Option<PickHit>

Pick the nearest item or sub-element under click_pos.

Dispatches across all item types retained from the last prepare() call. The mask controls which item types and sub-element levels participate.

Returns None if nothing matching the mask is under the cursor.

§Arguments
  • click_pos - cursor position in viewport pixels (top-left origin)
  • viewport_size - viewport width x height in pixels
  • view_proj - combined view x projection matrix from the last frame
  • mask - which item types and sub-element levels to include
§Example
if let Some(hit) = renderer.pick(cursor, vp_size, view_proj, PickMask::FACE) {
    println!("hit face {:?} on object {}", hit.sub_object, hit.id);
}
Source

pub fn pick_rect( &self, rect_min: Vec2, rect_max: Vec2, viewport_size: Vec2, view_proj: Mat4, mask: PickMask, ) -> PickRectResult

Pick all items or sub-elements inside a screen-space rectangle.

Dispatches across all item types retained from the last prepare() call. The mask controls which item types and sub-element levels participate.

§Arguments
  • rect_min - top-left corner of the selection rect in viewport pixels
  • rect_max - bottom-right corner of the selection rect in viewport pixels
  • viewport_size - viewport width x height in pixels
  • view_proj - combined view x projection matrix from the last frame
  • mask - which item types and sub-element levels to include
Source

pub fn pick_scene_gpu( &mut self, device: &Device, queue: &Queue, cursor: Vec2, frame: &FrameData, ) -> Option<GpuPickHit>

GPU object-ID pick: renders the scene to an offscreen R32Uint texture and reads back the single pixel under cursor.

This is O(1) in mesh complexity : every object is rendered with a flat u32 ID, and only one pixel is read back. For triangle-level queries (barycentric scalar probe, exact world position), use the CPU crate::interaction::picking::pick_scene_cpu path instead.

The pipeline is lazily initialized on first call : zero overhead when this method is never invoked.

§Arguments
  • device : wgpu device
  • queue : wgpu queue
  • cursor : cursor position in viewport-local pixels (top-left origin)
  • frame : current grouped frame data (camera, scene surfaces, viewport size)
§Returns

Some(GpuPickHit) if an object is under the cursor, None if empty space.

Source§

impl ViewportRenderer

Source

pub fn render_offscreen( &mut self, device: &Device, queue: &Queue, frame: &FrameData, width: u32, height: u32, ) -> Vec<u8>

Render a frame to an offscreen texture and return raw RGBA bytes.

Creates a temporary wgpu::Texture render target of the given dimensions, runs all render passes (shadow, scene, post-processing) into it via render(), then copies the result back to CPU memory.

No OS window or wgpu::Surface is required. The caller is responsible for initialising the wgpu adapter with compatible_surface: None and for constructing a valid FrameData (including viewport_size matching width/height).

Returns width * height * 4 bytes in RGBA8 layout. The caller encodes to PNG/EXR independently : no image codec dependency in this crate.

Source§

impl ViewportRenderer

Source

pub fn new(device: &Device, target_format: TextureFormat) -> Self

Create a new renderer with default settings (no MSAA). Call once at application startup.

Source

pub fn with_sample_count( device: &Device, target_format: TextureFormat, sample_count: u32, ) -> Self

Create a new renderer with the specified MSAA sample count (1, 2, or 4).

When using MSAA (sample_count > 1), the caller must create multisampled colour and depth textures and use them as render pass attachments with the final surface texture as the resolve target.

Source

pub fn resources(&self) -> &ViewportGpuResources

Access the underlying GPU resources (e.g. for mesh uploads).

Source

pub fn last_frame_stats(&self) -> FrameStats

Performance counters from the last completed frame.

Source

pub fn disable_gpu_driven_culling(&mut self)

Disable GPU-driven culling, reverting to the direct draw path.

Has no effect when the device does not support INDIRECT_FIRST_INSTANCE (culling is already disabled on those devices).

Source

pub fn force_dirty(&mut self)

Force a full instance buffer upload on the next frame.

Normally the renderer skips GPU writes for instanced batches whose data has not changed since the last upload. Call this when you have mutated batch-relevant state through a path the renderer cannot observe (for example, directly modifying GPU buffer contents or scene items after collect_render_items runs). The flag is consumed once and resets automatically after the next prepare call.

Source

pub fn enable_gpu_driven_culling(&mut self)

Re-enable GPU-driven culling after a call to disable_gpu_driven_culling.

Has no effect when the device does not support INDIRECT_FIRST_INSTANCE.

Source

pub fn set_runtime_mode(&mut self, mode: RuntimeMode)

Set the runtime mode controlling internal default behavior.

  • [RuntimeMode::Interactive]: full picking rate, full quality (default).
  • [RuntimeMode::Playback]: picking throttled to reduce CPU overhead during animation.
  • [RuntimeMode::Paused]: full picking rate, full quality.
  • [RuntimeMode::Capture]: full quality, intended for screenshot/export workflows.
Source

pub fn runtime_mode(&self) -> RuntimeMode

Return the current runtime mode.

Source

pub fn set_performance_policy(&mut self, policy: PerformancePolicy)

Set the performance policy controlling target FPS, render scale bounds, and permitted quality reductions.

The internal adaptation controller activates when policy.allow_dynamic_resolution is true and policy.target_fps is Some. It adjusts render_scale within [min_render_scale, max_render_scale] each frame based on total_frame_ms.

Source

pub fn performance_policy(&self) -> PerformancePolicy

Return the active performance policy.

Source

pub fn set_render_scale(&mut self, scale: f32)

Manually set the render scale.

Effective when performance_policy.allow_dynamic_resolution is false. When dynamic resolution is enabled the adaptation controller overrides this value each frame.

The value is clamped to [policy.min_render_scale, policy.max_render_scale].

Works on both the LDR and HDR render paths. On the HDR path, the scene, bloom, SSAO, tone-map, and FXAA all run at the scaled resolution; the result is upscale-blitted to native resolution before overlays and grid.

Source

pub fn set_target_fps(&mut self, fps: Option<f32>)

Set the target frame rate used to compute [FrameStats::missed_budget].

Convenience wrapper that updates performance_policy.target_fps.

Source

pub fn resources_mut(&mut self) -> &mut ViewportGpuResources

Mutable access to the underlying GPU resources (e.g. for mesh uploads).

Source

pub fn is_using_instanced_path(&self) -> bool

Returns true when the current frame is rendered via the instanced draw path.

When true, edits to mesh.wgsl shadow sampling code have no effect - the active shader is mesh_instanced.wgsl. Check this before testing shader changes.

Source

pub fn instanced_batch_count(&self) -> usize

Returns the number of instanced batches prepared for the current frame.

Zero when using the non-instanced path. Each batch corresponds to a distinct (MeshId, material) combination in the scene.

Source

pub fn shadow_debug_stats(&self) -> ShadowDebugStats

Returns per-frame shadow and lighting pipeline statistics for debug inspection.

All fields reflect the most recently completed prepare call (one frame behind the display). Returns default values before the first prepare call.

Source

pub fn read_debug_pixel( &self, device: &Device, queue: &Queue, x: u32, y: u32, ) -> Option<[f32; 4]>

Read the debug values at a specific pixel from the per-fragment storage buffer.

Returns None when debug_vis is inactive (no buffer allocated) or when (x, y) is outside the viewport. The four channels correspond to the current R/G/B channel selectors plus 1.0 for alpha.

This submits a GPU-to-CPU copy and waits synchronously. Only call from outside a render pass (e.g., in the next frame’s prepare step), not inside paint callbacks.

The returned values are from the previous rendered frame.

Source

pub fn upload_gaussian_splats( &mut self, device: &Device, queue: &Queue, data: &GaussianSplatData, ) -> ViewportResult<GaussianSplatId>

Upload a Gaussian splat set to the GPU.

Call once per splat set at startup or when it changes. The returned GaussianSplatId is valid until remove_gaussian_splats is called.

§Errors

Returns ViewportError::InvalidGaussianSplatData if data.positions is empty or if positions, scales, rotations, and opacities differ in length.

§Examples
let result = renderer.upload_gaussian_splats(device, queue, &GaussianSplatData::default());
assert!(matches!(result, Err(ViewportError::InvalidGaussianSplatData { .. })));
Source

pub fn remove_gaussian_splats(&mut self, id: GaussianSplatId)

Remove an uploaded Gaussian splat set by handle.

After this call the id is invalid and must not be submitted in SceneFrame.

Source

pub fn upload_environment_map( &mut self, device: &Device, queue: &Queue, pixels: &[f32], width: u32, height: u32, ) -> ViewportResult<()>

Upload an equirectangular HDR environment map and precompute IBL textures.

pixels is row-major RGBA f32 data (4 floats per texel), widthxheight. This rebuilds camera bind groups so shaders immediately see the new textures.

§Errors

Returns ViewportError::InvalidTextureData if pixels.len() does not equal width * height * 4.

§Examples
// 2x2 RGBA image requires exactly 16 floats.
let result = renderer.upload_environment_map(device, queue, &[0.0f32; 12], 2, 2);
assert!(matches!(result, Err(ViewportError::InvalidTextureData { expected: 16, actual: 12 })));
Source

pub fn create_viewport(&mut self, device: &Device) -> ViewportId

Create a new viewport slot and return its handle.

The returned ViewportId is stable for the lifetime of the renderer. Pass it to prepare_viewport, paint_viewport, and render_viewport each frame.

Also set the viewport slot on the camera frame when building the FrameData for this viewport:

let id = renderer.create_viewport(&device);
let frame = FrameData {
    camera: CameraFrame::from_camera(&cam, size).with_viewport_id(id),
    ..Default::default()
};
Source

pub fn destroy_viewport(&mut self, id: ViewportId)

Release the heavy GPU texture memory (HDR targets, OIT, bloom, SSAO) held by id.

The slot index is not reclaimed : future calls with this ViewportId will lazily recreate the texture resources as needed. This is useful when a viewport is hidden or minimised and you want to reduce VRAM pressure without invalidating the handle.

Source

pub fn owned(&mut self) -> OwnedPath<'_>

Returns the owned-encoder rendering path.

Use when you own the window loop and wgpu encoder (winit, raw wgpu). See OwnedPath for available methods.

Source

pub fn pass(&mut self) -> PassPath<'_>

Returns the pass-based rendering path.

Use when a framework provides you with a render pass (eframe, iced). See PassPath for available methods.

Source

pub fn pass_view(&self) -> PassView<'_>

Returns a read-only paint view for framework paint callbacks.

Use this in callbacks where only a shared reference to the renderer is available (e.g. eframe’s CallbackTrait::paint where callback_resources is &CallbackResources). Exposes only the paint methods, not prepare.

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> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_sync(self: Box<T>) -> Box<dyn Any + Send + Sync>

Converts Box<Trait> (where Trait: DowncastSync) to Box<dyn Any + Send + Sync>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Converts Arc<Trait> (where Trait: DowncastSync) to Arc<Any>, which can then be downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
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> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

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

Source§

impl<T> WasmNotSendSync for T

Source§

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