mirror of
https://github.com/bevyengine/bevy
synced 2025-02-16 14:08:32 +00:00
port forward lighting and add struct + array uniforms
This commit is contained in:
parent
380e59ee23
commit
489580f688
6 changed files with 102 additions and 29 deletions
|
@ -103,22 +103,22 @@ fn setup(world: &mut World) {
|
||||||
translation: Translation::new(-2.0, 0.0, 1.0),
|
translation: Translation::new(-2.0, 0.0, 1.0),
|
||||||
})
|
})
|
||||||
// light
|
// light
|
||||||
// .add_archetype(LightEntity {
|
.add_archetype(LightEntity {
|
||||||
// light: Light {
|
light: Light {
|
||||||
// color: wgpu::Color {
|
color: wgpu::Color {
|
||||||
// r: 0.8,
|
r: 0.8,
|
||||||
// g: 0.8,
|
g: 0.8,
|
||||||
// b: 0.5,
|
b: 0.5,
|
||||||
// a: 1.0,
|
a: 1.0,
|
||||||
// },
|
},
|
||||||
// fov: f32::to_radians(60.0),
|
fov: f32::to_radians(60.0),
|
||||||
// depth: 0.1..50.0,
|
depth: 0.1..50.0,
|
||||||
// target_view: None,
|
target_view: None,
|
||||||
// },
|
},
|
||||||
// local_to_world: LocalToWorld::identity(),
|
local_to_world: LocalToWorld::identity(),
|
||||||
// translation: Translation::new(4.0, -4.0, 5.0),
|
translation: Translation::new(4.0, -4.0, 5.0),
|
||||||
// rotation: Rotation::from_euler_angles(0.0, 0.0, 0.0),
|
rotation: Rotation::from_euler_angles(0.0, 0.0, 0.0),
|
||||||
// })
|
})
|
||||||
// camera
|
// camera
|
||||||
.add_archetype(CameraEntity {
|
.add_archetype(CameraEntity {
|
||||||
camera: Camera::new(CameraType::Projection {
|
camera: Camera::new(CameraType::Projection {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::{hash_map::DefaultHasher},
|
collections::hash_map::DefaultHasher,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
};
|
};
|
||||||
pub struct PipelineLayout {
|
pub struct PipelineLayout {
|
||||||
|
@ -50,7 +50,7 @@ pub struct Binding {
|
||||||
pub enum BindType {
|
pub enum BindType {
|
||||||
Uniform {
|
Uniform {
|
||||||
dynamic: bool,
|
dynamic: bool,
|
||||||
properties: Vec<UniformProperty>
|
properties: Vec<UniformProperty>,
|
||||||
},
|
},
|
||||||
Buffer {
|
Buffer {
|
||||||
dynamic: bool,
|
dynamic: bool,
|
||||||
|
@ -70,9 +70,11 @@ impl BindType {
|
||||||
pub fn get_uniform_size(&self) -> Option<u64> {
|
pub fn get_uniform_size(&self) -> Option<u64> {
|
||||||
match self {
|
match self {
|
||||||
BindType::Uniform { properties, .. } => {
|
BindType::Uniform { properties, .. } => {
|
||||||
Some(properties.iter().fold(0, |total, property| total + property.property_type.get_size()))
|
Some(properties.iter().fold(0, |total, property| {
|
||||||
},
|
total + property.property_type.get_size()
|
||||||
_ => None
|
}))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,8 +94,8 @@ pub enum UniformPropertyType {
|
||||||
Vec3,
|
Vec3,
|
||||||
Vec4,
|
Vec4,
|
||||||
Mat4,
|
Mat4,
|
||||||
// Struct(Vec<UniformPropertyType>),
|
Struct(Vec<UniformPropertyType>),
|
||||||
// Array(Box<UniformPropertyType>, usize),
|
Array(Box<UniformPropertyType>, usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UniformPropertyType {
|
impl UniformPropertyType {
|
||||||
|
@ -105,6 +107,11 @@ impl UniformPropertyType {
|
||||||
UniformPropertyType::Vec3 => 4 * 3,
|
UniformPropertyType::Vec3 => 4 * 3,
|
||||||
UniformPropertyType::Vec4 => 4 * 4,
|
UniformPropertyType::Vec4 => 4 * 4,
|
||||||
UniformPropertyType::Mat4 => 4 * 4 * 4,
|
UniformPropertyType::Mat4 => 4 * 4 * 4,
|
||||||
|
UniformPropertyType::Struct(properties) => properties
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.get_size())
|
||||||
|
.fold(0, |total, size| total + size),
|
||||||
|
UniformPropertyType::Array(property, length) => property.get_size() * *length as u64,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
|
const int MAX_LIGHTS = 10;
|
||||||
|
|
||||||
|
struct Light {
|
||||||
|
mat4 proj;
|
||||||
|
vec4 pos;
|
||||||
|
vec4 color;
|
||||||
|
};
|
||||||
|
|
||||||
layout(location = 0) in vec4 v_Position;
|
layout(location = 0) in vec4 v_Position;
|
||||||
layout(location = 1) in vec3 v_Normal;
|
layout(location = 1) in vec3 v_Normal;
|
||||||
layout(location = 2) in vec2 v_Uv;
|
layout(location = 2) in vec2 v_Uv;
|
||||||
|
@ -10,12 +18,29 @@ layout(set = 0, binding = 0) uniform Camera {
|
||||||
mat4 ViewProj;
|
mat4 ViewProj;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
layout(set = 0, binding = 1) uniform Lights {
|
||||||
|
uvec4 NumLights;
|
||||||
|
Light SceneLights[MAX_LIGHTS];
|
||||||
|
};
|
||||||
|
|
||||||
layout(set = 1, binding = 1) uniform StandardMaterial {
|
layout(set = 1, binding = 1) uniform StandardMaterial {
|
||||||
vec4 Albedo;
|
vec4 Albedo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
vec3 normal = normalize(v_Normal);
|
||||||
|
vec3 ambient = vec3(0.05, 0.05, 0.05);
|
||||||
|
// accumulate color
|
||||||
|
vec3 color = ambient;
|
||||||
|
for (int i=0; i<int(NumLights.x) && i<MAX_LIGHTS; ++i) {
|
||||||
|
Light light = SceneLights[i];
|
||||||
|
// compute Lambertian diffuse term
|
||||||
|
vec3 light_dir = normalize(light.pos.xyz - v_Position.xyz);
|
||||||
|
float diffuse = max(0.0, dot(normal, light_dir));
|
||||||
|
// add light contribution
|
||||||
|
color += diffuse * light.color.xyz;
|
||||||
|
}
|
||||||
// multiply the light by material color
|
// multiply the light by material color
|
||||||
o_Target = vec4(1.0, 0.0, 0.0, 1.0);
|
o_Target = vec4(color, 1.0) * Albedo;
|
||||||
o_Target = Albedo;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ layout(set = 1, binding = 1) uniform StandardMaterial {
|
||||||
void main() {
|
void main() {
|
||||||
v_Normal = mat3(Model) * vec3(a_Normal.xyz);
|
v_Normal = mat3(Model) * vec3(a_Normal.xyz);
|
||||||
v_Position = Model * vec4(a_Pos);
|
v_Position = Model * vec4(a_Pos);
|
||||||
// v_Normal = vec3(a_Normal.xyz);
|
v_Uv = a_Uv;
|
||||||
// v_Position = vec4(a_Pos);
|
|
||||||
gl_Position = ViewProj * v_Position;
|
gl_Position = ViewProj * v_Position;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,29 @@ impl ForwardPipelineBuilder for RenderGraphBuilder {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Binding {
|
||||||
|
name: "Lights".to_string(),
|
||||||
|
bind_type: BindType::Uniform {
|
||||||
|
dynamic: false,
|
||||||
|
properties: vec![
|
||||||
|
UniformProperty {
|
||||||
|
name: "NumLights".to_string(),
|
||||||
|
property_type: UniformPropertyType::UVec4,
|
||||||
|
},
|
||||||
|
UniformProperty {
|
||||||
|
name: "SceneLights".to_string(),
|
||||||
|
property_type: UniformPropertyType::Array(
|
||||||
|
Box::new(UniformPropertyType::Struct(vec![
|
||||||
|
UniformPropertyType::Mat4, // proj
|
||||||
|
UniformPropertyType::Vec4, // pos
|
||||||
|
UniformPropertyType::Vec4, // color
|
||||||
|
])),
|
||||||
|
10, // max lights
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
]
|
]
|
||||||
))
|
))
|
||||||
.add_bind_group(BindGroup::new(
|
.add_bind_group(BindGroup::new(
|
||||||
|
|
|
@ -58,6 +58,12 @@ pub struct LightResourceProvider {
|
||||||
pub max_lights: usize,
|
pub max_lights: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy, AsBytes)]
|
||||||
|
pub struct LightCount {
|
||||||
|
pub num_lights: [u32; 4],
|
||||||
|
}
|
||||||
|
|
||||||
impl LightResourceProvider {
|
impl LightResourceProvider {
|
||||||
pub fn new(max_lights: usize) -> Self {
|
pub fn new(max_lights: usize) -> Self {
|
||||||
LightResourceProvider {
|
LightResourceProvider {
|
||||||
|
@ -70,7 +76,7 @@ impl LightResourceProvider {
|
||||||
impl ResourceProvider for LightResourceProvider {
|
impl ResourceProvider for LightResourceProvider {
|
||||||
fn initialize(&mut self, renderer: &mut dyn Renderer, _world: &mut World) {
|
fn initialize(&mut self, renderer: &mut dyn Renderer, _world: &mut World) {
|
||||||
let light_uniform_size =
|
let light_uniform_size =
|
||||||
(self.max_lights * std::mem::size_of::<LightRaw>()) as wgpu::BufferAddress;
|
(std::mem::size_of::<LightCount>() + self.max_lights * std::mem::size_of::<LightRaw>()) as wgpu::BufferAddress;
|
||||||
|
|
||||||
renderer.create_buffer(
|
renderer.create_buffer(
|
||||||
resource_name::uniform::LIGHTS,
|
resource_name::uniform::LIGHTS,
|
||||||
|
@ -91,6 +97,7 @@ impl ResourceProvider for LightResourceProvider {
|
||||||
self.lights_are_dirty = false;
|
self.lights_are_dirty = false;
|
||||||
let size = std::mem::size_of::<LightRaw>();
|
let size = std::mem::size_of::<LightRaw>();
|
||||||
let total_size = size * light_count;
|
let total_size = size * light_count;
|
||||||
|
let light_count_size = std::mem::size_of::<LightCount>();
|
||||||
renderer
|
renderer
|
||||||
.create_buffer_mapped("LIGHT_TMP", total_size, wgpu::BufferUsage::COPY_SRC, &mut |data| {
|
.create_buffer_mapped("LIGHT_TMP", total_size, wgpu::BufferUsage::COPY_SRC, &mut |data| {
|
||||||
for ((light, local_to_world, translation), slot) in light_query
|
for ((light, local_to_world, translation), slot) in light_query
|
||||||
|
@ -102,10 +109,22 @@ impl ResourceProvider for LightResourceProvider {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
renderer
|
||||||
|
.create_buffer_mapped("LIGHT_COUNT_TMP", light_count_size, wgpu::BufferUsage::COPY_SRC, &mut |data| {
|
||||||
|
data.copy_from_slice([light_count as u32, 0, 0, 0].as_bytes());
|
||||||
|
});
|
||||||
|
|
||||||
|
renderer.copy_buffer_to_buffer(
|
||||||
|
"LIGHT_COUNT_TMP",
|
||||||
|
0,
|
||||||
|
resource_name::uniform::LIGHTS,
|
||||||
|
0,
|
||||||
|
light_count_size as wgpu::BufferAddress,
|
||||||
|
);
|
||||||
|
|
||||||
renderer.copy_buffer_to_buffer(
|
renderer.copy_buffer_to_buffer(
|
||||||
"LIGHT_TMP",
|
"LIGHT_TMP",
|
||||||
0,
|
light_count_size as u64,
|
||||||
resource_name::uniform::LIGHTS,
|
resource_name::uniform::LIGHTS,
|
||||||
0,
|
0,
|
||||||
total_size as wgpu::BufferAddress,
|
total_size as wgpu::BufferAddress,
|
||||||
|
|
Loading…
Add table
Reference in a new issue