Skip to content

Commit

Permalink
Start on splitting camera bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
mtsr committed Mar 10, 2021
1 parent b361e19 commit 2e809b3
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ layout(location = 2) in vec2 v_Uv;

layout(location = 0) out vec4 o_Target;

layout(set = 0, binding = 0) uniform Camera {
layout(set = 0, binding = 0) uniform CameraViewProj {
mat4 ViewProj;
};
layout(set = 0, binding = 1) uniform CameraView {
mat4 View;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ layout(location = 0) out vec3 v_Position;
layout(location = 1) out vec3 v_Normal;
layout(location = 2) out vec2 v_Uv;

layout(set = 0, binding = 0) uniform Camera {
layout(set = 0, binding = 0) uniform CameraViewProj {
mat4 ViewProj;
};
layout(set = 0, binding = 1) uniform CameraView {
mat4 View;
};

Expand Down
40 changes: 24 additions & 16 deletions crates/bevy_render/src/render_graph/nodes/camera_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ use crate::{
RenderResourceBindings, RenderResourceContext,
},
};
use bevy_core::AsBytes;
use bevy_core::{AsBytes, Bytes};
use bevy_ecs::{
system::{BoxedSystem, IntoSystem, Local, Query, Res, ResMut},
world::World,
};

use bevy_transform::prelude::*;
use std::borrow::Cow;

Expand Down Expand Up @@ -83,28 +84,42 @@ pub fn camera_node_system(
return;
};

let view_matrix = global_transform.compute_matrix().inverse();
let camera_matrix = [
(camera.projection_matrix * view_matrix).to_cols_array(),
view_matrix.to_cols_array(),
];
let buffer_size = camera_matrix.byte_len();

let staging_buffer = if let Some(staging_buffer) = state.staging_buffer {
render_resource_context.map_buffer(staging_buffer, BufferMapMode::Write);
staging_buffer
} else {
let size = std::mem::size_of::<[[[f32; 4]; 4]; 2]>();
let buffer = render_resource_context.create_buffer(BufferInfo {
size,
size: buffer_size,
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
..Default::default()
});
render_resource_bindings.set(
&state.camera_name,
&format!("{}ViewProj", &state.camera_name),
RenderResourceBinding::Buffer {
buffer,
range: 0..size as u64,
range: 0..view_matrix.byte_len() as u64,
dynamic_index: None,
},
);
render_resource_bindings.set(
&format!("{}View", &state.camera_name),
RenderResourceBinding::Buffer {
buffer,
range: view_matrix.byte_len() as u64..buffer_size as u64,
dynamic_index: None,
},
);
state.camera_buffer = Some(buffer);

let staging_buffer = render_resource_context.create_buffer(BufferInfo {
size,
size: buffer_size,
buffer_usage: BufferUsage::COPY_SRC | BufferUsage::MAP_WRITE,
mapped_at_creation: true,
});
Expand All @@ -113,18 +128,11 @@ pub fn camera_node_system(
staging_buffer
};

let matrix_size = std::mem::size_of::<[[[f32; 4]; 4]; 2]>();
let view_matrix = global_transform.compute_matrix().inverse();
let camera_matrix: [[f32; 16]; 2] = [
(camera.projection_matrix * view_matrix).to_cols_array(),
view_matrix.to_cols_array()
];

render_resource_context.write_mapped_buffer(
staging_buffer,
0..matrix_size as u64,
0..buffer_size as u64,
&mut |data, _renderer| {
data[0..matrix_size].copy_from_slice(camera_matrix.as_bytes());
data[0..buffer_size].copy_from_slice(camera_matrix.as_bytes());
},
);
render_resource_context.unmap_buffer(staging_buffer);
Expand All @@ -135,6 +143,6 @@ pub fn camera_node_system(
0,
camera_buffer,
0,
matrix_size as u64,
buffer_size as u64,
);
}
66 changes: 48 additions & 18 deletions crates/bevy_render/src/render_graph/nodes/pass_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,18 +108,30 @@ impl<Q: WorldQuery> PassNode<Q> {

let camera_bind_group_descriptor = BindGroupDescriptor::new(
0,
vec![BindingDescriptor {
name: "Camera".to_string(),
index: 0,
bind_type: BindType::Uniform {
has_dynamic_offset: false,
property: UniformProperty::Struct(vec![
UniformProperty::Mat4, // View Projection
UniformProperty::Mat4, // View
]),
vec![
BindingDescriptor {
name: "CameraViewProj".to_string(),
index: 0,
bind_type: BindType::Uniform {
has_dynamic_offset: false,
property: UniformProperty::Struct(vec![
UniformProperty::Mat4, // View Projection
]),
},
shader_stage: BindingShaderStage::VERTEX | BindingShaderStage::FRAGMENT,
},
shader_stage: BindingShaderStage::VERTEX | BindingShaderStage::FRAGMENT,
}],
BindingDescriptor {
name: "CameraView".to_string(),
index: 1,
bind_type: BindType::Uniform {
has_dynamic_offset: false,
property: UniformProperty::Struct(vec![
UniformProperty::Mat4, // View
]),
},
shader_stage: BindingShaderStage::VERTEX | BindingShaderStage::FRAGMENT,
},
],
);

PassNode {
Expand Down Expand Up @@ -195,18 +207,36 @@ where
.attachment =
TextureAttachment::Id(input.get(input_index).unwrap().get_texture().unwrap());
}

for camera_info in self.cameras.iter_mut() {
let camera_binding =
if let Some(camera_binding) = render_resource_bindings.get(&camera_info.name) {
camera_binding.clone()
} else {
continue;
};
let camera_name = &camera_info.name;

if render_context
.resources()
.bind_group_descriptor_exists(self.camera_bind_group_descriptor.id)
{
let camera_bind_group = BindGroup::build().add_binding(0, camera_binding).finish();
let mut camera_bind_group_builder = BindGroup::build();

for binding_name in self
.camera_bind_group_descriptor
.bindings
.iter()
.map(|binding| &binding.name)
{
let camera_binding = if let Some(camera_binding) = render_resource_bindings.get(
&format!("{}{}", &camera_name, binding_name.replace("Camera", "")),
) {
camera_binding.clone()
} else {
continue;
};

camera_bind_group_builder =
camera_bind_group_builder.add_binding(0, camera_binding);
}

let camera_bind_group = camera_bind_group_builder.finish();

render_context
.resources()
.create_bind_group(self.camera_bind_group_descriptor.id, &camera_bind_group);
Expand Down

0 comments on commit 2e809b3

Please sign in to comment.