这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "bevy_gaussian_splatting"
description = "bevy gaussian splatting render pipeline plugin"
version = "5.2.1"
version = "5.3.0"
edition = "2024"
rust-version = "1.85.0"
authors = ["mosure <mitchell@mosure.me>"]
Expand Down Expand Up @@ -55,6 +55,7 @@ default = [

# TODO: bevy_interleave storage bind group read_only per plane attribute support
# "morph_particles",
"morph_interpolate",

"sort_bitonic",
"sort_radix", # TODO: fix macos radix sort
Expand All @@ -77,6 +78,7 @@ io_ply = ["ply-rs"]
material_noise = ["noise", "dep:noise"]

morph_particles = []
morph_interpolate = []

noise = []

Expand Down
65 changes: 23 additions & 42 deletions benches/io.rs
Original file line number Diff line number Diff line change
@@ -1,65 +1,46 @@
use criterion::{
BenchmarkId,
criterion_group,
criterion_main,
Criterion,
Throughput,
};
use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main};

use bevy_gaussian_splatting::{
Gaussian3d,
Gaussian4d,
PlanarGaussian3d,
PlanarGaussian4d,
io::codec::CloudCodec,
random_gaussians_3d,
random_gaussians_4d,
Gaussian3d, Gaussian4d, PlanarGaussian3d, PlanarGaussian4d, io::codec::CloudCodec,
random_gaussians_3d, random_gaussians_4d,
};


const GAUSSIAN_COUNTS: [usize; 4] = [
1000,
10000,
84_348,
1_244_819,
1000, 10000, 84_348, 1_244_819,
// 6_131_954,
];

fn gaussian_cloud_3d_decode_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("encode 3d gaussian clouds");
for count in GAUSSIAN_COUNTS.iter() {
group.throughput(Throughput::Bytes(*count as u64 * std::mem::size_of::<Gaussian3d>() as u64));
group.bench_with_input(
BenchmarkId::new("decode/3d", count),
&count,
|b, &count| {
let gaussians = random_gaussians_3d(*count);
let bytes = gaussians.encode();

b.iter(|| PlanarGaussian3d::decode(bytes.as_slice()));
},
);
group.throughput(Throughput::Bytes(
*count as u64 * std::mem::size_of::<Gaussian3d>() as u64,
));
group.bench_with_input(BenchmarkId::new("decode/3d", count), &count, |b, &count| {
let gaussians = random_gaussians_3d(*count);
let bytes = gaussians.encode();

b.iter(|| PlanarGaussian3d::decode(bytes.as_slice()));
});
}
}

fn gaussian_cloud_4d_decode_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("encode 4d gaussian clouds");
for count in GAUSSIAN_COUNTS.iter() {
group.throughput(Throughput::Bytes(*count as u64 * std::mem::size_of::<Gaussian4d>() as u64));
group.bench_with_input(
BenchmarkId::new("decode/4d", count),
&count,
|b, &count| {
let gaussians = random_gaussians_4d(*count);
let bytes = gaussians.encode();

b.iter(|| PlanarGaussian4d::decode(bytes.as_slice()));
},
);
group.throughput(Throughput::Bytes(
*count as u64 * std::mem::size_of::<Gaussian4d>() as u64,
));
group.bench_with_input(BenchmarkId::new("decode/4d", count), &count, |b, &count| {
let gaussians = random_gaussians_4d(*count);
let bytes = gaussians.encode();

b.iter(|| PlanarGaussian4d::decode(bytes.as_slice()));
});
}
}

criterion_group!{
criterion_group! {
name = io_benches;
config = Criterion::default().sample_size(10);
targets = gaussian_cloud_3d_decode_benchmark,
Expand Down
56 changes: 26 additions & 30 deletions examples/headless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,33 @@
// c_rr --example headless --no-default-features --features "headless" -- [filename]

use bevy::{
prelude::*,
app::ScheduleRunnerPlugin,
core_pipeline::tonemapping::Tonemapping,
app::ScheduleRunnerPlugin, core_pipeline::tonemapping::Tonemapping, prelude::*,
render::renderer::RenderDevice,
};
use bevy_args::BevyArgsPlugin;

use bevy_gaussian_splatting::{
CloudSettings,
GaussianCamera,
PlanarGaussian3d,
PlanarGaussian3dHandle,
GaussianSplattingPlugin,
gaussian::interface::TestCloud,
random_gaussians_3d,
CloudSettings, GaussianCamera, GaussianSplattingPlugin, PlanarGaussian3d,
PlanarGaussian3dHandle, gaussian::interface::TestCloud, random_gaussians_3d,
utils::GaussianSplattingViewer,
};


/// Derived from: https://github.com/bevyengine/bevy/pull/5550
mod frame_capture {
pub mod image_copy {
use std::sync::Arc;

use bevy::prelude::*;
use bevy::render::render_asset::RenderAssets;
use bevy::render::render_graph::{self, NodeRunError, RenderGraph, RenderGraphContext, RenderLabel};
use bevy::render::render_graph::{
self, NodeRunError, RenderGraph, RenderGraphContext, RenderLabel,
};
use bevy::render::renderer::{RenderContext, RenderDevice, RenderQueue};
use bevy::render::{Extract, RenderApp};
use bevy::render::texture::GpuImage;
use bevy::render::{Extract, RenderApp};

use bevy::render::render_resource::{
Buffer, BufferDescriptor, BufferUsages, CommandEncoderDescriptor, Extent3d,
MapMode,
Buffer, BufferDescriptor, BufferUsages, CommandEncoderDescriptor, Extent3d, MapMode,
};
use pollster::FutureExt;
use wgpu::{Maintain, TexelCopyBufferInfo, TexelCopyBufferLayout};
Expand Down Expand Up @@ -88,7 +81,10 @@ mod frame_capture {

render_app.add_systems(ExtractSchedule, image_copy_extract);

let mut graph = render_app.world_mut().get_resource_mut::<RenderGraph>().unwrap();
let mut graph = render_app
.world_mut()
.get_resource_mut::<RenderGraph>()
.unwrap();

graph.add_node(ImageCopyLabel, ImageCopyDriver);
graph.add_node_edge(ImageCopyLabel, bevy::render::graph::CameraDriverLabel);
Expand Down Expand Up @@ -220,7 +216,6 @@ mod frame_capture {

use super::image_copy::ImageCopier;


#[derive(Component, Default)]
pub struct CaptureCamera;

Expand All @@ -244,13 +239,13 @@ mod frame_capture {
}

impl SceneController {
pub fn new(width:u32, height:u32, single_image: bool) -> SceneController {
pub fn new(width: u32, height: u32, single_image: bool) -> SceneController {
SceneController {
state: SceneState::BuildScene,
name: String::from(""),
width,
height,
single_image
single_image,
}
}
}
Expand Down Expand Up @@ -348,7 +343,7 @@ mod frame_capture {
std::fs::create_dir_all(&images_dir).unwrap();

let image_path = images_dir.join(format!("{i}.png"));
if let Err(e) = img.save(image_path){
if let Err(e) = img.save(image_path) {
panic!("Failed to save image: {}", e);
};
}
Expand Down Expand Up @@ -393,7 +388,6 @@ fn setup_gaussian_cloud(
String::from("main_scene"),
);


commands.spawn((
PlanarGaussian3dHandle(cloud),
CloudSettings::default(),
Expand Down Expand Up @@ -428,17 +422,21 @@ fn headless_app() {
};

// setup frame capture
app.insert_resource(frame_capture::scene::SceneController::new(config.width, config.height, config.single_image));
app.insert_resource(frame_capture::scene::SceneController::new(
config.width,
config.height,
config.single_image,
));
app.insert_resource(ClearColor(Color::srgb_u8(0, 0, 0)));

app.add_plugins(
DefaultPlugins
.set(ImagePlugin::default_nearest())
.set(WindowPlugin {
primary_window: None,
exit_condition: bevy::window::ExitCondition::DontExit,
close_when_requested: false,
}),
.set(ImagePlugin::default_nearest())
.set(WindowPlugin {
primary_window: None,
exit_condition: bevy::window::ExitCondition::DontExit,
close_when_requested: false,
}),
);
app.add_plugins(BevyArgsPlugin::<GaussianSplattingViewer>::default());

Expand All @@ -453,13 +451,11 @@ fn headless_app() {
// setup for gaussian splatting
app.add_plugins(GaussianSplattingPlugin);


app.init_resource::<frame_capture::scene::SceneController>();
app.add_event::<frame_capture::scene::SceneController>();

app.add_systems(Startup, setup_gaussian_cloud);


app.run();
}

Expand Down
1 change: 0 additions & 1 deletion examples/minimal.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// TODO: minimal app


fn main() {
println!("Hello, world!");
}
Loading
Loading