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:
- Buffers
- Operations
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>
impl<G: GaussianPod> Viewer<G>
Sourcepub fn new(
device: &Device,
texture_format: TextureFormat,
gaussians: &impl IterGaussian,
) -> Result<Self, ViewerCreateError>
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 }Sourcepub fn new_with_options(
device: &Device,
texture_format: TextureFormat,
gaussians: &impl IterGaussian,
options: ViewerCreateOptions,
) -> Result<Self, ViewerCreateError>
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 }Sourcepub fn update_camera(
&mut self,
queue: &Queue,
camera: &impl CameraTrait,
texture_size: UVec2,
)
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
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 }Sourcepub fn update_camera_with_pod(&mut self, queue: &Queue, pod: &CameraPod)
pub fn update_camera_with_pod(&mut self, queue: &Queue, pod: &CameraPod)
Update the camera with CameraPod.
Sourcepub fn update_model_transform(
&mut self,
queue: &Queue,
pos: Vec3,
rot: Quat,
scale: Vec3,
)
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
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 }Sourcepub fn update_model_transform_with_pod(
&mut self,
queue: &Queue,
pod: &ModelTransformPod,
)
pub fn update_model_transform_with_pod( &mut self, queue: &Queue, pod: &ModelTransformPod, )
Update the model transform with ModelTransformPod.
Sourcepub fn update_gaussian_transform(
&mut self,
queue: &Queue,
size: f32,
display_mode: GaussianDisplayMode,
sh_deg: GaussianShDegree,
no_sh0: bool,
max_std_dev: GaussianMaxStdDev,
)
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 }Sourcepub fn update_gaussian_transform_with_pod(
&mut self,
queue: &Queue,
pod: &GaussianTransformPod,
)
pub fn update_gaussian_transform_with_pod( &mut self, queue: &Queue, pod: &GaussianTransformPod, )
Update the Gaussian transform with GaussianTransformPod.
Sourcepub fn render(&self, encoder: &mut CommandEncoder, texture_view: &TextureView)
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
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§
Auto Trait Implementations§
impl<G> Freeze for Viewer<G>
impl<G = GaussianPodWithShSingleCov3dSingleConfigs> !RefUnwindSafe for Viewer<G>
impl<G> Send for Viewer<G>
impl<G> Sync for Viewer<G>
impl<G> Unpin for Viewer<G>where
G: Unpin,
impl<G> UnsafeUnpin for Viewer<G>
impl<G = GaussianPodWithShSingleCov3dSingleConfigs> !UnwindSafe for Viewer<G>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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