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,
|
radius: 6.371e6,
|
||||||
});
|
});
|
||||||
|
|
||||||
let earth_position = sim.bodies[1].position;
|
/*let earth_position = sim.bodies[1].position;
|
||||||
let earth_velocity = sim.bodies[1].velocity;
|
let earth_velocity = sim.bodies[1].velocity;
|
||||||
|
|
||||||
sim.add_body(Body {
|
sim.add_body(Body {
|
||||||
@ -31,7 +31,7 @@ pub async fn run() {
|
|||||||
velocity: earth_velocity + Vector3::new(0.0, 1022.0, 0.0),
|
velocity: earth_velocity + Vector3::new(0.0, 1022.0, 0.0),
|
||||||
mass: 7.342e22,
|
mass: 7.342e22,
|
||||||
radius: 1.737e6,
|
radius: 1.737e6,
|
||||||
});
|
});*/
|
||||||
}
|
}
|
||||||
|
|
||||||
let sim_clone = simulator.clone();
|
let sim_clone = simulator.clone();
|
||||||
|
|||||||
@ -9,6 +9,7 @@ mod renderer;
|
|||||||
mod instance_manager;
|
mod instance_manager;
|
||||||
mod globals;
|
mod globals;
|
||||||
mod geometry_manager;
|
mod geometry_manager;
|
||||||
|
mod material;
|
||||||
|
|
||||||
pub use body::Body;
|
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::instance_manager::InstanceManager;
|
||||||
use crate::light::LightManager;
|
use crate::light::LightManager;
|
||||||
use wgpu::{Device, Queue, SurfaceTexture, TextureView};
|
use wgpu::{Device, Queue, SurfaceTexture, TextureView};
|
||||||
|
use crate::material::MaterialManager;
|
||||||
|
|
||||||
pub struct RenderInstance {
|
pub struct RenderInstance {
|
||||||
pub position: cgmath::Vector3<f32>,
|
pub position: cgmath::Vector3<f32>,
|
||||||
@ -77,7 +78,7 @@ impl Vertex {
|
|||||||
pub struct Renderer {
|
pub struct Renderer {
|
||||||
pipeline: wgpu::RenderPipeline,
|
pipeline: wgpu::RenderPipeline,
|
||||||
depth_texture: TextureView,
|
depth_texture: TextureView,
|
||||||
sample_count: u32,
|
sample_count: u32
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Renderer {
|
impl Renderer {
|
||||||
@ -86,6 +87,7 @@ impl Renderer {
|
|||||||
config: &wgpu::SurfaceConfiguration,
|
config: &wgpu::SurfaceConfiguration,
|
||||||
global_layout: &wgpu::BindGroupLayout,
|
global_layout: &wgpu::BindGroupLayout,
|
||||||
light_manager: &mut LightManager,
|
light_manager: &mut LightManager,
|
||||||
|
material_manager: &MaterialManager,
|
||||||
camera: &Camera,
|
camera: &Camera,
|
||||||
sample_count: u32,
|
sample_count: u32,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@ -109,6 +111,7 @@ impl Renderer {
|
|||||||
global_layout,
|
global_layout,
|
||||||
&light_manager.layout,
|
&light_manager.layout,
|
||||||
&cluster_buffers.layout,
|
&cluster_buffers.layout,
|
||||||
|
&material_manager.layout,
|
||||||
],
|
],
|
||||||
push_constant_ranges: &[],
|
push_constant_ranges: &[],
|
||||||
});
|
});
|
||||||
@ -206,6 +209,7 @@ impl Renderer {
|
|||||||
light_manager: &mut LightManager,
|
light_manager: &mut LightManager,
|
||||||
geometry: &GeometryManager,
|
geometry: &GeometryManager,
|
||||||
instances: &InstanceManager,
|
instances: &InstanceManager,
|
||||||
|
material_manager: &mut MaterialManager,
|
||||||
) -> Result<(), wgpu::SurfaceError> {
|
) -> Result<(), wgpu::SurfaceError> {
|
||||||
// Update uniform buffer
|
// Update uniform buffer
|
||||||
globals.update(queue, camera);
|
globals.update(queue, camera);
|
||||||
@ -220,6 +224,9 @@ impl Renderer {
|
|||||||
light_manager.update_cluster_buffers(device, queue, &assignment);
|
light_manager.update_cluster_buffers(device, queue, &assignment);
|
||||||
light_manager.update_gpu(queue);
|
light_manager.update_gpu(queue);
|
||||||
|
|
||||||
|
// Update material buffer
|
||||||
|
material_manager.update(queue);
|
||||||
|
|
||||||
let multisampled_texture = device.create_texture(&wgpu::TextureDescriptor {
|
let multisampled_texture = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
label: Some("Multisample Target"),
|
label: Some("Multisample Target"),
|
||||||
size: wgpu::Extent3d {
|
size: wgpu::Extent3d {
|
||||||
@ -274,6 +281,7 @@ impl Renderer {
|
|||||||
if let Some(clusters) = &light_manager.cluster_buffers {
|
if let Some(clusters) = &light_manager.cluster_buffers {
|
||||||
pass.set_bind_group(2, &clusters.bind_group, &[]);
|
pass.set_bind_group(2, &clusters.bind_group, &[]);
|
||||||
}
|
}
|
||||||
|
pass.set_bind_group(3, &material_manager.bind_group, &[]);
|
||||||
|
|
||||||
for shape in geometry.shapes() {
|
for shape in geometry.shapes() {
|
||||||
if let Some(mesh) = geometry.get(&shape) {
|
if let Some(mesh) = geometry.get(&shape) {
|
||||||
|
|||||||
@ -62,6 +62,17 @@ var<storage, read> cluster_light_indices: array<u32>;
|
|||||||
@group(2) @binding(1)
|
@group(2) @binding(1)
|
||||||
var<storage, read> cluster_offsets: array<vec2<u32>>;
|
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
|
@vertex
|
||||||
fn vs_main(vertex: VertexInput, instance: InstanceInput) -> VSOutput {
|
fn vs_main(vertex: VertexInput, instance: InstanceInput) -> VSOutput {
|
||||||
var out: VSOutput;
|
var out: VSOutput;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::sync::Mutex;
|
||||||
use cgmath::{InnerSpace, Vector3};
|
use cgmath::{InnerSpace, Vector3};
|
||||||
use crate::body::Body;
|
use crate::body::Body;
|
||||||
|
use rayon::prelude::*;
|
||||||
|
|
||||||
const G: f64 = 6.67430e-11;
|
const G: f64 = 6.67430e-11;
|
||||||
|
|
||||||
@ -50,10 +51,12 @@ impl Simulator {
|
|||||||
|
|
||||||
let masses: Vec<f64> = self.bodies.iter().map(|b| b.mass).collect();
|
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>> {
|
fn compute_accelerations(states: &[State], masses: &[f64]) -> Vec<Vector3<f64>> {
|
||||||
let mut accels = vec![Vector3::new(0.0, 0.0, 0.0); states.len()];
|
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 r = states[j].position - states[i].position;
|
||||||
let dist_sq = r.magnitude2();
|
let dist_sq = r.magnitude2();
|
||||||
let dist = dist_sq.sqrt();
|
let dist = dist_sq.sqrt();
|
||||||
@ -64,16 +67,24 @@ impl Simulator {
|
|||||||
|
|
||||||
let force = G * masses[i] * masses[j] / dist_sq;
|
let force = G * masses[i] * masses[j] / dist_sq;
|
||||||
let accel = force * r / (dist * masses[i]);
|
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_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)| {
|
let mut temp_states: Vec<State> = original_states.iter().enumerate().map(|(i, s)| {
|
||||||
State {
|
State {
|
||||||
@ -83,7 +94,7 @@ impl Simulator {
|
|||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
let k2_pos = temp_states.iter().map(|s| s.velocity).collect::<Vec<_>>();
|
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 {
|
for i in 0..n {
|
||||||
temp_states[i].position = original_states[i].position + k2_pos[i] * (dt / 2.0);
|
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_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 {
|
for i in 0..n {
|
||||||
temp_states[i].position = original_states[i].position + k3_pos[i] * dt;
|
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_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 {
|
for i in 0..n {
|
||||||
let body = &mut self.bodies[i];
|
let body = &mut self.bodies[i];
|
||||||
@ -111,33 +122,6 @@ impl Simulator {
|
|||||||
self.time += dt;
|
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) {
|
pub fn increase_timewarp(&mut self) {
|
||||||
if let Some(new) = self.timewarp.checked_mul(2) {
|
if let Some(new) = self.timewarp.checked_mul(2) {
|
||||||
if new <= MAX_TIMEWARP {
|
if new <= MAX_TIMEWARP {
|
||||||
|
|||||||
@ -9,6 +9,7 @@ use crate::geometry_manager::GeometryManager;
|
|||||||
use crate::globals::GlobalsManager;
|
use crate::globals::GlobalsManager;
|
||||||
use crate::instance_manager::InstanceManager;
|
use crate::instance_manager::InstanceManager;
|
||||||
use crate::light::{LightManager};
|
use crate::light::{LightManager};
|
||||||
|
use crate::material::{GpuMaterial, MaterialManager};
|
||||||
use crate::renderer::{RenderInstance, Renderer};
|
use crate::renderer::{RenderInstance, Renderer};
|
||||||
|
|
||||||
pub struct SampleCount(pub u32);
|
pub struct SampleCount(pub u32);
|
||||||
@ -34,6 +35,7 @@ pub struct State<'a> {
|
|||||||
pub geometry_manager: GeometryManager,
|
pub geometry_manager: GeometryManager,
|
||||||
pub instance_manager: InstanceManager,
|
pub instance_manager: InstanceManager,
|
||||||
pub light_manager: LightManager,
|
pub light_manager: LightManager,
|
||||||
|
pub material_manager: MaterialManager,
|
||||||
pub renderer: Renderer,
|
pub renderer: Renderer,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,11 +66,24 @@ impl<'a> State<'a> {
|
|||||||
let instance_manager = InstanceManager::new(&device);
|
let instance_manager = InstanceManager::new(&device);
|
||||||
let mut light_manager = LightManager::new(&device, 100);
|
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(
|
let renderer = Renderer::new(
|
||||||
&device,
|
&device,
|
||||||
&config,
|
&config,
|
||||||
globals.layout(),
|
globals.layout(),
|
||||||
&mut light_manager,
|
&mut light_manager,
|
||||||
|
&material_manager,
|
||||||
&camera,
|
&camera,
|
||||||
sample_count.get(),
|
sample_count.get(),
|
||||||
);
|
);
|
||||||
@ -86,6 +101,7 @@ impl<'a> State<'a> {
|
|||||||
geometry_manager,
|
geometry_manager,
|
||||||
instance_manager,
|
instance_manager,
|
||||||
light_manager,
|
light_manager,
|
||||||
|
material_manager,
|
||||||
renderer,
|
renderer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,7 +209,7 @@ impl<'a> State<'a> {
|
|||||||
&mut self.light_manager,
|
&mut self.light_manager,
|
||||||
&self.geometry_manager,
|
&self.geometry_manager,
|
||||||
&self.instance_manager,
|
&self.instance_manager,
|
||||||
|
&mut self.material_manager
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user