pub trait Modifier<G: GaussianPod> {
// Required method
fn apply(
&self,
device: &Device,
encoder: &mut CommandEncoder,
gaussians: &GaussiansBuffer<G>,
model_transform: &ModelTransformBuffer,
gaussian_transform: &GaussianTransformBuffer,
);
}Expand description
A trait to apply modifier to Gaussians.
§Overview
This trait simply defines a method to apply modifications to a set of Gaussians stored in a
GaussiansBuffer. It makes it convenient for users to apply a sequence of modifications.
The trait is also blanket implemented for closures with the same signature, allowing users to easily create modifier closures instead of having to define a modifier struct.
Editor also provides an apply method which takes a slice of
Modifiers to apply them in sequence to the stored Gaussians.
§Usage
There are many ways to use this but the recommended way is to implement this trait for a closure
which dispatch a ComputeBundle.
// Create an editor that holds the buffers for the Gaussians and will apply the modifier
let editor = Editor::new(
&device,
&vec![core::Gaussian {
rot: Quat::IDENTITY,
pos: Vec3::ZERO,
color: U8Vec4::ZERO,
sh: [Vec3::ZERO; 15],
scale: Vec3::ONE,
}],
);
// Create the modifier compute bundle
let my_modifier_bundle = core::ComputeBundleBuilder::new()
.label("My Modifier")
.bind_group_layouts([
// For accessing Gaussians and transforms
&MODIFIER_GAUSSIANS_BIND_GROUP_LAYOUT_DESCRIPTOR,
// Your custom bind group layout here
&MY_CUSTOM_BIND_GROUP_LAYOUT_DESCRIPTOR,
])
.resolver({
let mut resolver =
wesl::StandardResolver::new("path/to/my/folder/containing/wesl");
// Required for using core buffer structs.
resolver.add_package(&core::shader::PACKAGE);
// Optionally add this for some utility functions.
resolver.add_package(&shader::PACKAGE);
resolver
})
.main_shader("package::my_wesl_filename".parse().unwrap())
.entry_point("main")
.wesl_compile_options(wesl::CompileOptions {
// Required for enabling the correct features for core struct.
features: GaussianPod::wesl_features(),
..Default::default()
})
.build(
&device,
[
vec![
editor.gaussians_buffer.buffer().as_entire_binding(),
editor.model_transform_buffer.buffer().as_entire_binding(),
editor.gaussian_transform_buffer.buffer().as_entire_binding(),
],
vec![my_buffer.buffer().as_entire_binding()],
],
)
.map_err(|e| log::error!("{e}"))
.expect("my modifier bundle");
// Create the modifier closure
// This function signature implements Modifier by default
let my_modifier =
|_device: &wgpu::Device,
encoder: &mut wgpu::CommandEncoder,
gaussians: &GaussiansBuffer<GaussianPod>,
_model_transform: &ModelTransformBuffer,
_gaussian_transform: &GaussianTransformBuffer| {
my_modifier_bundle.dispatch(encoder, gaussians.len() as u32);
};
// Apply the modifier using the editor
editor.apply(
&device,
&mut encoder,
[&my_modifier as &dyn Modifier<GaussianPod>],
);§Shader Format
You may copy and paste the following shader bindings for
MODIFIER_GAUSSIANS_BIND_GROUP_LAYOUT_DESCRIPTOR into your custom selection operation
shader to ensure that the bindings are correct, then add your own bindings after that.
import wgpu_3dgs_core::{
gaussian::Gaussian,
gaussian_transform::GaussianTransform,
model_transform::ModelTransform,
};
@group(0) @binding(0)
var<storage, read_write> gaussians: array<Gaussian>;
@group(0) @binding(1)
var<uniform> model_transform: ModelTransform;
@group(0) @binding(2)
var<uniform> gaussian_transform: GaussianTransform;
// Your custom bindings here...
//
// You may also apply modifier to selected gaussians only by adding:
// @group(1) @binding(N)
// var<storage, read> selection: array<u32>;
override workgroup_size: u32;
@compute @workgroup_size(workgroup_size)
fn main(@builtin(global_invocation_id) id: vec3<u32>) {
let index = id.x;
if index >= arrayLength(&gaussians) {
return;
}
@if(/* using selection buffer */) {
let word_index = index / 32u;
let bit_index = index % 32u;
let bit_mask = 1u << bit_index;
if (selection[word_index] & bit_mask) == 0 {
return;
}
}
var gaussian = gaussians[index];
// Your custom modifier operation code here...
gaussians[index] = gaussian;
}Required Methods§
Sourcefn apply(
&self,
device: &Device,
encoder: &mut CommandEncoder,
gaussians: &GaussiansBuffer<G>,
model_transform: &ModelTransformBuffer,
gaussian_transform: &GaussianTransformBuffer,
)
fn apply( &self, device: &Device, encoder: &mut CommandEncoder, gaussians: &GaussiansBuffer<G>, model_transform: &ModelTransformBuffer, gaussian_transform: &GaussianTransformBuffer, )
Apply the modifier to the Gaussians.