Expand description
viewport-lib : a 3D viewport library for wgpu applications.
Built on wgpu and glam, with no required UI toolkit. The crate provides
the renderer, camera, picking, and interaction code; host applications keep
their own windowing and event loop.
§Quick start (single viewport)
- Create a
ViewportRendererfrom awgpu::Deviceand target format. - Upload meshes or volumes through
ViewportGpuResources. - Build a
FrameDataeach frame (camera viaCameraFrameandRenderCamera, scene content viaSceneFrame, viewport chrome viaViewportFrame, etc.). - Call
ViewportRenderer::prepareand thenViewportRenderer::paint_to.
§Multi-viewport rendering
To render the same scene from multiple independent cameras (e.g. a CAD quad-view layout), use the split prepare/paint API:
ⓘ
// --- Setup (once at startup) ---
let vp_persp = renderer.create_viewport(&device); // ViewportId(0)
let vp_top = renderer.create_viewport(&device); // ViewportId(1)
let vp_front = renderer.create_viewport(&device); // ViewportId(2)
// --- Each frame ---
// 1. Build per-viewport FrameData (shared scene, independent cameras).
let frame_persp = FrameData {
camera: CameraFrame::from_camera(&cam_persp, vp_size).with_viewport_index(vp_persp.0),
scene: shared_scene.clone(),
..FrameData::default()
};
// ... similarly for vp_top, vp_front ...
// 2. Prepare scene data once (lighting, shadows, batching).
let (scene_fx, _) = frame_persp.effects.split();
renderer.prepare_scene(&device, &queue, &frame_persp, &scene_fx);
// 3. Prepare per-viewport state (camera uniforms, clip planes, overlays).
renderer.prepare_viewport(&device, &queue, vp_persp, &frame_persp);
renderer.prepare_viewport(&device, &queue, vp_top, &frame_top);
renderer.prepare_viewport(&device, &queue, vp_front, &frame_front);
// 4a. LDR path : single render pass with viewport/scissor rects.
let mut rp = encoder.begin_render_pass(...);
rp.set_viewport(0.0, 0.0, half_w, half_h, 0.0, 1.0);
renderer.paint_viewport(&mut rp, vp_persp, &frame_persp);
rp.set_viewport(half_w, 0.0, half_w, half_h, 0.0, 1.0);
renderer.paint_viewport(&mut rp, vp_top, &frame_top);
// ...
// 4b. HDR path : one command buffer per viewport, each into its own texture.
let cmd0 = renderer.render_viewport(&device, &queue, &view0, vp_persp, &frame_persp);
let cmd1 = renderer.render_viewport(&device, &queue, &view1, vp_top, &frame_top);
queue.submit([cmd0, cmd1]);Single-viewport applications require zero code changes:
prepare, paint_to, and
render continue to work as before.
Re-exports§
pub use geometry::bvh;pub use geometry::primitives;pub use interaction::clip_plane;pub use interaction::gizmo;pub use interaction::input;pub use interaction::manipulation;pub use interaction::picking;pub use interaction::selection;pub use interaction::snap;pub use scene::aabb;pub use scene::material;pub use scene::traits;pub use widgets::axes_indicator;pub use error::ViewportError;pub use error::ViewportResult;pub use camera::animator::CameraAnimator;pub use camera::animator::CameraDamping;pub use camera::animator::Easing;pub use camera::camera::Camera;pub use camera::camera::CameraTarget;pub use camera::camera::Projection;pub use camera::frustum::CullStats;pub use camera::frustum::Frustum;pub use camera::track::CameraTrack;pub use camera::track::interpolate_camera;pub use camera::turntable::TurntableController;pub use camera::view_preset::ViewPreset;pub use scene::aabb::Aabb;pub use scene::material::AppearanceSettings;pub use scene::material::BackfacePattern;pub use scene::material::BackfacePolicy;pub use scene::material::Material;pub use scene::material::ParamVis;pub use scene::material::ParamVisMode;pub use scene::material::PatternConfig;pub use scene::scene::Group;pub use scene::scene::GroupId;pub use scene::scene::Layer;pub use scene::scene::LayerId;pub use scene::scene::Scene;pub use scene::scene::SceneNode;pub use scene::traits::RenderMode;pub use scene::traits::ViewportObject;pub use geometry::bvh::PickAccelerator;pub use geometry::implicit::ImplicitRenderOptions;pub use geometry::implicit::march_implicit_surface;pub use geometry::implicit::march_implicit_surface_colour;pub use geometry::isoline::IsolineItem;pub use geometry::isoline::extract_isolines;pub use geometry::marching_cubes::VolumeData;pub use geometry::marching_cubes::extract_isosurface;pub use interaction::gizmo::Gizmo;pub use interaction::gizmo::GizmoAxis;pub use interaction::gizmo::GizmoMode;pub use interaction::gizmo::GizmoSpace;pub use interaction::gizmo::PivotMode;pub use interaction::gizmo::gizmo_center_for_pivot;pub use interaction::input::Action;pub use interaction::input::ActionState;pub use interaction::input::Binding;pub use interaction::input::FrameInput;pub use interaction::input::InputMode;pub use interaction::input::InputSystem;pub use interaction::input::KeyCode;pub use interaction::input::Modifiers;pub use interaction::input::MouseButton;pub use interaction::input::ActionFrame;pub use interaction::input::BindingPreset;pub use interaction::input::ButtonState;pub use interaction::input::ModifiersMatch;pub use interaction::input::OrbitCameraController;pub use interaction::input::ResolvedActionState;pub use interaction::input::ScrollUnits;pub use interaction::input::ViewportBinding;pub use interaction::input::ViewportContext;pub use interaction::input::ViewportEvent;pub use interaction::input::ViewportGesture;pub use interaction::input::ViewportInput;pub use interaction::input::viewport_all_bindings;pub use interaction::manipulation::solvers::angular_rotation_from_cursor;pub use interaction::manipulation::solvers::constrained_scale;pub use interaction::manipulation::solvers::constrained_translation;pub use interaction::manipulation::GizmoInfo;pub use interaction::manipulation::ManipResult;pub use interaction::manipulation::ManipulationContext;pub use interaction::manipulation::ManipulationController;pub use interaction::manipulation::ManipulationKind;pub use interaction::manipulation::ManipulationState;pub use interaction::manipulation::TransformDelta;pub use interaction::widgets::BoxWidget;pub use interaction::widgets::CylinderWidget;pub use interaction::widgets::DiskWidget;pub use interaction::widgets::LineProbeWidget;pub use interaction::widgets::PlaneWidget;pub use interaction::widgets::PolylineWidget;pub use interaction::widgets::SphereWidget;pub use interaction::widgets::SplineWidget;pub use interaction::widgets::WidgetContext;pub use interaction::widgets::WidgetResult;pub use interaction::clip_plane::ClipAxis;pub use interaction::clip_plane::ClipPlaneContext;pub use interaction::clip_plane::ClipPlaneController;pub use interaction::clip_plane::ClipPlaneDelta;pub use interaction::clip_plane::ClipPlaneHit;pub use interaction::clip_plane::ClipPlaneResult;pub use interaction::clip_plane::ClipPlaneSessionKind;pub use interaction::clip_plane::hit_test_normal_handle;pub use interaction::clip_plane::hit_test_plane_quad;pub use interaction::clip_plane::plane_from_axis_preset;pub use interaction::clip_plane::project_drag_onto_normal;pub use interaction::clip_plane::ray_plane_intersection;pub use interaction::clip_plane::snap_plane_distance;pub use interaction::pick_mask::PickMask;pub use interaction::picking::GpuPickHit;pub use interaction::picking::PickHit;pub use interaction::picking::ProbeBinding;pub use interaction::picking::RectPickResult;pub use interaction::picking::nearest_vertex_on_hit;pub use interaction::picking::pick_gaussian_splat_cpu;pub use interaction::picking::pick_gaussian_splat_rect;pub use interaction::picking::pick_point_cloud_cpu;pub use interaction::picking::pick_rect;pub use interaction::picking::pick_scene_accelerated_with_probe_cpu;pub use interaction::picking::pick_scene_nodes_with_probe_cpu;pub use interaction::picking::pick_scene_with_probe_cpu;pub use interaction::picking::pick_transparent_volume_mesh_cpu;pub use interaction::picking::pick_transparent_volume_mesh_rect;pub use interaction::picking::pick_volume_cpu;pub use interaction::picking::pick_volume_rect;pub use interaction::picking::voxel_world_aabb;pub use interaction::selection::NodeId;pub use interaction::selection::Selection;pub use interaction::snap::ConstraintOverlay;pub use interaction::snap::SnapConfig;pub use interaction::sub_object;pub use interaction::sub_object::CellSelectionInfo;pub use interaction::sub_object::PolylineSelectionInfo;pub use interaction::sub_object::SubObjectRef;pub use interaction::sub_object::SubSelection;pub use interaction::sub_object::SubSelectionRef;pub use interaction::sub_object::VolumeSelectionInfo;pub use widgets::axes_indicator::AxisView;pub use renderer::shader_hashes::ShaderValidation;pub use renderer::stats::FrameStats;pub use renderer::stats::PerformancePolicy;pub use renderer::stats::QualityPreset;pub use renderer::stats::RuntimeMode;pub use renderer::CameraFrame;pub use renderer::CameraFrustumItem;pub use renderer::ClipObject;pub use renderer::ClipShape;pub use renderer::ComputeFilterItem;pub use renderer::ComputeFilterKind;pub use renderer::EffectsFrame;pub use renderer::EnvironmentMap;pub use renderer::FilterMode;pub use renderer::FrameData;pub use renderer::GaussianSplatData;pub use renderer::GaussianSplatId;pub use renderer::GaussianSplatItem;pub use renderer::GlyphItem;pub use renderer::GlyphType;pub use renderer::GroundPlane;pub use renderer::GroundPlaneMode;pub use renderer::ImageAnchor;pub use renderer::ImageSliceItem;pub use renderer::InteractionFrame;pub use renderer::LabelAnchor;pub use renderer::LabelItem;pub use renderer::LightKind;pub use renderer::LightSource;pub use renderer::LightingSettings;pub use renderer::LoadingBarAnchor;pub use renderer::LoadingBarItem;pub use renderer::OverlayFrame;pub use renderer::OverlayImageItem;pub use renderer::PickId;pub use renderer::PickRectResult;pub use renderer::PointCloudItem;pub use renderer::PointRenderMode;pub use renderer::PolylineItem;pub use renderer::PostProcessSettings;pub use renderer::RenderCamera;pub use renderer::RibbonItem;pub use renderer::RulerItem;pub use renderer::ScalarBarAnchor;pub use renderer::ScalarBarItem;pub use renderer::ScalarBarOrientation;pub use renderer::SceneEffects;pub use renderer::SceneFrame;pub use renderer::SceneRenderItem;pub use renderer::ScreenImageItem;pub use renderer::ShDegree;pub use renderer::ShadowFilter;pub use renderer::SliceAxis;pub use renderer::SpriteItem;pub use renderer::SpriteSizeMode;pub use renderer::StreamtubeItem;pub use renderer::SurfaceLICConfig;pub use renderer::SurfaceLICItem;pub use renderer::SurfaceSubmission;pub use renderer::TensorGlyphItem;pub use renderer::ToneMapping;pub use renderer::TransparentVolumeMeshItem;pub use renderer::TubeItem;pub use renderer::ViewportEffects;pub use renderer::ViewportFrame;pub use renderer::ViewportId;pub use renderer::ViewportRenderer;pub use renderer::VolumeItem;pub use renderer::VolumeMeshItem;pub use renderer::VolumeSurfaceSliceItem;pub use renderer::aabb_wireframe_polyline;pub use quantities::edge_one_form_to_glyphs;pub use quantities::face_intrinsic_to_glyphs;pub use quantities::polyline_edge_vectors_to_glyphs;pub use quantities::polyline_node_vectors_to_glyphs;pub use quantities::vertex_intrinsic_to_glyphs;pub use quantities::volume_mesh_cell_vectors_to_glyphs;pub use quantities::volume_mesh_vertex_vectors_to_glyphs;pub use resources::ClipVolumeUniform;Deprecated pub use resources::colourmap_data::export_paraview_xml_colourmap;pub use resources::colourmap_data::lerp_colourmap_lut;pub use resources::colourmap_data::parse_paraview_xml_colourmap;pub use resources::mesh_store::MeshId;pub use resources::sparse_volume::SparseVolumeGridData;pub use resources::volume_mesh::CELL_SENTINEL;pub use resources::volume_mesh::TET_SENTINEL;Deprecated pub use resources::volume_mesh::VolumeMeshData;pub use resources::volume_mesh::extract_clipped_volume_faces;pub use resources::AttributeData;pub use resources::AttributeKind;pub use resources::AttributeRef;pub use resources::BuiltinColourmap;pub use resources::BuiltinMatcap;pub use resources::CLIP_VOLUME_MAX;pub use resources::CameraUniform;pub use resources::ClipVolumeEntry;pub use resources::ClipVolumesUniform;pub use resources::ColourmapId;pub use resources::ComputeFilterResult;pub use resources::FontError;pub use resources::FontHandle;pub use resources::GpuImplicitItem;pub use resources::GpuImplicitOptions;pub use resources::GpuMarchingCubesJob;pub use resources::ImplicitBlendMode;pub use resources::ImplicitPrimitive;pub use resources::LightUniform;pub use resources::LightsUniform;pub use resources::MatcapId;pub use resources::MeshData;pub use resources::ProjectedTetId;pub use resources::SingleLightUniform;pub use resources::ViewportGpuResources;pub use resources::VolumeGpuId;pub use resources::VolumeId;pub use resources::lerp_attributes;
Modules§
- camera
- Arcball camera, frustum, view presets, and animator.
- error
- Error types for the viewport library. Error types for the viewport library.
- geometry
- BVH picking, marching cubes, isolines, and cap geometry.
- interaction
- Gizmo, snap, selection, picking, and input.
- quantities
- On-surface vector quantities (intrinsic vectors, Whitney one-forms). On-surface vector quantity utilities.
- renderer
- Main viewport renderer wrapping all GPU resources.
ViewportRenderer: the main entry point for the viewport library. - resources
- GPU resource container (pipelines, buffers, bind groups).
- scene
- Scene graph, material, traits, and AABB.
- widgets
- Axes orientation indicator.