Skip to main content

Viewer

Struct Viewer 

Source
pub struct Viewer<G: GaussianPod = DefaultGaussianPod> {
Show 13 fields pub camera_buffer: CameraBuffer, pub model_transform_buffer: ModelTransformBuffer, pub gaussian_transform_buffer: GaussianTransformBuffer, pub gaussians_buffer: GaussiansBuffer<G>, pub indirect_args_buffer: IndirectArgsBuffer, pub radix_sort_indirect_args_buffer: RadixSortIndirectArgsBuffer, pub indirect_indices_buffer: IndirectIndicesBuffer, pub gaussians_depth_buffer: GaussiansDepthBuffer, pub selection_buffer: SelectionBuffer, pub invert_selection_buffer: PreprocessorInvertSelectionBuffer, pub preprocessor: Preprocessor<G>, pub radix_sorter: RadixSorter, pub renderer: Renderer<G>,
}
Expand description

The 3D Gaussian splatting viewer.

This provides all the necessary buffers and operations to render 3D Gaussians:

If you wish to manage these buffers yourself, you do not need to use this struct.

Fields§

§camera_buffer: CameraBuffer§model_transform_buffer: ModelTransformBuffer§gaussian_transform_buffer: GaussianTransformBuffer§gaussians_buffer: GaussiansBuffer<G>§indirect_args_buffer: IndirectArgsBuffer§radix_sort_indirect_args_buffer: RadixSortIndirectArgsBuffer§indirect_indices_buffer: IndirectIndicesBuffer§gaussians_depth_buffer: GaussiansDepthBuffer§selection_buffer: SelectionBuffer§invert_selection_buffer: PreprocessorInvertSelectionBuffer§preprocessor: Preprocessor<G>§radix_sorter: RadixSorter§renderer: Renderer<G>

Implementations§

Source§

impl<G: GaussianPod> Viewer<G>

Source

pub fn new( device: &Device, texture_format: TextureFormat, gaussians: &impl IterGaussian, ) -> Result<Self, ViewerCreateError>

Create a new viewer.

Examples found in repository?
examples/simple.rs (line 167)
110    async fn init(window: Arc<Window>, args: &Args) -> Self {
111        let model_path = &args.model;
112        let size = window.inner_size();
113
114        log::debug!("Creating wgpu instance");
115        let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor::default());
116
117        log::debug!("Creating window surface");
118        let surface = instance.create_surface(window.clone()).expect("surface");
119
120        log::debug!("Requesting adapter");
121        let adapter = instance
122            .request_adapter(&wgpu::RequestAdapterOptions {
123                power_preference: wgpu::PowerPreference::HighPerformance,
124                compatible_surface: Some(&surface),
125                force_fallback_adapter: false,
126            })
127            .await
128            .expect("adapter");
129
130        log::debug!("Requesting device");
131        let (device, queue) = adapter
132            .request_device(&wgpu::DeviceDescriptor {
133                label: Some("Device"),
134                required_limits: adapter.limits(),
135                ..Default::default()
136            })
137            .await
138            .expect("device");
139
140        let surface_caps = surface.get_capabilities(&adapter);
141        let surface_format = surface_caps.formats[0];
142        let config = wgpu::SurfaceConfiguration {
143            usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
144            format: surface_format,
145            width: size.width.max(1),
146            height: size.height.max(1),
147            present_mode: surface_caps.present_modes[0],
148            alpha_mode: surface_caps.alpha_modes[0],
149            view_formats: vec![surface_format.remove_srgb_suffix()],
150            desired_maximum_frame_latency: 2,
151        };
152
153        log::debug!("Configuring surface");
154        surface.configure(&device, &config);
155
156        log::debug!("Creating gaussians");
157        let gaussians = [GaussiansSource::Ply, GaussiansSource::Spz]
158            .into_iter()
159            .find_map(|source| gs::core::Gaussians::read_from_file(model_path, source).ok())
160            .expect("gaussians");
161
162        log::debug!("Creating camera");
163        let camera = gs::Camera::new(0.1..1e4, 60f32.to_radians());
164
165        log::debug!("Creating viewer");
166        let mut viewer =
167            gs::Viewer::new(&device, config.view_formats[0], &gaussians).expect("viewer");
168        viewer.update_model_transform(
169            &queue,
170            Vec3::ZERO,
171            Quat::from_axis_angle(Vec3::Z, 180f32.to_radians()),
172            Vec3::ONE,
173        );
174
175        viewer.update_gaussian_transform(
176            &queue,
177            args.size,
178            match args.mode {
179                DisplayMode::Splat => gs::core::GaussianDisplayMode::Splat,
180                DisplayMode::Ellipse => gs::core::GaussianDisplayMode::Ellipse,
181                DisplayMode::Point => gs::core::GaussianDisplayMode::Point,
182            },
183            gs::core::GaussianShDegree::new(args.sh_degree).expect("sh degree"),
184            args.no_sh0,
185            GaussianMaxStdDev::new(args.std_dev).expect("max std dev"),
186        );
187
188        log::info!("System initialized");
189
190        Self {
191            surface,
192            device,
193            queue,
194            config,
195
196            camera,
197            gaussians,
198            viewer,
199        }
200    }
Source

pub fn new_with_options( device: &Device, texture_format: TextureFormat, gaussians: &impl IterGaussian, options: ViewerCreateOptions, ) -> Result<Self, ViewerCreateError>

Create a new viewer with extra ViewerCreateOptions.

Examples found in repository?
examples/selection.rs (lines 154-164)
96    async fn init(window: Arc<Window>, args: &Args) -> Self {
97        let model_path = &args.model;
98        let filter = args.filter;
99        let immediate = args.immediate;
100        let size = window.inner_size();
101
102        log::debug!("Creating wgpu instance");
103        let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor::default());
104
105        log::debug!("Creating window surface");
106        let surface = instance.create_surface(window.clone()).expect("surface");
107
108        log::debug!("Requesting adapter");
109        let adapter = instance
110            .request_adapter(&wgpu::RequestAdapterOptions {
111                power_preference: wgpu::PowerPreference::HighPerformance,
112                compatible_surface: Some(&surface),
113                force_fallback_adapter: false,
114            })
115            .await
116            .expect("adapter");
117
118        log::debug!("Requesting device");
119        let (device, queue) = adapter
120            .request_device(&wgpu::DeviceDescriptor {
121                label: Some("Device"),
122                required_limits: adapter.limits(),
123                ..Default::default()
124            })
125            .await
126            .expect("device");
127
128        let surface_caps = surface.get_capabilities(&adapter);
129        let surface_format = surface_caps.formats[0];
130        let config = wgpu::SurfaceConfiguration {
131            usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
132            format: surface_format,
133            width: size.width.max(1),
134            height: size.height.max(1),
135            present_mode: surface_caps.present_modes[0],
136            alpha_mode: surface_caps.alpha_modes[0],
137            view_formats: vec![surface_format.remove_srgb_suffix()],
138            desired_maximum_frame_latency: 2,
139        };
140
141        log::debug!("Configuring surface");
142        surface.configure(&device, &config);
143
144        log::debug!("Creating gaussians");
145        let gaussians = [GaussiansSource::Ply, GaussiansSource::Spz]
146            .into_iter()
147            .find_map(|source| gs::core::Gaussians::read_from_file(model_path, source).ok())
148            .expect("gaussians");
149
150        log::debug!("Creating camera");
151        let camera = gs::Camera::new(0.1..1e4, 60f32.to_radians());
152
153        log::debug!("Creating viewer");
154        let mut viewer = gs::Viewer::new_with_options(
155            &device,
156            config.view_formats[0],
157            &gaussians,
158            gs::ViewerCreateOptions {
159                gaussians_buffer_usage:
160                    gs::core::GaussiansBuffer::<gs::DefaultGaussianPod>::DEFAULT_USAGES
161                        | wgpu::BufferUsages::COPY_SRC,
162                ..Default::default()
163            },
164        )
165        .expect("viewer");
166        viewer.update_model_transform(
167            &queue,
168            Vec3::ZERO,
169            Quat::from_axis_angle(Vec3::Z, 180f32.to_radians()),
170            Vec3::ONE,
171        );
172
173        log::debug!("Creating selector");
174        let mut selector = gs::selection::ViewportSelector::new(
175            &device,
176            &queue,
177            UVec2::new(size.width, size.height),
178            &viewer.camera_buffer,
179        )
180        .expect("selector");
181        selector.selector_type = gs::selection::ViewportSelectorType::Brush;
182
183        log::debug!("Creating selection viewport selection modifier");
184        let mut viewport_selection_modifier = gs::editor::NonDestructiveModifier::new(
185            &device,
186            &queue,
187            gs::editor::BasicSelectionModifier::new_with_basic_modifier(
188                &device,
189                &viewer.gaussians_buffer,
190                &viewer.model_transform_buffer,
191                &viewer.gaussian_transform_buffer,
192                vec![gs::selection::create_viewport_bundle::<
193                    gs::DefaultGaussianPod,
194                >(&device)],
195            ),
196            &viewer.gaussians_buffer,
197        )
198        .expect("modifier");
199
200        let viewport_selection_bind_group = viewport_selection_modifier.modifier.selection.bundles
201            [0]
202        .create_bind_group(
203            &device,
204            // index 0 is the Gaussians buffer, so we use 1,
205            // see docs of create_viewport_bundle
206            1,
207            [
208                viewer.camera_buffer.buffer().as_entire_binding(),
209                wgpu::BindingResource::TextureView(selector.texture().view()),
210            ],
211        )
212        .expect("bind group");
213
214        viewport_selection_modifier.modifier.selection_expr =
215            gs::editor::SelectionExpr::Selection(0, vec![viewport_selection_bind_group]);
216
217        viewport_selection_modifier // Non destructive modifier
218            .modifier // Selection modifier
219            .modifier // Basic modifier
220            .basic_color_modifiers_buffer
221            .update_with_pod(
222                &queue,
223                &gs::editor::BasicColorModifiersPod {
224                    rgb_or_hsv: BasicColorRgbOverrideOrHsvModifiersPod::new_rgb_override(
225                        Vec3::new(1.0, 1.0, 0.0),
226                    ),
227                    ..Default::default()
228                },
229            );
230
231        log::debug!("Creating selection viewport texture overlay renderer");
232        let viewport_texture_overlay_renderer =
233            utils::selection::ViewportTextureOverlayRenderer::new(
234                &device,
235                config.view_formats[0],
236                selector.texture(),
237            );
238
239        log::info!("System initialized");
240
241        Self {
242            surface,
243            device,
244            queue,
245            config,
246
247            filter,
248            immediate,
249            inverted: filter,
250            selector_type: None,
251
252            camera,
253            gaussians,
254            viewer,
255            selector,
256
257            viewport_selection_modifier,
258            viewport_texture_overlay_renderer,
259        }
260    }
Source

pub fn update_camera( &mut self, queue: &Queue, camera: &impl CameraTrait, texture_size: UVec2, )

Update the camera.

Examples found in repository?
examples/simple.rs (lines 244-248)
202    fn update(&mut self, input: &core::Input, delta_time: f32) {
203        // Camera movement
204        const SPEED: f32 = 1.0;
205
206        let mut forward = 0.0;
207        if input.held_keys.contains(&KeyCode::KeyW) {
208            forward += SPEED * delta_time;
209        }
210        if input.held_keys.contains(&KeyCode::KeyS) {
211            forward -= SPEED * delta_time;
212        }
213
214        let mut right = 0.0;
215        if input.held_keys.contains(&KeyCode::KeyD) {
216            right += SPEED * delta_time;
217        }
218        if input.held_keys.contains(&KeyCode::KeyA) {
219            right -= SPEED * delta_time;
220        }
221
222        self.camera.move_by(forward, right);
223
224        let mut up = 0.0;
225        if input.held_keys.contains(&KeyCode::Space) {
226            up += SPEED * delta_time;
227        }
228        if input.held_keys.contains(&KeyCode::ShiftLeft) {
229            up -= SPEED * delta_time;
230        }
231
232        self.camera.move_up(up);
233
234        // Camera rotation
235        const SENSITIVITY: f32 = 0.15;
236
237        let yaw = input.mouse_diff.x * SENSITIVITY * delta_time;
238        let pitch = input.mouse_diff.y * SENSITIVITY * delta_time;
239
240        self.camera.pitch_by(-pitch);
241        self.camera.yaw_by(-yaw);
242
243        // Update the viewer
244        self.viewer.update_camera(
245            &self.queue,
246            &self.camera,
247            uvec2(self.config.width, self.config.height),
248        );
249    }
More examples
Hide additional examples
examples/selection.rs (lines 295-299)
262    fn update(&mut self, input: &core::Input, delta_time: f32) {
263        // Toggle selection mode
264        if input.pressed_keys.contains(&KeyCode::KeyN) {
265            self.selector_type = None;
266            log::info!("Selector: None");
267        }
268        if input.pressed_keys.contains(&KeyCode::KeyR) {
269            self.selector_type = Some(gs::selection::ViewportSelectorType::Rectangle);
270            log::info!("Selector: Rectangle");
271            self.selector.selector_type = gs::selection::ViewportSelectorType::Rectangle;
272        }
273        if input.pressed_keys.contains(&KeyCode::KeyB) {
274            self.selector_type = Some(gs::selection::ViewportSelectorType::Brush);
275            log::info!("Selector: Brush");
276            self.selector.selector_type = gs::selection::ViewportSelectorType::Brush;
277        }
278        if input.pressed_keys.contains(&KeyCode::KeyI) {
279            self.inverted = !self.inverted;
280            log::info!("Inverted: {}", self.inverted);
281            if self.filter {
282                self.viewer
283                    .invert_selection_buffer
284                    .update(&self.queue, self.inverted);
285            }
286        }
287
288        if self.selector_type.is_some() {
289            self.update_selection(input, delta_time);
290        } else {
291            self.update_movement(input, delta_time);
292        }
293
294        // Update the viewer
295        self.viewer.update_camera(
296            &self.queue,
297            &self.camera,
298            uvec2(self.config.width, self.config.height),
299        );
300    }
Source

pub fn update_camera_with_pod(&mut self, queue: &Queue, pod: &CameraPod)

Update the camera with CameraPod.

Source

pub fn update_model_transform( &mut self, queue: &Queue, pos: Vec3, rot: Quat, scale: Vec3, )

Update the model transform.

Examples found in repository?
examples/simple.rs (lines 168-173)
110    async fn init(window: Arc<Window>, args: &Args) -> Self {
111        let model_path = &args.model;
112        let size = window.inner_size();
113
114        log::debug!("Creating wgpu instance");
115        let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor::default());
116
117        log::debug!("Creating window surface");
118        let surface = instance.create_surface(window.clone()).expect("surface");
119
120        log::debug!("Requesting adapter");
121        let adapter = instance
122            .request_adapter(&wgpu::RequestAdapterOptions {
123                power_preference: wgpu::PowerPreference::HighPerformance,
124                compatible_surface: Some(&surface),
125                force_fallback_adapter: false,
126            })
127            .await
128            .expect("adapter");
129
130        log::debug!("Requesting device");
131        let (device, queue) = adapter
132            .request_device(&wgpu::DeviceDescriptor {
133                label: Some("Device"),
134                required_limits: adapter.limits(),
135                ..Default::default()
136            })
137            .await
138            .expect("device");
139
140        let surface_caps = surface.get_capabilities(&adapter);
141        let surface_format = surface_caps.formats[0];
142        let config = wgpu::SurfaceConfiguration {
143            usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
144            format: surface_format,
145            width: size.width.max(1),
146            height: size.height.max(1),
147            present_mode: surface_caps.present_modes[0],
148            alpha_mode: surface_caps.alpha_modes[0],
149            view_formats: vec![surface_format.remove_srgb_suffix()],
150            desired_maximum_frame_latency: 2,
151        };
152
153        log::debug!("Configuring surface");
154        surface.configure(&device, &config);
155
156        log::debug!("Creating gaussians");
157        let gaussians = [GaussiansSource::Ply, GaussiansSource::Spz]
158            .into_iter()
159            .find_map(|source| gs::core::Gaussians::read_from_file(model_path, source).ok())
160            .expect("gaussians");
161
162        log::debug!("Creating camera");
163        let camera = gs::Camera::new(0.1..1e4, 60f32.to_radians());
164
165        log::debug!("Creating viewer");
166        let mut viewer =
167            gs::Viewer::new(&device, config.view_formats[0], &gaussians).expect("viewer");
168        viewer.update_model_transform(
169            &queue,
170            Vec3::ZERO,
171            Quat::from_axis_angle(Vec3::Z, 180f32.to_radians()),
172            Vec3::ONE,
173        );
174
175        viewer.update_gaussian_transform(
176            &queue,
177            args.size,
178            match args.mode {
179                DisplayMode::Splat => gs::core::GaussianDisplayMode::Splat,
180                DisplayMode::Ellipse => gs::core::GaussianDisplayMode::Ellipse,
181                DisplayMode::Point => gs::core::GaussianDisplayMode::Point,
182            },
183            gs::core::GaussianShDegree::new(args.sh_degree).expect("sh degree"),
184            args.no_sh0,
185            GaussianMaxStdDev::new(args.std_dev).expect("max std dev"),
186        );
187
188        log::info!("System initialized");
189
190        Self {
191            surface,
192            device,
193            queue,
194            config,
195
196            camera,
197            gaussians,
198            viewer,
199        }
200    }
More examples
Hide additional examples
examples/selection.rs (lines 166-171)
96    async fn init(window: Arc<Window>, args: &Args) -> Self {
97        let model_path = &args.model;
98        let filter = args.filter;
99        let immediate = args.immediate;
100        let size = window.inner_size();
101
102        log::debug!("Creating wgpu instance");
103        let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor::default());
104
105        log::debug!("Creating window surface");
106        let surface = instance.create_surface(window.clone()).expect("surface");
107
108        log::debug!("Requesting adapter");
109        let adapter = instance
110            .request_adapter(&wgpu::RequestAdapterOptions {
111                power_preference: wgpu::PowerPreference::HighPerformance,
112                compatible_surface: Some(&surface),
113                force_fallback_adapter: false,
114            })
115            .await
116            .expect("adapter");
117
118        log::debug!("Requesting device");
119        let (device, queue) = adapter
120            .request_device(&wgpu::DeviceDescriptor {
121                label: Some("Device"),
122                required_limits: adapter.limits(),
123                ..Default::default()
124            })
125            .await
126            .expect("device");
127
128        let surface_caps = surface.get_capabilities(&adapter);
129        let surface_format = surface_caps.formats[0];
130        let config = wgpu::SurfaceConfiguration {
131            usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
132            format: surface_format,
133            width: size.width.max(1),
134            height: size.height.max(1),
135            present_mode: surface_caps.present_modes[0],
136            alpha_mode: surface_caps.alpha_modes[0],
137            view_formats: vec![surface_format.remove_srgb_suffix()],
138            desired_maximum_frame_latency: 2,
139        };
140
141        log::debug!("Configuring surface");
142        surface.configure(&device, &config);
143
144        log::debug!("Creating gaussians");
145        let gaussians = [GaussiansSource::Ply, GaussiansSource::Spz]
146            .into_iter()
147            .find_map(|source| gs::core::Gaussians::read_from_file(model_path, source).ok())
148            .expect("gaussians");
149
150        log::debug!("Creating camera");
151        let camera = gs::Camera::new(0.1..1e4, 60f32.to_radians());
152
153        log::debug!("Creating viewer");
154        let mut viewer = gs::Viewer::new_with_options(
155            &device,
156            config.view_formats[0],
157            &gaussians,
158            gs::ViewerCreateOptions {
159                gaussians_buffer_usage:
160                    gs::core::GaussiansBuffer::<gs::DefaultGaussianPod>::DEFAULT_USAGES
161                        | wgpu::BufferUsages::COPY_SRC,
162                ..Default::default()
163            },
164        )
165        .expect("viewer");
166        viewer.update_model_transform(
167            &queue,
168            Vec3::ZERO,
169            Quat::from_axis_angle(Vec3::Z, 180f32.to_radians()),
170            Vec3::ONE,
171        );
172
173        log::debug!("Creating selector");
174        let mut selector = gs::selection::ViewportSelector::new(
175            &device,
176            &queue,
177            UVec2::new(size.width, size.height),
178            &viewer.camera_buffer,
179        )
180        .expect("selector");
181        selector.selector_type = gs::selection::ViewportSelectorType::Brush;
182
183        log::debug!("Creating selection viewport selection modifier");
184        let mut viewport_selection_modifier = gs::editor::NonDestructiveModifier::new(
185            &device,
186            &queue,
187            gs::editor::BasicSelectionModifier::new_with_basic_modifier(
188                &device,
189                &viewer.gaussians_buffer,
190                &viewer.model_transform_buffer,
191                &viewer.gaussian_transform_buffer,
192                vec![gs::selection::create_viewport_bundle::<
193                    gs::DefaultGaussianPod,
194                >(&device)],
195            ),
196            &viewer.gaussians_buffer,
197        )
198        .expect("modifier");
199
200        let viewport_selection_bind_group = viewport_selection_modifier.modifier.selection.bundles
201            [0]
202        .create_bind_group(
203            &device,
204            // index 0 is the Gaussians buffer, so we use 1,
205            // see docs of create_viewport_bundle
206            1,
207            [
208                viewer.camera_buffer.buffer().as_entire_binding(),
209                wgpu::BindingResource::TextureView(selector.texture().view()),
210            ],
211        )
212        .expect("bind group");
213
214        viewport_selection_modifier.modifier.selection_expr =
215            gs::editor::SelectionExpr::Selection(0, vec![viewport_selection_bind_group]);
216
217        viewport_selection_modifier // Non destructive modifier
218            .modifier // Selection modifier
219            .modifier // Basic modifier
220            .basic_color_modifiers_buffer
221            .update_with_pod(
222                &queue,
223                &gs::editor::BasicColorModifiersPod {
224                    rgb_or_hsv: BasicColorRgbOverrideOrHsvModifiersPod::new_rgb_override(
225                        Vec3::new(1.0, 1.0, 0.0),
226                    ),
227                    ..Default::default()
228                },
229            );
230
231        log::debug!("Creating selection viewport texture overlay renderer");
232        let viewport_texture_overlay_renderer =
233            utils::selection::ViewportTextureOverlayRenderer::new(
234                &device,
235                config.view_formats[0],
236                selector.texture(),
237            );
238
239        log::info!("System initialized");
240
241        Self {
242            surface,
243            device,
244            queue,
245            config,
246
247            filter,
248            immediate,
249            inverted: filter,
250            selector_type: None,
251
252            camera,
253            gaussians,
254            viewer,
255            selector,
256
257            viewport_selection_modifier,
258            viewport_texture_overlay_renderer,
259        }
260    }
Source

pub fn update_model_transform_with_pod( &mut self, queue: &Queue, pod: &ModelTransformPod, )

Update the model transform with ModelTransformPod.

Source

pub fn update_gaussian_transform( &mut self, queue: &Queue, size: f32, display_mode: GaussianDisplayMode, sh_deg: GaussianShDegree, no_sh0: bool, max_std_dev: GaussianMaxStdDev, )

Update the Gaussian transform.

Examples found in repository?
examples/simple.rs (lines 175-186)
110    async fn init(window: Arc<Window>, args: &Args) -> Self {
111        let model_path = &args.model;
112        let size = window.inner_size();
113
114        log::debug!("Creating wgpu instance");
115        let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor::default());
116
117        log::debug!("Creating window surface");
118        let surface = instance.create_surface(window.clone()).expect("surface");
119
120        log::debug!("Requesting adapter");
121        let adapter = instance
122            .request_adapter(&wgpu::RequestAdapterOptions {
123                power_preference: wgpu::PowerPreference::HighPerformance,
124                compatible_surface: Some(&surface),
125                force_fallback_adapter: false,
126            })
127            .await
128            .expect("adapter");
129
130        log::debug!("Requesting device");
131        let (device, queue) = adapter
132            .request_device(&wgpu::DeviceDescriptor {
133                label: Some("Device"),
134                required_limits: adapter.limits(),
135                ..Default::default()
136            })
137            .await
138            .expect("device");
139
140        let surface_caps = surface.get_capabilities(&adapter);
141        let surface_format = surface_caps.formats[0];
142        let config = wgpu::SurfaceConfiguration {
143            usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
144            format: surface_format,
145            width: size.width.max(1),
146            height: size.height.max(1),
147            present_mode: surface_caps.present_modes[0],
148            alpha_mode: surface_caps.alpha_modes[0],
149            view_formats: vec![surface_format.remove_srgb_suffix()],
150            desired_maximum_frame_latency: 2,
151        };
152
153        log::debug!("Configuring surface");
154        surface.configure(&device, &config);
155
156        log::debug!("Creating gaussians");
157        let gaussians = [GaussiansSource::Ply, GaussiansSource::Spz]
158            .into_iter()
159            .find_map(|source| gs::core::Gaussians::read_from_file(model_path, source).ok())
160            .expect("gaussians");
161
162        log::debug!("Creating camera");
163        let camera = gs::Camera::new(0.1..1e4, 60f32.to_radians());
164
165        log::debug!("Creating viewer");
166        let mut viewer =
167            gs::Viewer::new(&device, config.view_formats[0], &gaussians).expect("viewer");
168        viewer.update_model_transform(
169            &queue,
170            Vec3::ZERO,
171            Quat::from_axis_angle(Vec3::Z, 180f32.to_radians()),
172            Vec3::ONE,
173        );
174
175        viewer.update_gaussian_transform(
176            &queue,
177            args.size,
178            match args.mode {
179                DisplayMode::Splat => gs::core::GaussianDisplayMode::Splat,
180                DisplayMode::Ellipse => gs::core::GaussianDisplayMode::Ellipse,
181                DisplayMode::Point => gs::core::GaussianDisplayMode::Point,
182            },
183            gs::core::GaussianShDegree::new(args.sh_degree).expect("sh degree"),
184            args.no_sh0,
185            GaussianMaxStdDev::new(args.std_dev).expect("max std dev"),
186        );
187
188        log::info!("System initialized");
189
190        Self {
191            surface,
192            device,
193            queue,
194            config,
195
196            camera,
197            gaussians,
198            viewer,
199        }
200    }
Source

pub fn update_gaussian_transform_with_pod( &mut self, queue: &Queue, pod: &GaussianTransformPod, )

Update the Gaussian transform with GaussianTransformPod.

Source

pub fn render(&self, encoder: &mut CommandEncoder, texture_view: &TextureView)

Render the viewer.

Examples found in repository?
examples/simple.rs (line 271)
251    fn render(&mut self) {
252        let texture = match self.surface.get_current_texture() {
253            Ok(texture) => texture,
254            Err(e) => {
255                log::error!("Failed to get current texture: {e:?}");
256                return;
257            }
258        };
259        let texture_view = texture.texture.create_view(&wgpu::TextureViewDescriptor {
260            label: Some("Texture View"),
261            format: Some(self.config.view_formats[0]),
262            ..Default::default()
263        });
264
265        let mut encoder = self
266            .device
267            .create_command_encoder(&wgpu::CommandEncoderDescriptor {
268                label: Some("Command Encoder"),
269            });
270
271        self.viewer.render(&mut encoder, &texture_view);
272
273        self.queue.submit(std::iter::once(encoder.finish()));
274        if let Err(e) = self.device.poll(wgpu::PollType::wait_indefinitely()) {
275            log::error!("Failed to poll device: {e:?}");
276        }
277        texture.present();
278    }
More examples
Hide additional examples
examples/selection.rs (line 322)
302    fn render(&mut self) {
303        let texture = match self.surface.get_current_texture() {
304            Ok(texture) => texture,
305            Err(e) => {
306                log::error!("Failed to get current texture: {e:?}");
307                return;
308            }
309        };
310        let texture_view = texture.texture.create_view(&wgpu::TextureViewDescriptor {
311            label: Some("Texture View"),
312            format: Some(self.config.view_formats[0]),
313            ..Default::default()
314        });
315
316        let mut encoder = self
317            .device
318            .create_command_encoder(&wgpu::CommandEncoderDescriptor {
319                label: Some("Command Encoder"),
320            });
321
322        self.viewer.render(&mut encoder, &texture_view);
323
324        if !self.immediate && self.selector_type.is_some() {
325            self.viewport_texture_overlay_renderer
326                .render(&mut encoder, &texture_view);
327        }
328
329        self.queue.submit(std::iter::once(encoder.finish()));
330        if let Err(e) = self.device.poll(wgpu::PollType::wait_indefinitely()) {
331            log::error!("Failed to poll device: {e:?}");
332        }
333        texture.present();
334    }

Trait Implementations§

Source§

impl<G: Debug + GaussianPod> Debug for Viewer<G>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

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> 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, 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,