Added directional light from sun
This commit is contained in:
parent
6c0cfbefce
commit
5a444c3e07
@ -1,5 +1,5 @@
|
|||||||
use cgmath::Rotation3;
|
use cgmath::{Rotation3, Vector3};
|
||||||
use solar_engine::{Application, Body, Key, KeyState, Simulator};
|
use solar_engine::{Application, Body, Key, KeyState, Light, LightType, Simulator};
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
@ -47,14 +47,34 @@ pub async fn run() {
|
|||||||
let sim = simulator_clone.read().unwrap();
|
let sim = simulator_clone.read().unwrap();
|
||||||
let bodies = &sim.bodies;
|
let bodies = &sim.bodies;
|
||||||
|
|
||||||
|
let sun_pos = Vector3::new(
|
||||||
|
(bodies[0].position[0] / 1.496e11) as f32,
|
||||||
|
(bodies[0].position[1] / 1.496e11) as f32,
|
||||||
|
0.0,
|
||||||
|
);
|
||||||
|
|
||||||
|
let light_offset = Vector3::new(0.0, 0.0, 0.1);
|
||||||
|
|
||||||
|
state.light_manager.clear();
|
||||||
|
state.light_manager.add_light(Light {
|
||||||
|
position: sun_pos + light_offset,
|
||||||
|
direction: Vector3::new(0.0, 0.0, 0.0),
|
||||||
|
color: Vector3::from([1.0, 1.0, 0.8]),
|
||||||
|
intensity: 5.0,
|
||||||
|
range: 0.0,
|
||||||
|
inner_cutoff: 0.0,
|
||||||
|
light_type: LightType::Directional,
|
||||||
|
outer_cutoff: 0.0,
|
||||||
|
});
|
||||||
|
|
||||||
let instances = bodies
|
let instances = bodies
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, b)| {
|
.map(|(i, b)| {
|
||||||
solar_engine::RenderInstance {
|
solar_engine::RenderInstance {
|
||||||
position: cgmath::Vector3::new(
|
position: Vector3::new(
|
||||||
(b.position[0] / 1.496e11) as f32,
|
((b.position[0] / 1.496e11) as f32) - sun_pos.x,
|
||||||
(b.position[1] / 1.496e11) as f32,
|
((b.position[1] / 1.496e11) as f32) - sun_pos.y,
|
||||||
0.0,
|
0.0,
|
||||||
),
|
),
|
||||||
rotation: cgmath::Quaternion::from_angle_z(cgmath::Deg(0.0)),
|
rotation: cgmath::Quaternion::from_angle_z(cgmath::Deg(0.0)),
|
||||||
|
|||||||
@ -5,6 +5,7 @@ mod render;
|
|||||||
mod application;
|
mod application;
|
||||||
mod input;
|
mod input;
|
||||||
mod camera;
|
mod camera;
|
||||||
|
mod light;
|
||||||
|
|
||||||
pub use body::Body;
|
pub use body::Body;
|
||||||
|
|
||||||
@ -22,3 +23,6 @@ pub use input::Key;
|
|||||||
pub use input::map_winit_key;
|
pub use input::map_winit_key;
|
||||||
pub use input::InputEvent;
|
pub use input::InputEvent;
|
||||||
pub use input::KeyState;
|
pub use input::KeyState;
|
||||||
|
|
||||||
|
pub use light::Light;
|
||||||
|
pub use light::LightType;
|
||||||
118
solar_engine/src/light.rs
Normal file
118
solar_engine/src/light.rs
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
use bytemuck::{Pod, Zeroable};
|
||||||
|
use cgmath::Vector3;
|
||||||
|
|
||||||
|
#[repr(u32)]
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub enum LightType {
|
||||||
|
Directional = 0,
|
||||||
|
Point = 1,
|
||||||
|
Spot = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy, Pod, Zeroable, Debug)]
|
||||||
|
pub struct GpuLight {
|
||||||
|
pub position: [f32; 3],
|
||||||
|
pub light_type: u32,
|
||||||
|
pub color: [f32; 3],
|
||||||
|
pub intensity: f32,
|
||||||
|
pub direction: [f32; 3],
|
||||||
|
pub range: f32,
|
||||||
|
pub inner_cutoff: f32,
|
||||||
|
pub outer_cutoff: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Light {
|
||||||
|
pub light_type: LightType,
|
||||||
|
pub position: Vector3<f32>,
|
||||||
|
pub direction: Vector3<f32>,
|
||||||
|
pub color: Vector3<f32>,
|
||||||
|
pub intensity: f32,
|
||||||
|
pub range: f32,
|
||||||
|
pub inner_cutoff: f32,
|
||||||
|
pub outer_cutoff: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Light {
|
||||||
|
pub fn to_gpu(&self) -> GpuLight {
|
||||||
|
GpuLight {
|
||||||
|
position: self.position.into(),
|
||||||
|
light_type: self.light_type as u32,
|
||||||
|
color: self.color.into(),
|
||||||
|
intensity: self.intensity,
|
||||||
|
direction: self.direction.into(),
|
||||||
|
range: self.range,
|
||||||
|
inner_cutoff: self.inner_cutoff,
|
||||||
|
outer_cutoff: self.outer_cutoff,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct LightManager {
|
||||||
|
pub lights: Vec<Light>,
|
||||||
|
pub buffer: wgpu::Buffer,
|
||||||
|
pub bind_group: wgpu::BindGroup,
|
||||||
|
pub layout: wgpu::BindGroupLayout,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LightManager {
|
||||||
|
pub fn new(device: &wgpu::Device, max_lights: usize) -> Self {
|
||||||
|
let buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
|
label: Some("Light Buffer"),
|
||||||
|
size: (max_lights * size_of::<GpuLight>()) as wgpu::BufferAddress,
|
||||||
|
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||||
|
mapped_at_creation: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
let layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
label: Some("Light Bind Group Layout"),
|
||||||
|
entries: &[wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 0,
|
||||||
|
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::Buffer {
|
||||||
|
ty: wgpu::BufferBindingType::Uniform,
|
||||||
|
has_dynamic_offset: false,
|
||||||
|
min_binding_size: None,
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
|
||||||
|
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
label: Some("Light Bind Group"),
|
||||||
|
layout: &layout,
|
||||||
|
entries: &[wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: buffer.as_entire_binding(),
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
|
||||||
|
Self {
|
||||||
|
lights: Vec::new(),
|
||||||
|
buffer,
|
||||||
|
bind_group,
|
||||||
|
layout,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_light(&mut self, light: Light) {
|
||||||
|
self.lights.push(light);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_gpu(&self, queue: &wgpu::Queue) {
|
||||||
|
let data: Vec<GpuLight> = self.lights.iter().map(|l| l.to_gpu()).collect();
|
||||||
|
queue.write_buffer(&self.buffer, 0, bytemuck::cast_slice(&data));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind_group(&self) -> &wgpu::BindGroup {
|
||||||
|
&self.bind_group
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn layout(&self) -> &wgpu::BindGroupLayout {
|
||||||
|
&self.layout
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear(&mut self) {
|
||||||
|
self.lights.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,7 +6,6 @@ pub struct Globals {
|
|||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum Shape {
|
pub enum Shape {
|
||||||
Polygon,
|
|
||||||
Circle,
|
Circle,
|
||||||
Sphere,
|
Sphere,
|
||||||
}
|
}
|
||||||
@ -74,11 +73,12 @@ impl SampleCount {
|
|||||||
pub struct Vertex {
|
pub struct Vertex {
|
||||||
pub(crate) position: [f32; 3],
|
pub(crate) position: [f32; 3],
|
||||||
pub(crate) color: [f32; 3],
|
pub(crate) color: [f32; 3],
|
||||||
|
pub(crate) normal: [f32; 3],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vertex {
|
impl Vertex {
|
||||||
const ATTRIBS: [wgpu::VertexAttribute; 2] =
|
const ATTRIBS: [wgpu::VertexAttribute; 3] =
|
||||||
wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x3];
|
wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x3, 2 => Float32x3];
|
||||||
|
|
||||||
pub(crate) fn desc() -> wgpu::VertexBufferLayout<'static> {
|
pub(crate) fn desc() -> wgpu::VertexBufferLayout<'static> {
|
||||||
wgpu::VertexBufferLayout {
|
wgpu::VertexBufferLayout {
|
||||||
@ -90,14 +90,22 @@ impl Vertex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_circle_vertices(segment_count: usize, radius: f32, color: [f32; 3]) -> (Vec<Vertex>, Vec<u16>) {
|
pub fn create_circle_vertices(segment_count: usize, radius: f32, color: [f32; 3]) -> (Vec<Vertex>, Vec<u16>) {
|
||||||
let mut vertices = vec![Vertex { position: [0.0, 0.0, 0.0], color }];
|
let mut vertices = vec![Vertex {
|
||||||
|
position: [0.0, 0.0, 0.0],
|
||||||
|
color,
|
||||||
|
normal: [0.0, 0.0, 1.0],
|
||||||
|
}];
|
||||||
let mut indices = vec![];
|
let mut indices = vec![];
|
||||||
|
|
||||||
for i in 0..=segment_count {
|
for i in 0..=segment_count {
|
||||||
let theta = (i as f32) / (segment_count as f32) * std::f32::consts::TAU;
|
let theta = (i as f32) / (segment_count as f32) * std::f32::consts::TAU;
|
||||||
let x = radius * theta.cos();
|
let x = radius * theta.cos();
|
||||||
let y = radius * theta.sin();
|
let y = radius * theta.sin();
|
||||||
vertices.push(Vertex { position: [x, y, 0.0], color });
|
vertices.push(Vertex {
|
||||||
|
position: [x, y, 0.0],
|
||||||
|
color,
|
||||||
|
normal: [0.0, 0.0, 1.0],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 1..=segment_count {
|
for i in 1..=segment_count {
|
||||||
@ -123,9 +131,12 @@ pub fn create_sphere_vertices(stacks: usize, slices: usize, radius: f32, color:
|
|||||||
let x = r * theta.cos();
|
let x = r * theta.cos();
|
||||||
let z = r * theta.sin();
|
let z = r * theta.sin();
|
||||||
|
|
||||||
|
let normal = [x, y, z];
|
||||||
|
|
||||||
vertices.push(Vertex {
|
vertices.push(Vertex {
|
||||||
position: [x * radius, y * radius, z * radius],
|
position: [x * radius, y * radius, z * radius],
|
||||||
color,
|
color,
|
||||||
|
normal,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
struct VertexInput {
|
struct VertexInput {
|
||||||
@location(0) position: vec3<f32>,
|
@location(0) position: vec3<f32>,
|
||||||
@location(1) color: vec3<f32>,
|
@location(1) color: vec3<f32>,
|
||||||
|
@location(2) normal: vec3<f32>,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InstanceInput {
|
struct InstanceInput {
|
||||||
@ -13,7 +14,9 @@ struct InstanceInput {
|
|||||||
|
|
||||||
struct VSOutput {
|
struct VSOutput {
|
||||||
@builtin(position) position: vec4<f32>,
|
@builtin(position) position: vec4<f32>,
|
||||||
@location(0) color: vec3<f32>,
|
@location(0) frag_color: vec3<f32>,
|
||||||
|
@location(1) world_pos: vec3<f32>,
|
||||||
|
@location(2) normal: vec3<f32>,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Globals {
|
struct Globals {
|
||||||
@ -23,21 +26,52 @@ struct Globals {
|
|||||||
@group(0) @binding(0)
|
@group(0) @binding(0)
|
||||||
var<uniform> globals: Globals;
|
var<uniform> globals: Globals;
|
||||||
|
|
||||||
|
struct GpuLight {
|
||||||
|
position: vec3<f32>,
|
||||||
|
color: vec3<f32>,
|
||||||
|
intensity: f32,
|
||||||
|
};
|
||||||
|
|
||||||
|
@group(1) @binding(0)
|
||||||
|
var<uniform> lights: array<GpuLight, 10>;
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
fn vs_main(vertex: VertexInput, instance: InstanceInput) -> VSOutput {
|
fn vs_main(vertex: VertexInput, instance: InstanceInput) -> VSOutput {
|
||||||
var out: VSOutput;
|
var out: VSOutput;
|
||||||
|
|
||||||
let model = mat4x4<f32>(
|
let model = mat4x4<f32>(
|
||||||
instance.model_row0,
|
instance.model_row0,
|
||||||
instance.model_row1,
|
instance.model_row1,
|
||||||
instance.model_row2,
|
instance.model_row2,
|
||||||
instance.model_row3
|
instance.model_row3
|
||||||
);
|
);
|
||||||
out.position = globals.view_proj * model * vec4<f32>(vertex.position, 1.0);
|
|
||||||
out.color = instance.color;
|
let world_position = (model * vec4<f32>(vertex.position, 1.0)).xyz;
|
||||||
|
let normal_matrix = mat3x3<f32>(
|
||||||
|
instance.model_row0.xyz,
|
||||||
|
instance.model_row1.xyz,
|
||||||
|
instance.model_row2.xyz
|
||||||
|
);
|
||||||
|
|
||||||
|
out.position = globals.view_proj * vec4<f32>(world_position, 1.0);
|
||||||
|
out.frag_color = instance.color * vertex.color;
|
||||||
|
out.world_pos = world_position;
|
||||||
|
out.normal = normalize(normal_matrix * vertex.normal);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
fn fs_main(input: VSOutput) -> @location(0) vec4<f32> {
|
fn fs_main(input: VSOutput) -> @location(0) vec4<f32> {
|
||||||
return vec4<f32>(input.color, 1.0);
|
var lighting: vec3<f32> = vec3<f32>(0.0);
|
||||||
|
|
||||||
|
for (var i = 0u; i < 10u; i = i + 1u) {
|
||||||
|
let light = lights[i];
|
||||||
|
let light_dir = normalize(light.position - input.world_pos);
|
||||||
|
let diff = max(dot(input.normal, light_dir), 0.0);
|
||||||
|
lighting += light.color * light.intensity * diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
let final_color = input.frag_color * lighting;
|
||||||
|
return vec4<f32>(final_color, 1.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ use wgpu::{Adapter, Device, Instance, PresentMode, Queue, Surface, SurfaceCapabi
|
|||||||
use winit::dpi::PhysicalSize;
|
use winit::dpi::PhysicalSize;
|
||||||
use winit::window::{Window};
|
use winit::window::{Window};
|
||||||
use crate::camera::Camera;
|
use crate::camera::Camera;
|
||||||
|
use crate::light::{GpuLight, LightManager};
|
||||||
use crate::render::{create_circle_vertices, create_sphere_vertices, Geometry, Globals, InstanceRaw, RenderInstance, SampleCount, Shape, Vertex};
|
use crate::render::{create_circle_vertices, create_sphere_vertices, Geometry, Globals, InstanceRaw, RenderInstance, SampleCount, Shape, Vertex};
|
||||||
|
|
||||||
pub struct State<'a> {
|
pub struct State<'a> {
|
||||||
@ -32,6 +33,8 @@ pub struct State<'a> {
|
|||||||
|
|
||||||
camera: Camera,
|
camera: Camera,
|
||||||
depth_texture: wgpu::TextureView,
|
depth_texture: wgpu::TextureView,
|
||||||
|
|
||||||
|
pub light_manager: LightManager,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> State<'a> {
|
impl<'a> State<'a> {
|
||||||
@ -83,7 +86,9 @@ impl<'a> State<'a> {
|
|||||||
label: Some("Global Bind Group"),
|
label: Some("Global Bind Group"),
|
||||||
});
|
});
|
||||||
|
|
||||||
let render_pipeline = Self::create_render_pipeline(&device, &config, sample_count.0, &global_bind_group_layout);
|
let light_manager = LightManager::new(&device, 10);
|
||||||
|
|
||||||
|
let render_pipeline = Self::create_render_pipeline(&device, &config, sample_count.0, &global_bind_group_layout, &light_manager);
|
||||||
let geometries = Self::create_geometries(&device);
|
let geometries = Self::create_geometries(&device);
|
||||||
|
|
||||||
let instances = vec![];
|
let instances = vec![];
|
||||||
@ -112,9 +117,15 @@ impl<'a> State<'a> {
|
|||||||
instance_buffer,
|
instance_buffer,
|
||||||
camera,
|
camera,
|
||||||
depth_texture,
|
depth_texture,
|
||||||
|
light_manager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_lights(&mut self) {
|
||||||
|
let light_data: Vec<GpuLight> = self.light_manager.lights.iter().map(|l| l.to_gpu()).collect();
|
||||||
|
self.queue.write_buffer(&self.light_manager.buffer, 0, bytemuck::cast_slice(&light_data));
|
||||||
|
}
|
||||||
|
|
||||||
fn create_depth_texture(device: &Device, width: u32, height: u32, sample_count: u32) -> wgpu::TextureView {
|
fn create_depth_texture(device: &Device, width: u32, height: u32, sample_count: u32) -> wgpu::TextureView {
|
||||||
let texture = device.create_texture(&wgpu::TextureDescriptor {
|
let texture = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
label: Some("Depth Texture"),
|
label: Some("Depth Texture"),
|
||||||
@ -136,18 +147,6 @@ impl<'a> State<'a> {
|
|||||||
fn create_geometries(device: &Device) -> HashMap<Shape, Geometry> {
|
fn create_geometries(device: &Device) -> HashMap<Shape, Geometry> {
|
||||||
let mut geometries = HashMap::new();
|
let mut geometries = HashMap::new();
|
||||||
|
|
||||||
let polygon_vertices = vec![
|
|
||||||
Vertex { position: [-0.0868241, 0.49240386, 0.0], color: [0.5, 0.0, 0.5] },
|
|
||||||
Vertex { position: [-0.49513406, 0.06958647, 0.0], color: [0.5, 0.0, 0.5] },
|
|
||||||
Vertex { position: [-0.21918549, -0.44939706, 0.0], color: [0.5, 0.0, 0.5] },
|
|
||||||
Vertex { position: [0.35966998, -0.3473291, 0.0], color: [0.5, 0.0, 0.5] },
|
|
||||||
Vertex { position: [0.44147372, 0.2347359, 0.0], color: [0.5, 0.0, 0.5] },
|
|
||||||
];
|
|
||||||
let polygon_indices = vec![0, 1, 4, 1, 2, 4, 2, 3, 4];
|
|
||||||
|
|
||||||
let polygon_geometry = Self::create_geometry(device, &polygon_vertices, &polygon_indices);
|
|
||||||
geometries.insert(Shape::Polygon, polygon_geometry);
|
|
||||||
|
|
||||||
let (circle_vertices, circle_indices) = create_circle_vertices(512, 0.5, [0.5, 0.5, 0.5]);
|
let (circle_vertices, circle_indices) = create_circle_vertices(512, 0.5, [0.5, 0.5, 0.5]);
|
||||||
let circle_geometry = Self::create_geometry(device, &circle_vertices, &circle_indices);
|
let circle_geometry = Self::create_geometry(device, &circle_vertices, &circle_indices);
|
||||||
geometries.insert(Shape::Circle, circle_geometry);
|
geometries.insert(Shape::Circle, circle_geometry);
|
||||||
@ -207,7 +206,7 @@ impl<'a> State<'a> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_render_pipeline(device: &Device, config: &SurfaceConfiguration, sample_count: u32, global_bind_group_layout: &wgpu::BindGroupLayout) -> wgpu::RenderPipeline {
|
fn create_render_pipeline(device: &Device, config: &SurfaceConfiguration, sample_count: u32, global_bind_group_layout: &wgpu::BindGroupLayout, light_manager: &LightManager) -> wgpu::RenderPipeline {
|
||||||
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
label: Some("Shader"),
|
label: Some("Shader"),
|
||||||
source: wgpu::ShaderSource::Wgsl(include_str!("shader.wgsl").into()),
|
source: wgpu::ShaderSource::Wgsl(include_str!("shader.wgsl").into()),
|
||||||
@ -216,7 +215,7 @@ impl<'a> State<'a> {
|
|||||||
let render_pipeline_layout =
|
let render_pipeline_layout =
|
||||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("Render Pipeline Layout"),
|
label: Some("Render Pipeline Layout"),
|
||||||
bind_group_layouts: &[&global_bind_group_layout],
|
bind_group_layouts: &[&global_bind_group_layout, &light_manager.layout],
|
||||||
push_constant_ranges: &[],
|
push_constant_ranges: &[],
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -394,6 +393,10 @@ impl<'a> State<'a> {
|
|||||||
render_pass.set_pipeline(&self.render_pipeline);
|
render_pass.set_pipeline(&self.render_pipeline);
|
||||||
render_pass.set_bind_group(0, &self.global_bind_group, &[]);
|
render_pass.set_bind_group(0, &self.global_bind_group, &[]);
|
||||||
|
|
||||||
|
// Update the light manager buffer
|
||||||
|
self.light_manager.update_gpu(&self.queue);
|
||||||
|
render_pass.set_bind_group(1, &self.light_manager.bind_group, &[]);
|
||||||
|
|
||||||
for shape in self.geometries.keys().copied() {
|
for shape in self.geometries.keys().copied() {
|
||||||
let geometry = &self.geometries[&shape];
|
let geometry = &self.geometries[&shape];
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user