uncommented and fixed the lights, but everything still is mega-dark

master
mitchellhansen 4 years ago
parent 80ac21e9d3
commit 8d7a62da7f

@ -1,13 +1,7 @@
use bytemuck::__core::ops::Range; use bytemuck::__core::ops::Range;
use bytemuck::{Zeroable, Pod}; use bytemuck::{Zeroable, Pod};
use crate::OPENGL_TO_WGPU_MATRIX; use crate::{OPENGL_TO_WGPU_MATRIX, DirectionalLight, Position};
pub struct Light {
pub(crate) pos: cgmath::Point3<f32>,
pub(crate) color: wgpu::Color,
pub(crate) fov: f32,
pub(crate) depth: Range<f32>,
}
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
@ -21,11 +15,12 @@ unsafe impl Pod for LightRaw {}
unsafe impl Zeroable for LightRaw {} unsafe impl Zeroable for LightRaw {}
impl Light { impl DirectionalLight {
fn to_raw(&self) -> LightRaw { pub fn to_raw(&self, pos: Position) -> LightRaw {
use cgmath::{Deg, EuclideanSpace, Matrix4, PerspectiveFov, Point3, Vector3}; use cgmath::{Deg, EuclideanSpace, Matrix4, PerspectiveFov, Point3, Vector3};
let mx_view = Matrix4::look_at(self.pos, Point3::origin(), Vector3::unit_z()); let pos = cgmath::Point3::new(pos.x, pos.y, pos.z);
let mx_view = Matrix4::look_at(pos, Point3::origin(), Vector3::unit_z());
let projection = PerspectiveFov { let projection = PerspectiveFov {
fovy: Deg(self.fov).into(), fovy: Deg(self.fov).into(),
aspect: 1.0, aspect: 1.0,
@ -37,7 +32,7 @@ impl Light {
mx_correction * cgmath::Matrix4::from(projection.to_perspective()) * mx_view; mx_correction * cgmath::Matrix4::from(projection.to_perspective()) * mx_view;
LightRaw { LightRaw {
proj: *mx_view_proj.as_ref(), proj: *mx_view_proj.as_ref(),
pos: [self.pos.x, self.pos.y, self.pos.z, 1.0], pos: [pos.x, pos.y, pos.z, 1.0],
color: [ color: [
self.color.r as f32, self.color.r as f32,
self.color.g as f32, self.color.g as f32,

@ -10,7 +10,7 @@ use bytemuck::__core::ops::Range;
use cgmath::{Matrix4, Point3}; use cgmath::{Matrix4, Point3};
use futures::task::LocalSpawn; use futures::task::LocalSpawn;
use legion::*; use legion::*;
use wgpu::{BindGroup, Buffer}; use wgpu::{BindGroup, Buffer, TextureView};
use wgpu_subscriber; use wgpu_subscriber;
use winit::platform::unix::x11::ffi::Time; use winit::platform::unix::x11::ffi::Time;
use winit::{ use winit::{
@ -119,11 +119,12 @@ pub struct RangeCopy<Idx> {
pub end: Idx, pub end: Idx,
} }
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Debug)]
struct DirectionalLight { pub struct DirectionalLight {
color: wgpu::Color, color: wgpu::Color,
fov: f32, fov: f32,
depth: RangeCopy<f32>, depth: RangeCopy<f32>,
target_view: Arc<TextureView>,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -219,23 +220,11 @@ fn main() {
// This could be used for relationships between entities...??? // This could be used for relationships between entities...???
let light_entity: Entity = world.push(( let light_entity: Entity = world.push((
cgmath::Point3 { cgmath::Point3 {
x: -5.0, x: -5.0 as f32,
y: 7.0, y: 7.0 as f32,
z: 10.0, z: 10.0 as f32,
},
DirectionalLight {
color: wgpu::Color {
r: 1.0,
g: 0.5,
b: 0.5,
a: 1.0,
},
fov: 45.0,
depth: RangeCopy {
start: 1.0,
end: 20.0,
},
}, },
renderer.create_light(),
)); ));
let mesh_entity: Entity = world.push(( let mesh_entity: Entity = world.push((

@ -8,14 +8,15 @@ use futures::executor::LocalPool;
use legion::world::SubWorld; use legion::world::SubWorld;
use legion::*; use legion::*;
use wgpu::util::DeviceExt; use wgpu::util::DeviceExt;
use wgpu::{Buffer, Device, Instance, Queue, Surface, SwapChain, SwapChainDescriptor, SwapChainFrame, BindGroup, BindGroupLayout}; use wgpu::{BindGroup, BindGroupLayout, Buffer, Device, Instance, Queue, Surface, SwapChain, SwapChainDescriptor, SwapChainFrame, TextureView};
use winit::dpi::PhysicalSize; use winit::dpi::PhysicalSize;
use winit::platform::unix::x11::ffi::Time; use winit::platform::unix::x11::ffi::Time;
use winit::window::Window; use winit::window::Window;
use crate::geometry::{create_plane, import_mesh, Vertex}; use crate::geometry::{create_plane, import_mesh, Vertex};
use crate::light::LightRaw; use crate::light::LightRaw;
use crate::{Color, Mesh, Position, Velocity, OPENGL_TO_WGPU_MATRIX}; use crate::{Color, DirectionalLight, Mesh, Position, RangeCopy, Velocity, OPENGL_TO_WGPU_MATRIX};
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
@ -67,8 +68,9 @@ pub struct Renderer {
forward_depth: wgpu::TextureView, forward_depth: wgpu::TextureView,
entity_bind_group_layout: BindGroupLayout, entity_bind_group_layout: BindGroupLayout,
light_uniform_buf: wgpu::Buffer, shadow_target_views: Vec<Arc<TextureView>>,
light_uniform_buf: wgpu::Buffer,
} }
impl Renderer { impl Renderer {
@ -93,26 +95,12 @@ impl Renderer {
} }
} }
/*
SOOOOOOOOOOOOooo... Legion systems have to be standalone functions, which is fine
we can do a special kind of song and dance
Main loop {
renderer
runtime
render_system(param1,2,3, renderer);
animation_system(param1,2,3, runtime);
renderer.finalize()
}
*/
#[system] #[system]
#[write_component(Position)] #[write_component(Position)]
#[write_component(Point3<f32>)]
#[write_component(Mesh)] #[write_component(Mesh)]
#[write_component(Color)] #[write_component(Color)]
#[write_component(DirectionalLight)]
pub fn render_test(world: &mut SubWorld, #[resource] renderer: &mut Renderer) { pub fn render_test(world: &mut SubWorld, #[resource] renderer: &mut Renderer) {
let frame = renderer.get_current_frame(); let frame = renderer.get_current_frame();
@ -120,11 +108,8 @@ pub fn render_test(world: &mut SubWorld, #[resource] renderer: &mut Renderer) {
// Update the entity uniforms // Update the entity uniforms
for (pos, mesh, color) in query.iter_mut(world) { for (pos, mesh, color) in query.iter_mut(world) {
// Revolve the entity by the rotation speed, only if it is non-zero let rotation = cgmath::Matrix4::from_angle_x(cgmath::Deg(1.0));
// if vel.rs != 0.0 { pos.mx = pos.mx * rotation;
// let rotation = cgmath::Matrix4::from_angle_x(cgmath::Deg(vel.rs));
// pos.mx = pos.mx * rotation;
// }
let data = EntityUniforms { let data = EntityUniforms {
model: pos.mx.into(), model: pos.mx.into(),
@ -140,66 +125,78 @@ pub fn render_test(world: &mut SubWorld, #[resource] renderer: &mut Renderer) {
.write_buffer(&mesh.uniform_buffer, 0, bytemuck::bytes_of(&data)); .write_buffer(&mesh.uniform_buffer, 0, bytemuck::bytes_of(&data));
} }
// if self.lights_are_dirty { if renderer.lights_are_dirty {
// self.lights_are_dirty = false; renderer.lights_are_dirty = false;
// for (i, light) in self.lights.iter().enumerate() { let mut query = <(&mut DirectionalLight, &mut Position)>::query();
// queue.write_buffer( for (i, (light, pos)) in query.iter_mut(world).enumerate() {
// &self.light_uniform_buf, renderer.queue.write_buffer(
// (i * mem::size_of::<LightRaw>()) as wgpu::BufferAddress, &renderer.light_uniform_buf,
// bytemuck::bytes_of(&light.to_raw()), (i * mem::size_of::<LightRaw>()) as wgpu::BufferAddress,
// ); bytemuck::bytes_of(&light.to_raw(*pos)),
// } );
// } }
}
let mut encoder = renderer let mut encoder = renderer
.device .device
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); .create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
encoder.push_debug_group("shadow passes"); encoder.push_debug_group("shadow passes");
/*for (i, light) in self.lights.iter().enumerate() {
let mut query = <(&mut DirectionalLight, &mut Point3<f32>)>::query();
let mut light_stack = Vec::new();
for (i, (light, pos)) in query.iter_mut(world).enumerate() {
light_stack.push(light.clone());
encoder.push_debug_group(&format!( encoder.push_debug_group(&format!(
"shadow pass {} (light at position {:?})", "shadow pass {} (light at position {:?})",
i, light.pos i, pos
)); ));
// The light uniform buffer already has the projection, // The light uniform buffer already has the projection,
// let's just copy it over to the shadow uniform buffer. // let's just copy it over to the shadow uniform buffer.
encoder.copy_buffer_to_buffer( encoder.copy_buffer_to_buffer(
&self.light_uniform_buf, &renderer.light_uniform_buf,
(i * mem::size_of::<LightRaw>()) as wgpu::BufferAddress, (i * mem::size_of::<LightRaw>()) as wgpu::BufferAddress,
&self.shadow_pass.uniform_buf, &renderer.shadow_pass.uniform_buf,
0, 0,
64, 64,
); );
encoder.pop_debug_group();
}
for light in light_stack {
encoder.insert_debug_marker("render entities"); encoder.insert_debug_marker("render entities");
{ {
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[], color_attachments: &[],
depth_stencil_attachment: Some( depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor {
wgpu::RenderPassDepthStencilAttachmentDescriptor {
attachment: &light.target_view, attachment: &light.target_view,
depth_ops: Some(wgpu::Operations { depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(1.0), load: wgpu::LoadOp::Clear(1.0),
store: true, store: true,
}), }),
stencil_ops: None, stencil_ops: None,
}, }),
),
}); });
pass.set_pipeline(&self.shadow_pass.pipeline); pass.set_pipeline(&renderer.shadow_pass.pipeline);
pass.set_bind_group(0, &self.shadow_pass.bind_group, &[]); pass.set_bind_group(0, &renderer.shadow_pass.bind_group, &[]);
let mut query = <(&mut Position, &mut Mesh, &mut Color)>::query();
for entity in &self.entities { for (pos, mesh, color) in query.iter_mut(world) {
pass.set_bind_group(1, &entity.bind_group, &[]); pass.set_bind_group(1, &mesh.bind_group, &[]);
pass.set_index_buffer(entity.index_buf.slice(..)); pass.set_index_buffer(mesh.index_buffer.slice(..));
pass.set_vertex_buffer(0, entity.vertex_buf.slice(..)); pass.set_vertex_buffer(0, mesh.vertex_buffer.slice(..));
pass.draw_indexed(0..entity.index_count as u32, 0, 0..1); pass.draw_indexed(0..mesh.index_count as u32, 0, 0..1);
}
} }
} }
encoder.pop_debug_group();
}*/
encoder.pop_debug_group(); encoder.pop_debug_group();
// forward pass // forward pass
@ -258,7 +255,6 @@ pub fn render_test(world: &mut SubWorld, #[resource] renderer: &mut Renderer) {
} }
impl Renderer { impl Renderer {
pub fn get_current_frame(&mut self) -> SwapChainFrame { pub fn get_current_frame(&mut self) -> SwapChainFrame {
// Update the renderers swapchain state // Update the renderers swapchain state
match self.swapchain.get_current_frame() { match self.swapchain.get_current_frame() {
@ -299,25 +295,28 @@ impl Renderer {
}), }),
); );
// // Creates the vertex and index buffers for the plane
// let (plane_vertex_data, plane_index_data) = create_plane(7.0);
// self.plane_vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
// label: Some("Plane Vertex Buffer"),
// contents: bytemuck::cast_slice(&plane_vertex_data),
// usage: wgpu::BufferUsage::VERTEX,
// });
//
// self.plane_index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
// label: Some("Plane Index Buffer"),
// contents: bytemuck::cast_slice(&plane_index_data),
// usage: wgpu::BufferUsage::INDEX,
// });
// Creates the uniform for entities, which does the rotation and projection
(vertex_buf, index_buf) (vertex_buf, index_buf)
} }
pub fn create_light(&self) -> DirectionalLight {
let target = self.shadow_target_views.get(0).take().unwrap();
DirectionalLight {
color: wgpu::Color {
r: 1.0,
g: 0.5,
b: 0.5,
a: 1.0,
},
fov: 45.0,
depth: RangeCopy {
start: 1.0,
end: 20.0,
},
target_view: target.clone()
}
}
pub fn load_mesh_to_buffer(&self, filepath: &str) -> Mesh { pub fn load_mesh_to_buffer(&self, filepath: &str) -> Mesh {
let (vertices, indices) = import_mesh(filepath); let (vertices, indices) = import_mesh(filepath);
let index_count = indices.len(); let index_count = indices.len();
@ -370,11 +369,6 @@ impl Renderer {
let optional_features = Renderer::optional_features(); let optional_features = Renderer::optional_features();
let required_features = Renderer::required_features(); let required_features = Renderer::required_features();
let adapter_features = adapter.features(); let adapter_features = adapter.features();
// assert!(
// adapter_features.contains(required_features),
// "Adapter does not support required features for this example: {:?}",
// required_features - adapter_features
// );
let needed_limits = wgpu::Limits::default(); //Renderer::required_limits(); let needed_limits = wgpu::Limits::default(); //Renderer::required_limits();
@ -453,19 +447,6 @@ impl Renderer {
mapped_at_creation: false, mapped_at_creation: false,
}); });
// Pre init the light uniform, with slots enough for MAX_LIGHTS
let light_uniform_size =
(Self::MAX_LIGHTS * mem::size_of::<LightRaw>()) as wgpu::BufferAddress;
let light_uniform_buf = device.create_buffer(&wgpu::BufferDescriptor {
label: None,
size: light_uniform_size,
usage: wgpu::BufferUsage::UNIFORM
| wgpu::BufferUsage::COPY_SRC
| wgpu::BufferUsage::COPY_DST,
mapped_at_creation: false,
});
// This seems way way way way easier than what I was doing in tracer // This seems way way way way easier than what I was doing in tracer
// Though the attr thing is still a macro. Which would cause issues if // Though the attr thing is still a macro. Which would cause issues if
// I wanted to get tricky with the 0,1 types // I wanted to get tricky with the 0,1 types
@ -494,7 +475,6 @@ impl Renderer {
}], }],
}); });
/* /*
There appear to be two passes required for shadows, the shadow pass, and the forward pass There appear to be two passes required for shadows, the shadow pass, and the forward pass
Need to open this up in renderdoc and see what it's actually doing Need to open this up in renderdoc and see what it's actually doing
@ -592,6 +572,44 @@ impl Renderer {
} }
}; };
// Pre init the light uniform, with slots enough for MAX_LIGHTS
let light_uniform_size =
(Self::MAX_LIGHTS * mem::size_of::<LightRaw>()) as wgpu::BufferAddress;
let light_uniform_buf = device.create_buffer(&wgpu::BufferDescriptor {
label: None,
size: light_uniform_size,
usage: wgpu::BufferUsage::UNIFORM
| wgpu::BufferUsage::COPY_SRC
| wgpu::BufferUsage::COPY_DST,
mapped_at_creation: false,
});
let shadow_texture = device.create_texture(&wgpu::TextureDescriptor {
size: Self::SHADOW_SIZE,
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: Self::SHADOW_FORMAT,
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT | wgpu::TextureUsage::SAMPLED,
label: None,
});
let mut shadow_target_views = (0..2)
.map(|i| {
Arc::new(shadow_texture.create_view(&wgpu::TextureViewDescriptor {
label: Some("shadow"),
format: None,
dimension: Some(wgpu::TextureViewDimension::D2),
aspect: wgpu::TextureAspect::All,
base_mip_level: 0,
level_count: None,
base_array_layer: i as u32,
array_layer_count: NonZeroU32::new(1),
}))
})
.collect::<Vec<_>>();
let forward_pass = { let forward_pass = {
// Create pipeline layout // Create pipeline layout
let bind_group_layout = let bind_group_layout =
@ -660,30 +678,7 @@ impl Renderer {
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
}); });
let shadow_texture = device.create_texture(&wgpu::TextureDescriptor {
size: Self::SHADOW_SIZE,
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: Self::SHADOW_FORMAT,
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT | wgpu::TextureUsage::SAMPLED,
label: None,
});
let mut shadow_target_views = (0..2)
.map(|i| {
Some(shadow_texture.create_view(&wgpu::TextureViewDescriptor {
label: Some("shadow"),
format: None,
dimension: Some(wgpu::TextureViewDimension::D2),
aspect: wgpu::TextureAspect::All,
base_mip_level: 0,
level_count: None,
base_array_layer: i as u32,
array_layer_count: NonZeroU32::new(1),
}))
})
.collect::<Vec<_>>();
// shadow_target_views[0].take().unwrap(), // shadow_target_views[0].take().unwrap(),
// pub(crate) target_view: wgpu::TextureView, // pub(crate) target_view: wgpu::TextureView,
@ -796,142 +791,12 @@ impl Renderer {
forward_pass, forward_pass,
forward_depth: depth_texture.create_view(&wgpu::TextureViewDescriptor::default()), forward_depth: depth_texture.create_view(&wgpu::TextureViewDescriptor::default()),
entity_bind_group_layout: entity_bind_group_layout, entity_bind_group_layout: entity_bind_group_layout,
shadow_target_views: shadow_target_views,
light_uniform_buf, light_uniform_buf,
swapchain_description: sc_desc, swapchain_description: sc_desc,
surface, surface,
instance: Arc::new(instance), instance: Arc::new(instance),
}
}
pub fn render(
&mut self,
frame: &wgpu::SwapChainTexture,
device: &wgpu::Device,
queue: &wgpu::Queue,
_spawner: &impl futures::task::LocalSpawn,
) {
// update uniforms
// for entity in self.entities.iter_mut() {
//
// // Revolve the entity by the rotation speed, only if it is non-zero
// if entity.rotation_speed != 0.0 {
// let rotation = cgmath::Matrix4::from_angle_x(cgmath::Deg(entity.rotation_speed));
// entity.mx_world = entity.mx_world * rotation;
// }
//
// let data = EntityUniforms {
// model: entity.mx_world.into(),
// color: [
// entity.color.r as f32,
// entity.color.g as f32,
// entity.color.b as f32,
// entity.color.a as f32,
// ],
// };
// queue.write_buffer(&entity.uniform_buf, 0, bytemuck::bytes_of(&data));
// }
// if self.lights_are_dirty {
// self.lights_are_dirty = false;
// for (i, light) in self.lights.iter().enumerate() {
// queue.write_buffer(
// &self.light_uniform_buf,
// (i * mem::size_of::<LightRaw>()) as wgpu::BufferAddress,
// bytemuck::bytes_of(&light.to_raw()),
// );
// }
// }
let mut encoder =
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
encoder.push_debug_group("shadow passes");
/*for (i, light) in self.lights.iter().enumerate() {
encoder.push_debug_group(&format!(
"shadow pass {} (light at position {:?})",
i, light.pos
));
// The light uniform buffer already has the projection,
// let's just copy it over to the shadow uniform buffer.
encoder.copy_buffer_to_buffer(
&self.light_uniform_buf,
(i * mem::size_of::<LightRaw>()) as wgpu::BufferAddress,
&self.shadow_pass.uniform_buf,
0,
64,
);
encoder.insert_debug_marker("render entities");
{
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[],
depth_stencil_attachment: Some(
wgpu::RenderPassDepthStencilAttachmentDescriptor {
attachment: &light.target_view,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(1.0),
store: true,
}),
stencil_ops: None,
},
),
});
pass.set_pipeline(&self.shadow_pass.pipeline);
pass.set_bind_group(0, &self.shadow_pass.bind_group, &[]);
for entity in &self.entities {
pass.set_bind_group(1, &entity.bind_group, &[]);
pass.set_index_buffer(entity.index_buf.slice(..));
pass.set_vertex_buffer(0, entity.vertex_buf.slice(..));
pass.draw_indexed(0..entity.index_count as u32, 0, 0..1);
}
}
encoder.pop_debug_group();
}*/
encoder.pop_debug_group();
// forward pass
encoder.push_debug_group("forward rendering pass");
{
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
attachment: &frame.view,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color {
r: 0.1,
g: 0.2,
b: 0.3,
a: 1.0,
}),
store: true,
},
}],
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor {
attachment: &self.forward_depth,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(1.0),
store: false,
}),
stencil_ops: None,
}),
});
pass.set_pipeline(&self.forward_pass.pipeline);
pass.set_bind_group(0, &self.forward_pass.bind_group, &[]);
// for entity in &self.entities {
// pass.set_bind_group(1, &entity.bind_group, &[]);
// pass.set_index_buffer(entity.index_buf.slice(..));
// pass.set_vertex_buffer(0, entity.vertex_buf.slice(..));
// pass.draw_indexed(0..entity.index_count as u32, 0, 0..1);
// }
} }
encoder.pop_debug_group();
queue.submit(iter::once(encoder.finish()));
} }
pub(crate) fn required_features() -> wgpu::Features { pub(crate) fn required_features() -> wgpu::Features {

@ -4,8 +4,8 @@ use bytemuck::__core::mem;
use bytemuck::__core::num::NonZeroU32; use bytemuck::__core::num::NonZeroU32;
use cgmath::{Decomposed, Deg, InnerSpace, Quaternion, Rotation3, SquareMatrix}; use cgmath::{Decomposed, Deg, InnerSpace, Quaternion, Rotation3, SquareMatrix};
use crate::light::Light;
use crate::render::EntityUniforms; use crate::render::EntityUniforms;
use crate::DirectionalLight;
/* /*
@ -34,7 +34,7 @@ struct Entity {
pub struct Runtime { pub struct Runtime {
entities: Vec<Entity>, entities: Vec<Entity>,
// This is going to be ECS'd // This is going to be ECS'd
lights: Vec<Light>, // ECS lights: Vec<DirectionalLight>, // ECS
} }
impl Runtime { impl Runtime {
@ -163,28 +163,28 @@ impl Runtime {
// This is just metadata we hold for the lights. We can hold onto this // This is just metadata we hold for the lights. We can hold onto this
let lights = vec![ let lights = vec![
Light { // Light {
pos: cgmath::Point3::new(7.0, -5.0, 10.0), // pos: cgmath::Point3::new(7.0, -5.0, 10.0),
color: wgpu::Color { // color: wgpu::Color {
r: 0.5, // r: 0.5,
g: 1.0, // g: 1.0,
b: 0.5, // b: 0.5,
a: 1.0, // a: 1.0,
}, // },
fov: 60.0, // fov: 60.0,
depth: 1.0..20.0, // depth: 1.0..20.0,
}, // },
Light { // Light {
pos: cgmath::Point3::new(-5.0, 7.0, 10.0), // pos: cgmath::Point3::new(-5.0, 7.0, 10.0),
color: wgpu::Color { // color: wgpu::Color {
r: 1.0, // r: 1.0,
g: 0.5, // g: 0.5,
b: 0.5, // b: 0.5,
a: 1.0, // a: 1.0,
}, // },
fov: 45.0, // fov: 45.0,
depth: 1.0..20.0, // depth: 1.0..20.0,
}, // },
]; ];
Runtime { Runtime {

Loading…
Cancel
Save