Added Materials - Removed moon and advanced orbits for now to focus on post processing and materials
This commit is contained in:
parent
573e9e9687
commit
cb64d94c09
@ -22,7 +22,7 @@ pub async fn run() {
|
||||
radius: 6.371e6,
|
||||
});
|
||||
|
||||
let earth_position = sim.bodies[1].position;
|
||||
/*let earth_position = sim.bodies[1].position;
|
||||
let earth_velocity = sim.bodies[1].velocity;
|
||||
|
||||
sim.add_body(Body {
|
||||
@ -31,7 +31,7 @@ pub async fn run() {
|
||||
velocity: earth_velocity + Vector3::new(0.0, 1022.0, 0.0),
|
||||
mass: 7.342e22,
|
||||
radius: 1.737e6,
|
||||
});
|
||||
});*/
|
||||
}
|
||||
|
||||
let sim_clone = simulator.clone();
|
||||
|
||||
@ -9,6 +9,7 @@ mod renderer;
|
||||
mod instance_manager;
|
||||
mod globals;
|
||||
mod geometry_manager;
|
||||
mod material;
|
||||
|
||||
pub use body::Body;
|
||||
|
||||
|
||||
58
solar_engine/src/material.rs
Normal file
58
solar_engine/src/material.rs
Normal file
@ -0,0 +1,58 @@
|
||||
use wgpu::{Buffer, Device, Queue};
|
||||
use wgpu::util::DeviceExt;
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Pod, Zeroable)]
|
||||
pub struct GpuMaterial {
|
||||
pub albedo: [f32; 3],
|
||||
pub emissive: [f32; 3],
|
||||
pub metallic: f32,
|
||||
pub roughness: f32,
|
||||
}
|
||||
|
||||
pub struct MaterialManager {
|
||||
materials: Vec<GpuMaterial>,
|
||||
buffer: Buffer,
|
||||
pub layout: wgpu::BindGroupLayout,
|
||||
pub bind_group: wgpu::BindGroup,
|
||||
}
|
||||
|
||||
impl MaterialManager {
|
||||
pub fn new(device: &Device, materials: Vec<GpuMaterial>) -> Self {
|
||||
let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("Material Buffer"),
|
||||
contents: bytemuck::cast_slice(&materials),
|
||||
usage: wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST,
|
||||
});
|
||||
|
||||
let layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: Some("Material BindGroupLayout"),
|
||||
entries: &[wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Buffer {
|
||||
ty: wgpu::BufferBindingType::Storage { read_only: true },
|
||||
has_dynamic_offset: false,
|
||||
min_binding_size: None,
|
||||
},
|
||||
count: None,
|
||||
}],
|
||||
});
|
||||
|
||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
label: Some("Material BindGroup"),
|
||||
layout: &layout,
|
||||
entries: &[wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: buffer.as_entire_binding(),
|
||||
}],
|
||||
});
|
||||
|
||||
Self { materials, buffer, layout, bind_group }
|
||||
}
|
||||
|
||||
pub fn update(&mut self, queue: &Queue) {
|
||||
queue.write_buffer(&self.buffer, 0, bytemuck::cast_slice(&self.materials));
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,7 @@ use crate::globals::GlobalsManager;
|
||||
use crate::instance_manager::InstanceManager;
|
||||
use crate::light::LightManager;
|
||||
use wgpu::{Device, Queue, SurfaceTexture, TextureView};
|
||||
use crate::material::MaterialManager;
|
||||
|
||||
pub struct RenderInstance {
|
||||
pub position: cgmath::Vector3<f32>,
|
||||
@ -77,7 +78,7 @@ impl Vertex {
|
||||
pub struct Renderer {
|
||||
pipeline: wgpu::RenderPipeline,
|
||||
depth_texture: TextureView,
|
||||
sample_count: u32,
|
||||
sample_count: u32
|
||||
}
|
||||
|
||||
impl Renderer {
|
||||
@ -86,6 +87,7 @@ impl Renderer {
|
||||
config: &wgpu::SurfaceConfiguration,
|
||||
global_layout: &wgpu::BindGroupLayout,
|
||||
light_manager: &mut LightManager,
|
||||
material_manager: &MaterialManager,
|
||||
camera: &Camera,
|
||||
sample_count: u32,
|
||||
) -> Self {
|
||||
@ -109,6 +111,7 @@ impl Renderer {
|
||||
global_layout,
|
||||
&light_manager.layout,
|
||||
&cluster_buffers.layout,
|
||||
&material_manager.layout,
|
||||
],
|
||||
push_constant_ranges: &[],
|
||||
});
|
||||
@ -206,6 +209,7 @@ impl Renderer {
|
||||
light_manager: &mut LightManager,
|
||||
geometry: &GeometryManager,
|
||||
instances: &InstanceManager,
|
||||
material_manager: &mut MaterialManager,
|
||||
) -> Result<(), wgpu::SurfaceError> {
|
||||
// Update uniform buffer
|
||||
globals.update(queue, camera);
|
||||
@ -220,6 +224,9 @@ impl Renderer {
|
||||
light_manager.update_cluster_buffers(device, queue, &assignment);
|
||||
light_manager.update_gpu(queue);
|
||||
|
||||
// Update material buffer
|
||||
material_manager.update(queue);
|
||||
|
||||
let multisampled_texture = device.create_texture(&wgpu::TextureDescriptor {
|
||||
label: Some("Multisample Target"),
|
||||
size: wgpu::Extent3d {
|
||||
@ -274,6 +281,7 @@ impl Renderer {
|
||||
if let Some(clusters) = &light_manager.cluster_buffers {
|
||||
pass.set_bind_group(2, &clusters.bind_group, &[]);
|
||||
}
|
||||
pass.set_bind_group(3, &material_manager.bind_group, &[]);
|
||||
|
||||
for shape in geometry.shapes() {
|
||||
if let Some(mesh) = geometry.get(&shape) {
|
||||
|
||||
@ -62,6 +62,17 @@ var<storage, read> cluster_light_indices: array<u32>;
|
||||
@group(2) @binding(1)
|
||||
var<storage, read> cluster_offsets: array<vec2<u32>>;
|
||||
|
||||
struct GpuMaterial {
|
||||
albedo: vec3<f32>,
|
||||
emissive: vec3<f32>,
|
||||
metallic: f32,
|
||||
roughness: f32,
|
||||
_pad: vec2<f32>,
|
||||
};
|
||||
|
||||
@group(3) @binding(0)
|
||||
var<storage, read> materials: array<GpuMaterial>;
|
||||
|
||||
@vertex
|
||||
fn vs_main(vertex: VertexInput, instance: InstanceInput) -> VSOutput {
|
||||
var out: VSOutput;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Mutex;
|
||||
use cgmath::{InnerSpace, Vector3};
|
||||
use crate::body::Body;
|
||||
use rayon::prelude::*;
|
||||
|
||||
const G: f64 = 6.67430e-11;
|
||||
|
||||
@ -50,10 +51,12 @@ impl Simulator {
|
||||
|
||||
let masses: Vec<f64> = self.bodies.iter().map(|b| b.mass).collect();
|
||||
|
||||
fn compute_accelerations(states: &[State], masses: &[f64], ownership: &HashMap<usize, usize>) -> Vec<Vector3<f64>> {
|
||||
let mut accels = vec![Vector3::new(0.0, 0.0, 0.0); states.len()];
|
||||
fn compute_accelerations(states: &[State], masses: &[f64]) -> Vec<Vector3<f64>> {
|
||||
let n = states.len();
|
||||
let accels = (0..n).map(|_| Mutex::new(Vector3::new(0.0, 0.0, 0.0))).collect::<Vec<_>>();
|
||||
|
||||
for (&i, &j) in ownership {
|
||||
(0..n).into_par_iter().for_each(|i| {
|
||||
for j in (i + 1)..n {
|
||||
let r = states[j].position - states[i].position;
|
||||
let dist_sq = r.magnitude2();
|
||||
let dist = dist_sq.sqrt();
|
||||
@ -64,16 +67,24 @@ impl Simulator {
|
||||
|
||||
let force = G * masses[i] * masses[j] / dist_sq;
|
||||
let accel = force * r / (dist * masses[i]);
|
||||
let accel_j = -force * r / (dist * masses[j]);
|
||||
|
||||
accels[i] += accel;
|
||||
{
|
||||
let mut a_i_lock = accels[i].lock().unwrap();
|
||||
*a_i_lock += accel;
|
||||
}
|
||||
{
|
||||
let mut a_j_lock = accels[j].lock().unwrap();
|
||||
*a_j_lock += accel_j;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
accels.into_iter().map(|mutex| mutex.into_inner().unwrap()).collect()
|
||||
}
|
||||
|
||||
accels
|
||||
}
|
||||
|
||||
let ownership = self.compute_soi_owners();
|
||||
let k1_pos = original_states.iter().map(|s| s.velocity).collect::<Vec<_>>();
|
||||
let k1_vel = compute_accelerations(&original_states, &masses, &ownership);
|
||||
let k1_vel = compute_accelerations(&original_states, &masses);
|
||||
|
||||
let mut temp_states: Vec<State> = original_states.iter().enumerate().map(|(i, s)| {
|
||||
State {
|
||||
@ -83,7 +94,7 @@ impl Simulator {
|
||||
}).collect();
|
||||
|
||||
let k2_pos = temp_states.iter().map(|s| s.velocity).collect::<Vec<_>>();
|
||||
let k2_vel = compute_accelerations(&temp_states, &masses, &ownership);
|
||||
let k2_vel = compute_accelerations(&temp_states, &masses);
|
||||
|
||||
for i in 0..n {
|
||||
temp_states[i].position = original_states[i].position + k2_pos[i] * (dt / 2.0);
|
||||
@ -91,7 +102,7 @@ impl Simulator {
|
||||
}
|
||||
|
||||
let k3_pos = temp_states.iter().map(|s| s.velocity).collect::<Vec<_>>();
|
||||
let k3_vel = compute_accelerations(&temp_states, &masses, &ownership);
|
||||
let k3_vel = compute_accelerations(&temp_states, &masses);
|
||||
|
||||
for i in 0..n {
|
||||
temp_states[i].position = original_states[i].position + k3_pos[i] * dt;
|
||||
@ -99,7 +110,7 @@ impl Simulator {
|
||||
}
|
||||
|
||||
let k4_pos = temp_states.iter().map(|s| s.velocity).collect::<Vec<_>>();
|
||||
let k4_vel = compute_accelerations(&temp_states, &masses, &ownership);
|
||||
let k4_vel = compute_accelerations(&temp_states, &masses);
|
||||
|
||||
for i in 0..n {
|
||||
let body = &mut self.bodies[i];
|
||||
@ -111,33 +122,6 @@ impl Simulator {
|
||||
self.time += dt;
|
||||
}
|
||||
|
||||
fn compute_soi_owners(&self) -> HashMap<usize, usize> {
|
||||
let mut ownership = HashMap::new();
|
||||
for (i, body) in self.bodies.iter().enumerate() {
|
||||
let mut min_distance = f64::MAX;
|
||||
let mut dominant_index = None;
|
||||
|
||||
for (j, other) in self.bodies.iter().enumerate() {
|
||||
if i == j {
|
||||
continue;
|
||||
}
|
||||
|
||||
let r = (body.position - other.position).magnitude();
|
||||
let soi_radius = r * (body.mass / other.mass).powf(2.0 / 5.0);
|
||||
|
||||
if r < soi_radius && r < min_distance {
|
||||
min_distance = r;
|
||||
dominant_index = Some(j);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(j) = dominant_index {
|
||||
ownership.insert(i, j);
|
||||
}
|
||||
}
|
||||
ownership
|
||||
}
|
||||
|
||||
pub fn increase_timewarp(&mut self) {
|
||||
if let Some(new) = self.timewarp.checked_mul(2) {
|
||||
if new <= MAX_TIMEWARP {
|
||||
|
||||
@ -9,6 +9,7 @@ use crate::geometry_manager::GeometryManager;
|
||||
use crate::globals::GlobalsManager;
|
||||
use crate::instance_manager::InstanceManager;
|
||||
use crate::light::{LightManager};
|
||||
use crate::material::{GpuMaterial, MaterialManager};
|
||||
use crate::renderer::{RenderInstance, Renderer};
|
||||
|
||||
pub struct SampleCount(pub u32);
|
||||
@ -34,6 +35,7 @@ pub struct State<'a> {
|
||||
pub geometry_manager: GeometryManager,
|
||||
pub instance_manager: InstanceManager,
|
||||
pub light_manager: LightManager,
|
||||
pub material_manager: MaterialManager,
|
||||
pub renderer: Renderer,
|
||||
}
|
||||
|
||||
@ -64,11 +66,24 @@ impl<'a> State<'a> {
|
||||
let instance_manager = InstanceManager::new(&device);
|
||||
let mut light_manager = LightManager::new(&device, 100);
|
||||
|
||||
let initial_materials = vec![
|
||||
GpuMaterial {
|
||||
albedo: [1.0, 1.0, 1.0],
|
||||
emissive: [0.0, 0.0, 0.0],
|
||||
metallic: 0.0,
|
||||
roughness: 0.5,
|
||||
};
|
||||
8
|
||||
];
|
||||
|
||||
let mut material_manager = MaterialManager::new(&device, initial_materials);
|
||||
|
||||
let renderer = Renderer::new(
|
||||
&device,
|
||||
&config,
|
||||
globals.layout(),
|
||||
&mut light_manager,
|
||||
&material_manager,
|
||||
&camera,
|
||||
sample_count.get(),
|
||||
);
|
||||
@ -86,6 +101,7 @@ impl<'a> State<'a> {
|
||||
geometry_manager,
|
||||
instance_manager,
|
||||
light_manager,
|
||||
material_manager,
|
||||
renderer,
|
||||
}
|
||||
}
|
||||
@ -193,7 +209,7 @@ impl<'a> State<'a> {
|
||||
&mut self.light_manager,
|
||||
&self.geometry_manager,
|
||||
&self.instance_manager,
|
||||
|
||||
&mut self.material_manager
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user