mirror of
https://github.com/bevyengine/bevy
synced 2025-02-16 14:08:32 +00:00
begin porting over lighting
This commit is contained in:
parent
48e8967acc
commit
380e59ee23
11 changed files with 285 additions and 50 deletions
|
@ -4,7 +4,7 @@ use crate::{
|
|||
core::Time,
|
||||
legion::prelude::{Runnable, Schedulable, Schedule, Universe, World},
|
||||
render::render_graph_2,
|
||||
render::render_graph_2::{pipelines::*, wgpu_renderer::WgpuRenderer, resource_provider::CameraResourceProvider, UniformResourceProvider, StandardMaterial},
|
||||
render::render_graph_2::{pipelines::*, passes::*, wgpu_renderer::WgpuRenderer, resource_provider::{CameraResourceProvider, LightResourceProvider}, UniformResourceProvider, StandardMaterial},
|
||||
render::{passes::*, *},
|
||||
plugin::load_plugin,
|
||||
ui,
|
||||
|
@ -175,6 +175,7 @@ impl AppBuilder {
|
|||
self.render_graph_builder = self
|
||||
.render_graph_builder
|
||||
.add_resource_provider(Box::new(CameraResourceProvider))
|
||||
.add_resource_provider(Box::new(LightResourceProvider::new(10)))
|
||||
.add_resource_provider(Box::new(UniformResourceProvider::<StandardMaterial>::new()))
|
||||
.add_resource_provider(Box::new(UniformResourceProvider::<LocalToWorld>::new()))
|
||||
.add_forward_pass()
|
||||
|
|
|
@ -2,6 +2,7 @@ pub mod pipelines;
|
|||
pub mod resource_name;
|
||||
pub mod wgpu_renderer;
|
||||
pub mod resource_provider;
|
||||
pub mod passes;
|
||||
mod resource;
|
||||
mod pipeline;
|
||||
mod pipeline_layout;
|
||||
|
|
43
src/render/render_graph_2/passes/forward.rs
Normal file
43
src/render/render_graph_2/passes/forward.rs
Normal file
|
@ -0,0 +1,43 @@
|
|||
use crate::render::{
|
||||
render_graph_2::{
|
||||
resource_name, PassDescriptor,
|
||||
RenderGraphBuilder, RenderPassColorAttachmentDescriptor,
|
||||
},
|
||||
};
|
||||
|
||||
pub trait ForwardPassBuilder {
|
||||
fn add_forward_pass(self) -> Self;
|
||||
}
|
||||
|
||||
impl ForwardPassBuilder for RenderGraphBuilder {
|
||||
fn add_forward_pass(self) -> Self {
|
||||
self.add_pass(
|
||||
"main",
|
||||
PassDescriptor {
|
||||
color_attachments: vec![RenderPassColorAttachmentDescriptor {
|
||||
attachment: resource_name::texture::SWAP_CHAIN.to_string(),
|
||||
resolve_target: None,
|
||||
load_op: wgpu::LoadOp::Clear,
|
||||
store_op: wgpu::StoreOp::Store,
|
||||
clear_color: wgpu::Color {
|
||||
r: 0.3,
|
||||
g: 0.4,
|
||||
b: 0.5,
|
||||
a: 1.0,
|
||||
},
|
||||
}],
|
||||
depth_stencil_attachment: None,
|
||||
// depth_stencil_attachment: Some(RenderPassDepthStencilAttachmentDescriptor {
|
||||
// attachment: "forward_depth".to_string(),
|
||||
// depth_load_op: wgpu::LoadOp::Clear,
|
||||
// depth_store_op: wgpu::StoreOp::Store,
|
||||
// stencil_load_op: wgpu::LoadOp::Clear,
|
||||
// stencil_store_op: wgpu::StoreOp::Store,
|
||||
// clear_depth: 1.0,
|
||||
// clear_stencil: 0,
|
||||
// }),
|
||||
sample_count: 1,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
3
src/render/render_graph_2/passes/mod.rs
Normal file
3
src/render/render_graph_2/passes/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
mod forward;
|
||||
|
||||
pub use forward::*;
|
|
@ -2,8 +2,8 @@ use crate::render::{
|
|||
Vertex,
|
||||
{
|
||||
render_graph_2::{
|
||||
mesh_draw_target, resource_name, pipeline_layout::*, PassDescriptor, PipelineDescriptor,
|
||||
RenderGraphBuilder, RenderPassColorAttachmentDescriptor,
|
||||
mesh_draw_target, pipeline_layout::*, PipelineDescriptor,
|
||||
RenderGraphBuilder,
|
||||
},
|
||||
shader::{Shader, ShaderStage},
|
||||
},
|
||||
|
@ -95,41 +95,4 @@ impl ForwardPipelineBuilder for RenderGraphBuilder {
|
|||
.build(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ForwardPassBuilder {
|
||||
fn add_forward_pass(self) -> Self;
|
||||
}
|
||||
|
||||
impl ForwardPassBuilder for RenderGraphBuilder {
|
||||
fn add_forward_pass(self) -> Self {
|
||||
self.add_pass(
|
||||
"main",
|
||||
PassDescriptor {
|
||||
color_attachments: vec![RenderPassColorAttachmentDescriptor {
|
||||
attachment: resource_name::texture::SWAP_CHAIN.to_string(),
|
||||
resolve_target: None,
|
||||
load_op: wgpu::LoadOp::Clear,
|
||||
store_op: wgpu::StoreOp::Store,
|
||||
clear_color: wgpu::Color {
|
||||
r: 0.3,
|
||||
g: 0.4,
|
||||
b: 0.5,
|
||||
a: 1.0,
|
||||
},
|
||||
}],
|
||||
depth_stencil_attachment: None,
|
||||
// depth_stencil_attachment: Some(RenderPassDepthStencilAttachmentDescriptor {
|
||||
// attachment: "forward_depth".to_string(),
|
||||
// depth_load_op: wgpu::LoadOp::Clear,
|
||||
// depth_store_op: wgpu::StoreOp::Store,
|
||||
// stencil_load_op: wgpu::LoadOp::Clear,
|
||||
// stencil_store_op: wgpu::StoreOp::Store,
|
||||
// clear_depth: 1.0,
|
||||
// clear_stencil: 0,
|
||||
// }),
|
||||
sample_count: 1,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) in vec4 v_Position;
|
||||
layout(location = 1) in vec3 v_Normal;
|
||||
layout(location = 2) in vec2 v_Uv;
|
||||
|
||||
layout(location = 0) out vec4 o_Target;
|
||||
|
||||
layout(set = 0, binding = 0) uniform Camera {
|
||||
mat4 ViewProj;
|
||||
};
|
||||
|
||||
layout(set = 1, binding = 1) uniform StandardMaterial {
|
||||
vec4 Albedo;
|
||||
};
|
||||
|
||||
void main() {
|
||||
// multiply the light by material color
|
||||
o_Target = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
o_Target = Albedo;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) in vec4 a_Pos;
|
||||
layout(location = 1) in vec4 a_Normal;
|
||||
layout(location = 2) in vec2 a_Uv;
|
||||
|
||||
layout(location = 0) out vec4 v_Position;
|
||||
layout(location = 1) out vec3 v_Normal;
|
||||
layout(location = 2) out vec2 v_Uv;
|
||||
|
||||
layout(set = 0, binding = 0) uniform Camera {
|
||||
mat4 ViewProj;
|
||||
};
|
||||
|
||||
layout(set = 1, binding = 0) uniform Object {
|
||||
mat4 Model;
|
||||
};
|
||||
|
||||
layout(set = 1, binding = 1) uniform StandardMaterial {
|
||||
vec4 Albedo;
|
||||
};
|
||||
|
||||
void main() {
|
||||
v_Normal = mat3(Model) * vec3(a_Normal.xyz);
|
||||
v_Position = Model * vec4(a_Pos);
|
||||
// v_Normal = vec3(a_Normal.xyz);
|
||||
// v_Position = vec4(a_Pos);
|
||||
gl_Position = ViewProj * v_Position;
|
||||
}
|
98
src/render/render_graph_2/pipelines/forward_flat/mod.rs
Normal file
98
src/render/render_graph_2/pipelines/forward_flat/mod.rs
Normal file
|
@ -0,0 +1,98 @@
|
|||
use crate::render::{
|
||||
Vertex,
|
||||
{
|
||||
render_graph_2::{
|
||||
mesh_draw_target, pipeline_layout::*, PipelineDescriptor,
|
||||
RenderGraphBuilder,
|
||||
},
|
||||
shader::{Shader, ShaderStage},
|
||||
},
|
||||
};
|
||||
pub trait ForwardFlatPipelineBuilder {
|
||||
fn add_forward_flat_pipeline(self) -> Self;
|
||||
}
|
||||
|
||||
impl ForwardFlatPipelineBuilder for RenderGraphBuilder {
|
||||
fn add_forward_flat_pipeline(self) -> Self {
|
||||
self.add_pipeline(
|
||||
"forward_flat",
|
||||
PipelineDescriptor::build(Shader::from_glsl(
|
||||
include_str!("forward_flat.vert"),
|
||||
ShaderStage::Vertex,
|
||||
))
|
||||
.with_fragment_shader(Shader::from_glsl(
|
||||
include_str!("forward_flat.frag"),
|
||||
ShaderStage::Fragment,
|
||||
))
|
||||
.add_bind_group(BindGroup::new(
|
||||
vec![
|
||||
Binding {
|
||||
name: "Camera".to_string(),
|
||||
bind_type: BindType::Uniform {
|
||||
dynamic: false,
|
||||
properties: vec![
|
||||
UniformProperty {
|
||||
name: "ViewProj".to_string(),
|
||||
property_type: UniformPropertyType::Mat4,
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]
|
||||
))
|
||||
.add_bind_group(BindGroup::new(
|
||||
vec![
|
||||
Binding {
|
||||
name: "Object".to_string(),
|
||||
bind_type: BindType::Uniform {
|
||||
dynamic: true,
|
||||
properties: vec![
|
||||
UniformProperty {
|
||||
name: "Model".to_string(),
|
||||
property_type: UniformPropertyType::Mat4,
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
Binding {
|
||||
name: "StandardMaterial".to_string(),
|
||||
bind_type: BindType::Uniform {
|
||||
dynamic: true,
|
||||
properties: vec![
|
||||
UniformProperty {
|
||||
name: "Albedo".to_string(),
|
||||
property_type: UniformPropertyType::Vec4,
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]
|
||||
))
|
||||
.with_rasterization_state(wgpu::RasterizationStateDescriptor {
|
||||
front_face: wgpu::FrontFace::Ccw,
|
||||
cull_mode: wgpu::CullMode::Back,
|
||||
depth_bias: 0,
|
||||
depth_bias_slope_scale: 0.0,
|
||||
depth_bias_clamp: 0.0,
|
||||
})
|
||||
// .with_depth_stencil_state(wgpu::DepthStencilStateDescriptor {
|
||||
// format: wgpu::TextureFormat::Depth32Float,
|
||||
// depth_write_enabled: true,
|
||||
// depth_compare: wgpu::CompareFunction::Less,
|
||||
// stencil_front: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
// stencil_back: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
// stencil_read_mask: 0,
|
||||
// stencil_write_mask: 0,
|
||||
// })
|
||||
.add_color_state(wgpu::ColorStateDescriptor {
|
||||
format: wgpu::TextureFormat::Bgra8UnormSrgb,
|
||||
color_blend: wgpu::BlendDescriptor::REPLACE,
|
||||
alpha_blend: wgpu::BlendDescriptor::REPLACE,
|
||||
write_mask: wgpu::ColorWrite::ALL,
|
||||
})
|
||||
.add_vertex_buffer_descriptor(Vertex::get_vertex_buffer_descriptor())
|
||||
.add_draw_target(mesh_draw_target)
|
||||
.build(),
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
mod forward;
|
||||
mod forward_flat;
|
||||
|
||||
pub use forward::*;
|
||||
pub use forward::*;
|
||||
pub use forward_flat::*;
|
|
@ -4,4 +4,5 @@ pub mod texture {
|
|||
|
||||
pub mod uniform {
|
||||
pub const CAMERA: &str = "Camera";
|
||||
pub const LIGHTS: &str = "Lights";
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
use crate::render::{
|
||||
use crate::{render::{
|
||||
render_graph_2::{resource_name, Renderer},
|
||||
ActiveCamera, Camera,
|
||||
};
|
||||
ActiveCamera, Camera, Light, LightRaw,
|
||||
}, transform::prelude::Translation};
|
||||
use bevy_transform::prelude::LocalToWorld;
|
||||
use legion::prelude::*;
|
||||
use zerocopy::AsBytes;
|
||||
|
@ -33,11 +33,84 @@ impl ResourceProvider for CameraResourceProvider {
|
|||
let camera_matrix: [[f32; 4]; 4] =
|
||||
(camera.view_matrix * local_to_world.0).to_cols_array_2d();
|
||||
|
||||
renderer.create_buffer_mapped("camera_tmp", matrix_size, wgpu::BufferUsage::COPY_SRC, &mut |data| {
|
||||
data[0..matrix_size].copy_from_slice(camera_matrix.as_bytes());
|
||||
});
|
||||
renderer.create_buffer_mapped(
|
||||
"camera_tmp",
|
||||
matrix_size,
|
||||
wgpu::BufferUsage::COPY_SRC,
|
||||
&mut |data| {
|
||||
data[0..matrix_size].copy_from_slice(camera_matrix.as_bytes());
|
||||
},
|
||||
);
|
||||
|
||||
renderer.copy_buffer_to_buffer("camera_tmp", 0, resource_name::uniform::CAMERA, 0, matrix_size as u64);
|
||||
renderer.copy_buffer_to_buffer(
|
||||
"camera_tmp",
|
||||
0,
|
||||
resource_name::uniform::CAMERA,
|
||||
0,
|
||||
matrix_size as u64,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LightResourceProvider {
|
||||
pub lights_are_dirty: bool,
|
||||
pub max_lights: usize,
|
||||
}
|
||||
|
||||
impl LightResourceProvider {
|
||||
pub fn new(max_lights: usize) -> Self {
|
||||
LightResourceProvider {
|
||||
lights_are_dirty: true,
|
||||
max_lights: max_lights,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ResourceProvider for LightResourceProvider {
|
||||
fn initialize(&mut self, renderer: &mut dyn Renderer, _world: &mut World) {
|
||||
let light_uniform_size =
|
||||
(self.max_lights * std::mem::size_of::<LightRaw>()) as wgpu::BufferAddress;
|
||||
|
||||
renderer.create_buffer(
|
||||
resource_name::uniform::LIGHTS,
|
||||
light_uniform_size,
|
||||
wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_SRC | wgpu::BufferUsage::COPY_DST,
|
||||
);
|
||||
}
|
||||
|
||||
fn update(&mut self, renderer: &mut dyn Renderer, world: &mut World) {
|
||||
if self.lights_are_dirty {
|
||||
let light_query = <(Read<Light>, Read<LocalToWorld>, Read<Translation>)>::query();
|
||||
let light_count = light_query.iter(world).count();
|
||||
|
||||
if light_count == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
self.lights_are_dirty = false;
|
||||
let size = std::mem::size_of::<LightRaw>();
|
||||
let total_size = size * light_count;
|
||||
renderer
|
||||
.create_buffer_mapped("LIGHT_TMP", total_size, wgpu::BufferUsage::COPY_SRC, &mut |data| {
|
||||
for ((light, local_to_world, translation), slot) in light_query
|
||||
.iter(world)
|
||||
.zip(data.chunks_exact_mut(size))
|
||||
{
|
||||
slot.copy_from_slice(
|
||||
LightRaw::from(&light, &local_to_world.0, &translation).as_bytes(),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
renderer.copy_buffer_to_buffer(
|
||||
"LIGHT_TMP",
|
||||
0,
|
||||
resource_name::uniform::LIGHTS,
|
||||
0,
|
||||
total_size as wgpu::BufferAddress,
|
||||
);
|
||||
}
|
||||
}
|
||||
fn resize(&mut self, renderer: &mut dyn Renderer, world: &mut World, width: u32, height: u32) {}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue