BasicColorModifiersBuffer

Struct BasicColorModifiersBuffer 

Source
pub struct BasicColorModifiersBuffer(/* private fields */);
Expand description

The basic color modifiers buffer for the BasicModifierBundle.

This buffer holds the data for basic color modifications, including RGB override or HSV modifications, alpha, contrast, exposure, and gamma adjustments.

Implementations§

Source§

impl BasicColorModifiersBuffer

Source

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

Create a new basic color modifiers buffer.

Source

pub fn update( &self, queue: &Queue, rgb_or_hsv: BasicColorRgbOverrideOrHsvModifiersPod, alpha: f32, contrast: f32, exposure: f32, gamma: f32, )

Update the basic color modifiers.

Examples found in repository?
examples/modify.rs (lines 122-132)
76async fn main() {
77    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
78
79    let args = Args::parse();
80    let model_path = &args.model;
81
82    log::debug!("Creating wgpu instance");
83    let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor::default());
84
85    log::debug!("Requesting adapter");
86    let adapter = instance
87        .request_adapter(&wgpu::RequestAdapterOptions::default())
88        .await
89        .expect("adapter");
90
91    log::debug!("Requesting device");
92    let (device, queue) = adapter
93        .request_device(&wgpu::DeviceDescriptor {
94            label: Some("Device"),
95            required_limits: adapter.limits(),
96            ..Default::default()
97        })
98        .await
99        .expect("device");
100
101    log::debug!("Creating gaussians");
102    let gaussians = [
103        gs::core::GaussiansSource::Ply,
104        gs::core::GaussiansSource::Spz,
105    ]
106    .into_iter()
107    .find_map(|source| gs::core::Gaussians::read_from_file(model_path, source).ok())
108    .expect("gaussians");
109
110    log::debug!("Creating editor");
111    let editor = gs::Editor::<GaussianPod>::new(&device, &gaussians);
112
113    log::debug!("Creating basic modifier");
114    let basic_modifier = gs::BasicModifier::<GaussianPod>::new(
115        &device,
116        &editor.gaussians_buffer,
117        &editor.model_transform_buffer,
118        &editor.gaussian_transform_buffer,
119    );
120
121    log::debug!("Configuring modifiers");
122    basic_modifier.basic_color_modifiers_buffer.update(
123        &queue,
124        match args.override_rgb {
125            true => gs::BasicColorRgbOverrideOrHsvModifiersPod::new_rgb_override,
126            false => gs::BasicColorRgbOverrideOrHsvModifiersPod::new_hsv_modifiers,
127        }(Vec3::from_slice(&args.rgb_or_hsv)),
128        args.alpha,
129        args.contrast,
130        args.exposure,
131        args.gamma,
132    );
133
134    log::info!("Starting editing process");
135    let time = std::time::Instant::now();
136
137    log::debug!("Editing Gaussians");
138    let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
139        label: Some("Edit Encoder"),
140    });
141
142    editor.apply(
143        &device,
144        &mut encoder,
145        [&basic_modifier as &dyn gs::Modifier<GaussianPod>],
146    );
147
148    queue.submit(Some(encoder.finish()));
149
150    device
151        .poll(wgpu::PollType::wait_indefinitely())
152        .expect("poll");
153
154    log::info!("Editing process completed in {:?}", time.elapsed());
155
156    log::debug!("Downloading Gaussians");
157    let modified_gaussians = editor
158        .gaussians_buffer
159        .download_gaussians(&device, &queue)
160        .await
161        .map(|gs| {
162            match &args.output[args.output.len().saturating_sub(4)..] {
163                ".ply" => {
164                    gs::core::Gaussians::Ply(gs::core::PlyGaussians::from_iter(gs.into_iter()))
165                }
166                ".spz" => {
167                    gs::core::Gaussians::Spz(
168                        gs::core::SpzGaussians::from_gaussians_with_options(
169                            gs,
170                            &gs::core::SpzGaussiansFromGaussianSliceOptions {
171                                version: 2, // Version 2 is more widely supported as of now
172                                ..Default::default()
173                            },
174                        )
175                        .expect("SpzGaussians from gaussians"),
176                    )
177                }
178                _ => panic!("Unsupported output file extension, expected .ply or .spz"),
179            }
180        })
181        .expect("gaussians download");
182
183    log::debug!("Writing modified Gaussians to output file");
184    modified_gaussians
185        .write_to_file(&args.output)
186        .expect("write modified Gaussians to output file");
187
188    log::info!("Modified Gaussians written to {}", args.output);
189}
More examples
Hide additional examples
examples/modify_selection.rs (lines 199-209)
137async fn main() {
138    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
139
140    let args = Args::parse();
141    let model_path = &args.model;
142    let pos = Vec3::from_slice(&args.pos);
143    let rot = Quat::from_slice(&args.rot);
144    let scale = Vec3::from_slice(&args.scale);
145    let shape = match args.shape {
146        Shape::Sphere => gs::SelectionBundle::<GaussianPod>::create_sphere_bundle,
147        Shape::Box => gs::SelectionBundle::<GaussianPod>::create_box_bundle,
148    };
149    let repeat = args.repeat;
150    let offset = Vec3::from_slice(&args.offset);
151
152    log::debug!("Creating wgpu instance");
153    let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor::default());
154
155    log::debug!("Requesting adapter");
156    let adapter = instance
157        .request_adapter(&wgpu::RequestAdapterOptions::default())
158        .await
159        .expect("adapter");
160
161    log::debug!("Requesting device");
162    let (device, queue) = adapter
163        .request_device(&wgpu::DeviceDescriptor {
164            label: Some("Device"),
165            required_limits: adapter.limits(),
166            ..Default::default()
167        })
168        .await
169        .expect("device");
170
171    log::debug!("Creating gaussians");
172    let gaussians = [
173        gs::core::GaussiansSource::Ply,
174        gs::core::GaussiansSource::Spz,
175    ]
176    .into_iter()
177    .find_map(|source| gs::core::Gaussians::read_from_file(model_path, source).ok())
178    .expect("gaussians");
179
180    log::debug!("Creating editor");
181    let editor = gs::Editor::<GaussianPod>::new(&device, &gaussians);
182
183    log::debug!("Creating shape selection compute bundle");
184    let shape_selection = shape(&device);
185
186    log::debug!("Creating basic selection modifier");
187    let mut basic_selection_modifier = gs::SelectionModifier::new_with_basic_modifier(
188        &device,
189        &editor.gaussians_buffer,
190        &editor.model_transform_buffer,
191        &editor.gaussian_transform_buffer,
192        vec![shape_selection],
193    );
194
195    log::debug!("Configuring modifiers");
196    basic_selection_modifier
197        .modifier
198        .basic_color_modifiers_buffer
199        .update(
200            &queue,
201            match args.override_rgb {
202                true => gs::BasicColorRgbOverrideOrHsvModifiersPod::new_rgb_override,
203                false => gs::BasicColorRgbOverrideOrHsvModifiersPod::new_hsv_modifiers,
204            }(Vec3::from_slice(&args.rgb_or_hsv)),
205            args.alpha,
206            args.contrast,
207            args.exposure,
208            args.gamma,
209        );
210
211    log::debug!("Creating shape selection buffers");
212    let shape_selection_buffers = (0..repeat)
213        .map(|i| {
214            let offset_pos = pos + offset * i as f32;
215            let buffer = gs::InvTransformBuffer::new(&device);
216            buffer.update_with_scale_rot_pos(&queue, scale, rot, offset_pos);
217            buffer
218        })
219        .collect::<Vec<_>>();
220
221    log::debug!("Creating shape selection bind groups");
222    let shape_selection_bind_groups = shape_selection_buffers
223        .iter()
224        .map(|buffer| {
225            basic_selection_modifier.selection.bundles[0]
226                .create_bind_group(
227                    &device,
228                    // index 0 is the Gaussians buffer, so we use 1,
229                    // see docs of create_sphere_bundle or create_box_bundle
230                    1,
231                    [buffer.buffer().as_entire_binding()],
232                )
233                .expect("bind group")
234        })
235        .collect::<Vec<_>>();
236
237    log::debug!("Creating selection expression");
238    basic_selection_modifier.selection_expr = shape_selection_bind_groups.into_iter().fold(
239        gs::SelectionExpr::Identity,
240        |acc, bind_group| {
241            acc.union(gs::SelectionExpr::selection(
242                0, // the 0 here is the bundle index in the selection bundle
243                vec![bind_group],
244            ))
245        },
246    );
247
248    log::info!("Starting editing process");
249    let time = std::time::Instant::now();
250
251    log::debug!("Editing Gaussians");
252    let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
253        label: Some("Edit Encoder"),
254    });
255
256    editor.apply(
257        &device,
258        &mut encoder,
259        [&basic_selection_modifier as &dyn gs::Modifier<GaussianPod>],
260    );
261
262    queue.submit(Some(encoder.finish()));
263
264    device
265        .poll(wgpu::PollType::wait_indefinitely())
266        .expect("poll");
267
268    log::info!("Editing process completed in {:?}", time.elapsed());
269
270    log::debug!("Downloading Gaussians");
271    let modified_gaussians = editor
272        .gaussians_buffer
273        .download_gaussians(&device, &queue)
274        .await
275        .map(|gs| {
276            match &args.output[args.output.len().saturating_sub(4)..] {
277                ".ply" => {
278                    gs::core::Gaussians::Ply(gs::core::PlyGaussians::from_iter(gs.into_iter()))
279                }
280                ".spz" => {
281                    gs::core::Gaussians::Spz(
282                        gs::core::SpzGaussians::from_gaussians_with_options(
283                            gs,
284                            &gs::core::SpzGaussiansFromGaussianSliceOptions {
285                                version: 2, // Version 2 is more widely supported as of now
286                                ..Default::default()
287                            },
288                        )
289                        .expect("SpzGaussians from gaussians"),
290                    )
291                }
292                _ => panic!("Unsupported output file extension, expected .ply or .spz"),
293            }
294        })
295        .expect("gaussians download");
296
297    log::debug!("Writing modified Gaussians to output file");
298    modified_gaussians
299        .write_to_file(&args.output)
300        .expect("write modified Gaussians to output file");
301
302    log::info!("Modified Gaussians written to {}", args.output);
303}
Source

pub fn update_with_pod(&self, queue: &Queue, pod: &BasicColorModifiersPod)

Update the basic color modifiers buffer with BasicColorModifiersPod.

Trait Implementations§

Source§

impl BufferWrapper for BasicColorModifiersBuffer

Source§

fn buffer(&self) -> &Buffer

Returns a reference to the buffer data.
Source§

const DEFAULT_USAGES: BufferUsages = _

The default usages.
Source§

fn download<'life0, 'life1, 'life2, 'async_trait, T>( &'life0 self, device: &'life1 Device, queue: &'life2 Queue, ) -> Pin<Box<dyn Future<Output = Result<Vec<T>, DownloadBufferError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, Self: Send + Sync + 'async_trait, T: 'async_trait + NoUninit + AnyBitPattern,

Download the buffer data into a Vec.
Source§

fn prepare_download( &self, device: &Device, encoder: &mut CommandEncoder, ) -> Buffer

Prepare for downloading the buffer data. Read more
Source§

fn map_download<'life0, 'life1, 'async_trait, T>( download: &'life0 Buffer, device: &'life1 Device, ) -> Pin<Box<dyn Future<Output = Result<Vec<T>, DownloadBufferError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, T: 'async_trait + NoUninit + AnyBitPattern, Self: Send + 'async_trait,

Map the download buffer to read the buffer data. Read more
Source§

fn map_download_with_poll_type<'life0, 'life1, 'async_trait, T>( download: &'life0 Buffer, device: &'life1 Device, poll_type: PollType<SubmissionIndex>, ) -> Pin<Box<dyn Future<Output = Result<Vec<T>, DownloadBufferError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, T: 'async_trait + NoUninit + AnyBitPattern,

Map the download buffer to read the buffer data with custom wgpu::PollType. Read more
Source§

impl Clone for BasicColorModifiersBuffer

Source§

fn clone(&self) -> BasicColorModifiersBuffer

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for BasicColorModifiersBuffer

Source§

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

Formats the value using the given formatter. Read more
Source§

impl FixedSizeBufferWrapper for BasicColorModifiersBuffer

Source§

type Pod = BasicColorModifiersPod

The POD element type that defines the layout/size.
Source§

fn pod_size() -> u64

Returns the size in bytes of the POD element.
Source§

fn verify_buffer_size( buffer: &Buffer, ) -> Result<(), FixedSizeBufferWrapperError>

Check if the given buffer matches the expected size. Read more
Source§

fn download_single( &self, device: &Device, queue: &Queue, ) -> impl Future<Output = Result<Self::Pod, DownloadBufferError>> + Send
where Self: Send + Sync, Self::Pod: NoUninit + AnyBitPattern,

Download a single FixedSizeBufferWrapper::Pod.
Source§

impl From<BasicColorModifiersBuffer> for Buffer

Source§

fn from(wrapper: BasicColorModifiersBuffer) -> Self

Converts to this type from the input type.
Source§

impl TryFrom<Buffer> for BasicColorModifiersBuffer

Source§

type Error = FixedSizeBufferWrapperError

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

fn try_from(buffer: Buffer) -> Result<Self, Self::Error>

Performs the conversion.

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. 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,