refactor camera and mandelbulb to separate modules
This commit is contained in:
parent
8da858f57f
commit
405d187a29
4 changed files with 103 additions and 72 deletions
12
src/camera.rs
Normal file
12
src/camera.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
pub fn plugin(app: &mut App) {
|
||||||
|
app.add_systems(Startup, setup);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup(mut commands: Commands) {
|
||||||
|
commands.spawn((
|
||||||
|
Camera3d::default(),
|
||||||
|
Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||||
|
));
|
||||||
|
}
|
||||||
84
src/main.rs
84
src/main.rs
|
|
@ -1,32 +1,27 @@
|
||||||
use bevy::{
|
use bevy::{color::palettes::css::RED, prelude::*, render::storage::ShaderStorageBuffer};
|
||||||
color::palettes::css::RED,
|
use mandelbulb::{MandelbulbExtension, MandelbulbMaterial, MandelbulbStorage};
|
||||||
pbr::{ExtendedMaterial, MaterialExtension},
|
|
||||||
prelude::*,
|
|
||||||
render::{render_resource::*, storage::ShaderStorageBuffer},
|
|
||||||
};
|
|
||||||
|
|
||||||
const SHADER_ASSET_PATH: &str = "shaders/material.wgsl";
|
mod camera;
|
||||||
|
mod mandelbulb;
|
||||||
type VoluMaterial = ExtendedMaterial<StandardMaterial, VoluExtension>;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_plugins(MaterialPlugin::<VoluMaterial>::default())
|
.add_plugins((camera::plugin, mandelbulb::plugin))
|
||||||
.add_systems(Startup, setup)
|
.add_systems(Startup, setup)
|
||||||
.add_systems(Update, (rotate_things, update_volu_material))
|
.add_systems(Update, (rotate_things,))
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup(
|
fn setup(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
mut meshes: ResMut<Assets<Mesh>>,
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
mut materials: ResMut<Assets<VoluMaterial>>,
|
mut materials: ResMut<Assets<MandelbulbMaterial>>,
|
||||||
mut buffers: ResMut<Assets<ShaderStorageBuffer>>,
|
mut buffers: ResMut<Assets<ShaderStorageBuffer>>,
|
||||||
) {
|
) {
|
||||||
let transform = Transform::from_xyz(0.0, 0.0, 0.0);
|
let transform = Transform::from_xyz(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
let storage = buffers.add(ShaderStorageBuffer::from(VoluStorage {
|
let storage = buffers.add(ShaderStorageBuffer::from(MandelbulbStorage {
|
||||||
mesh_translation: transform.translation,
|
mesh_translation: transform.translation,
|
||||||
sphere_radius: 1.0,
|
sphere_radius: 1.0,
|
||||||
color: Vec4::default(),
|
color: Vec4::default(),
|
||||||
|
|
@ -37,14 +32,14 @@ fn setup(
|
||||||
|
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Mesh3d(meshes.add(Cuboid::new(2.0, 2.0, 2.0))),
|
Mesh3d(meshes.add(Cuboid::new(2.0, 2.0, 2.0))),
|
||||||
MeshMaterial3d(materials.add(ExtendedMaterial {
|
MeshMaterial3d(materials.add(MandelbulbExtension::create_material(
|
||||||
base: StandardMaterial {
|
StandardMaterial {
|
||||||
base_color: RED.into(),
|
base_color: RED.into(),
|
||||||
alpha_mode: AlphaMode::Blend,
|
alpha_mode: AlphaMode::Blend,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
extension: VoluExtension { storage },
|
storage,
|
||||||
})),
|
))),
|
||||||
transform,
|
transform,
|
||||||
Rotate,
|
Rotate,
|
||||||
));
|
));
|
||||||
|
|
@ -54,11 +49,6 @@ fn setup(
|
||||||
Transform::from_xyz(1.0, 1.0, 1.0).looking_at(Vec3::ZERO, Vec3::Y),
|
Transform::from_xyz(1.0, 1.0, 1.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||||
Rotate,
|
Rotate,
|
||||||
));
|
));
|
||||||
|
|
||||||
commands.spawn((
|
|
||||||
Camera3d::default(),
|
|
||||||
Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
|
|
@ -69,53 +59,3 @@ fn rotate_things(mut q: Query<&mut Transform, With<Rotate>>, time: Res<Time>) {
|
||||||
t.rotate_y(time.delta_secs());
|
t.rotate_y(time.delta_secs());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_volu_material(
|
|
||||||
q: Query<(&Transform, &MeshMaterial3d<VoluMaterial>), Changed<Transform>>,
|
|
||||||
mut volu_materials: ResMut<Assets<VoluMaterial>>,
|
|
||||||
mut buffers: ResMut<Assets<ShaderStorageBuffer>>,
|
|
||||||
time: Res<Time>,
|
|
||||||
) {
|
|
||||||
for (transform, material) in q.iter() {
|
|
||||||
let volu_material = volu_materials.get_mut(material.0.id()).unwrap();
|
|
||||||
|
|
||||||
let buffer = buffers
|
|
||||||
.get_mut(volu_material.extension.storage.id())
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let elapsed = time.elapsed_secs_wrapped();
|
|
||||||
|
|
||||||
let volu_storage = VoluStorage {
|
|
||||||
mesh_translation: transform.translation,
|
|
||||||
sphere_radius: (elapsed.sin() + 3.) / 4.,
|
|
||||||
color: vec4((elapsed.sin() + 1.) / 2., 0.0, 0.0, 1.0),
|
|
||||||
model_inverse: transform.compute_matrix(),
|
|
||||||
power: 8.0,
|
|
||||||
iterations: 32,
|
|
||||||
};
|
|
||||||
|
|
||||||
buffer.set_data(volu_storage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Asset, AsBindGroup, Reflect, Debug, Clone)]
|
|
||||||
struct VoluExtension {
|
|
||||||
#[storage(100, read_only)]
|
|
||||||
storage: Handle<ShaderStorageBuffer>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MaterialExtension for VoluExtension {
|
|
||||||
fn fragment_shader() -> ShaderRef {
|
|
||||||
SHADER_ASSET_PATH.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(ShaderType, Clone, Default, Debug)]
|
|
||||||
pub struct VoluStorage {
|
|
||||||
mesh_translation: Vec3,
|
|
||||||
sphere_radius: f32,
|
|
||||||
color: Vec4,
|
|
||||||
model_inverse: Mat4,
|
|
||||||
power: f32,
|
|
||||||
iterations: i32,
|
|
||||||
}
|
|
||||||
|
|
|
||||||
79
src/mandelbulb.rs
Normal file
79
src/mandelbulb.rs
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
use bevy::{
|
||||||
|
pbr::{ExtendedMaterial, MaterialExtension},
|
||||||
|
prelude::*,
|
||||||
|
render::{
|
||||||
|
render_resource::{AsBindGroup, ShaderRef, ShaderType},
|
||||||
|
storage::ShaderStorageBuffer,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub type MandelbulbMaterial = ExtendedMaterial<StandardMaterial, MandelbulbExtension>;
|
||||||
|
|
||||||
|
const SHADER_ASSET_PATH: &str = "shaders/mandelbulb.wgsl";
|
||||||
|
|
||||||
|
pub fn plugin(app: &mut App) {
|
||||||
|
app.add_plugins(MaterialPlugin::<MandelbulbMaterial>::default())
|
||||||
|
.add_systems(Update, update_volu_material);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_volu_material(
|
||||||
|
q: Query<(&Transform, &MeshMaterial3d<MandelbulbMaterial>)>,
|
||||||
|
mut volu_materials: ResMut<Assets<MandelbulbMaterial>>,
|
||||||
|
mut buffers: ResMut<Assets<ShaderStorageBuffer>>,
|
||||||
|
time: Res<Time>,
|
||||||
|
) {
|
||||||
|
for (transform, material) in q.iter() {
|
||||||
|
let volu_material = volu_materials.get_mut(material.0.id()).unwrap();
|
||||||
|
|
||||||
|
let buffer = buffers
|
||||||
|
.get_mut(volu_material.extension.storage.id())
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let elapsed = time.elapsed_secs_wrapped();
|
||||||
|
|
||||||
|
let volu_storage = MandelbulbStorage {
|
||||||
|
mesh_translation: transform.translation,
|
||||||
|
sphere_radius: (elapsed.sin() + 3.) / 4.,
|
||||||
|
color: vec4((elapsed.sin() + 1.) / 2., 0.0, 0.0, 1.0),
|
||||||
|
model_inverse: transform.compute_matrix(),
|
||||||
|
power: 8.0,
|
||||||
|
iterations: 32,
|
||||||
|
};
|
||||||
|
|
||||||
|
buffer.set_data(volu_storage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Asset, AsBindGroup, Reflect, Debug, Clone)]
|
||||||
|
pub struct MandelbulbExtension {
|
||||||
|
#[storage(100, read_only)]
|
||||||
|
pub storage: Handle<ShaderStorageBuffer>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MaterialExtension for MandelbulbExtension {
|
||||||
|
fn fragment_shader() -> ShaderRef {
|
||||||
|
SHADER_ASSET_PATH.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MandelbulbExtension {
|
||||||
|
pub fn create_material(
|
||||||
|
base: StandardMaterial,
|
||||||
|
storage: Handle<ShaderStorageBuffer>,
|
||||||
|
) -> MandelbulbMaterial {
|
||||||
|
MandelbulbMaterial {
|
||||||
|
base,
|
||||||
|
extension: Self { storage },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(ShaderType, Clone, Default, Debug)]
|
||||||
|
pub struct MandelbulbStorage {
|
||||||
|
pub mesh_translation: Vec3,
|
||||||
|
pub sphere_radius: f32,
|
||||||
|
pub color: Vec4,
|
||||||
|
pub model_inverse: Mat4,
|
||||||
|
pub power: f32,
|
||||||
|
pub iterations: i32,
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue