Skip to content

Commit

Permalink
Improved shadow rendering code.
Browse files Browse the repository at this point in the history
  • Loading branch information
facundo-villa committed Feb 3, 2024
1 parent 4331f23 commit f8b6a90
Show file tree
Hide file tree
Showing 13 changed files with 288 additions and 147 deletions.
13 changes: 11 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
workspace = { members = ["tests/gi"] }
[package]
name = "byte_engine"
version = "0.1.0"
Expand Down
32 changes: 16 additions & 16 deletions src/ghi/graphics_hardware_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ pub trait GraphicsHardwareInterface {
fn add_mesh_from_vertices_and_indices(&mut self, vertex_count: u32, index_count: u32, vertices: &[u8], indices: &[u8], vertex_layout: &[VertexElement]) -> MeshHandle;

/// Creates a shader.
fn create_shader(&mut self, shader_source_type: ShaderSource, stage: ShaderTypes, shader_binding_descriptors: &[ShaderBindingDescriptor],) -> ShaderHandle;
fn create_shader(&mut self, name: Option<&str>, shader_source_type: ShaderSource, stage: ShaderTypes, shader_binding_descriptors: &[ShaderBindingDescriptor],) -> ShaderHandle;

fn create_descriptor_set_template(&mut self, name: Option<&str>, binding_templates: &[DescriptorSetBindingTemplate]) -> DescriptorSetTemplateHandle;

Expand Down Expand Up @@ -1191,8 +1191,8 @@ pub(super) mod tests {
}
";

let vertex_shader = renderer.create_shader(ShaderSource::GLSL(vertex_shader_code.to_string()), ShaderTypes::Vertex, &[]);
let fragment_shader = renderer.create_shader(ShaderSource::GLSL(fragment_shader_code.to_string()), ShaderTypes::Fragment, &[]);
let vertex_shader = renderer.create_shader(None, ShaderSource::GLSL(vertex_shader_code.to_string()), ShaderTypes::Vertex, &[]);
let fragment_shader = renderer.create_shader(None, ShaderSource::GLSL(fragment_shader_code.to_string()), ShaderTypes::Fragment, &[]);

let pipeline_layout = renderer.create_pipeline_layout(&[], &[]);

Expand Down Expand Up @@ -1330,8 +1330,8 @@ pub(super) mod tests {
}
";

let vertex_shader = renderer.create_shader(ShaderSource::GLSL(vertex_shader_code.to_string()), ShaderTypes::Vertex, &[]);
let fragment_shader = renderer.create_shader(ShaderSource::GLSL(fragment_shader_code.to_string()), ShaderTypes::Fragment, &[]);
let vertex_shader = renderer.create_shader(None, ShaderSource::GLSL(vertex_shader_code.to_string()), ShaderTypes::Vertex, &[]);
let fragment_shader = renderer.create_shader(None, ShaderSource::GLSL(fragment_shader_code.to_string()), ShaderTypes::Fragment, &[]);

let pipeline_layout = renderer.create_pipeline_layout(&[], &[]);

Expand Down Expand Up @@ -1458,8 +1458,8 @@ pub(super) mod tests {
}
";

let vertex_shader = renderer.create_shader(ShaderSource::GLSL(vertex_shader_code.to_string()), ShaderTypes::Vertex, &[]);
let fragment_shader = renderer.create_shader(ShaderSource::GLSL(fragment_shader_code.to_string()), ShaderTypes::Fragment, &[]);
let vertex_shader = renderer.create_shader(None, ShaderSource::GLSL(vertex_shader_code.to_string()), ShaderTypes::Vertex, &[]);
let fragment_shader = renderer.create_shader(None, ShaderSource::GLSL(fragment_shader_code.to_string()), ShaderTypes::Fragment, &[]);

let pipeline_layout = renderer.create_pipeline_layout(&[], &[]);

Expand Down Expand Up @@ -1585,8 +1585,8 @@ pub(super) mod tests {
}
";

let vertex_shader = renderer.create_shader(ShaderSource::GLSL(vertex_shader_code.to_string()), ShaderTypes::Vertex, &[]);
let fragment_shader = renderer.create_shader(ShaderSource::GLSL(fragment_shader_code.to_string()), ShaderTypes::Fragment, &[]);
let vertex_shader = renderer.create_shader(None, ShaderSource::GLSL(vertex_shader_code.to_string()), ShaderTypes::Vertex, &[]);
let fragment_shader = renderer.create_shader(None, ShaderSource::GLSL(fragment_shader_code.to_string()), ShaderTypes::Fragment, &[]);

let pipeline_layout = renderer.create_pipeline_layout(&[], &[]);

Expand Down Expand Up @@ -1722,8 +1722,8 @@ pub(super) mod tests {
}
";

let vertex_shader = renderer.create_shader(ShaderSource::GLSL(vertex_shader_code.to_string()), ShaderTypes::Vertex, &[]);
let fragment_shader = renderer.create_shader(ShaderSource::GLSL(fragment_shader_code.to_string()), ShaderTypes::Fragment, &[]);
let vertex_shader = renderer.create_shader(None, ShaderSource::GLSL(vertex_shader_code.to_string()), ShaderTypes::Vertex, &[]);
let fragment_shader = renderer.create_shader(None, ShaderSource::GLSL(fragment_shader_code.to_string()), ShaderTypes::Fragment, &[]);

let pipeline_layout = renderer.create_pipeline_layout(&[], &[PushConstantRange{ offset: 0, size: 16 * 4 }]);

Expand Down Expand Up @@ -1888,8 +1888,8 @@ pub(super) mod tests {
}
";

let vertex_shader = renderer.create_shader(ShaderSource::GLSL(vertex_shader_code.to_string()), ShaderTypes::Vertex, &[ShaderBindingDescriptor::new(0, 1, AccessPolicies::READ)]);
let fragment_shader = renderer.create_shader(ShaderSource::GLSL(fragment_shader_code.to_string()), ShaderTypes::Fragment, &[ShaderBindingDescriptor::new(0, 0, AccessPolicies::READ), ShaderBindingDescriptor::new(0, 2, AccessPolicies::READ)]);
let vertex_shader = renderer.create_shader(None, ShaderSource::GLSL(vertex_shader_code.to_string()), ShaderTypes::Vertex, &[ShaderBindingDescriptor::new(0, 1, AccessPolicies::READ)]);
let fragment_shader = renderer.create_shader(None, ShaderSource::GLSL(fragment_shader_code.to_string()), ShaderTypes::Fragment, &[ShaderBindingDescriptor::new(0, 0, AccessPolicies::READ), ShaderBindingDescriptor::new(0, 2, AccessPolicies::READ)]);

let buffer = renderer.create_buffer(None, 64, Uses::Uniform | Uses::Storage, DeviceAccesses::CpuWrite | DeviceAccesses::GpuRead, UseCases::DYNAMIC);

Expand Down Expand Up @@ -2111,9 +2111,9 @@ void main() {
}
";

let raygen_shader = renderer.create_shader(ShaderSource::GLSL(raygen_shader_code.to_string()), ShaderTypes::RayGen, &[ShaderBindingDescriptor::new(0, 0, AccessPolicies::READ), ShaderBindingDescriptor::new(0, 1, AccessPolicies::WRITE)]);
let closest_hit_shader = renderer.create_shader(ShaderSource::GLSL(closest_hit_shader_code.to_string()), ShaderTypes::ClosestHit, &[ShaderBindingDescriptor::new(0, 2, AccessPolicies::READ), ShaderBindingDescriptor::new(0, 3, AccessPolicies::READ), ShaderBindingDescriptor::new(0, 4, AccessPolicies::READ)]);
let miss_shader = renderer.create_shader(ShaderSource::GLSL(miss_shader_code.to_string()), ShaderTypes::Miss, &[]);
let raygen_shader = renderer.create_shader(None, ShaderSource::GLSL(raygen_shader_code.to_string()), ShaderTypes::RayGen, &[ShaderBindingDescriptor::new(0, 0, AccessPolicies::READ), ShaderBindingDescriptor::new(0, 1, AccessPolicies::WRITE)]);
let closest_hit_shader = renderer.create_shader(None, ShaderSource::GLSL(closest_hit_shader_code.to_string()), ShaderTypes::ClosestHit, &[ShaderBindingDescriptor::new(0, 2, AccessPolicies::READ), ShaderBindingDescriptor::new(0, 3, AccessPolicies::READ), ShaderBindingDescriptor::new(0, 4, AccessPolicies::READ)]);
let miss_shader = renderer.create_shader(None, ShaderSource::GLSL(miss_shader_code.to_string()), ShaderTypes::Miss, &[]);

let top_level_acceleration_structure = renderer.create_top_level_acceleration_structure(Some("Top Level"));
let bottom_level_acceleration_structure = renderer.create_bottom_level_acceleration_structure(&BottomLevelAccelerationStructure{
Expand Down
60 changes: 41 additions & 19 deletions src/ghi/vulkan_ghi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl graphics_hardware_interface::GraphicsHardwareInterface for VulkanGHI {
}

/// Creates a shader.
fn create_shader(&mut self, shader_source_type: graphics_hardware_interface::ShaderSource, stage: graphics_hardware_interface::ShaderTypes, shader_binding_descriptors: &[ShaderBindingDescriptor],) -> graphics_hardware_interface::ShaderHandle {
fn create_shader(&mut self, name: Option<&str>, shader_source_type: graphics_hardware_interface::ShaderSource, stage: graphics_hardware_interface::ShaderTypes, shader_binding_descriptors: &[ShaderBindingDescriptor],) -> graphics_hardware_interface::ShaderHandle {
match shader_source_type {
graphics_hardware_interface::ShaderSource::GLSL(source_code) => {
let compiler = shaderc::Compiler::new().unwrap();
Expand All @@ -114,7 +114,7 @@ impl graphics_hardware_interface::GraphicsHardwareInterface for VulkanGHI {

match binary {
Ok(binary) => {
self.create_vulkan_shader(stage, binary.as_binary_u8(), shader_binding_descriptors)
self.create_vulkan_shader(name, stage, binary.as_binary_u8(), shader_binding_descriptors)
},
Err(err) => {
let compiler_error_string = err.to_string();
Expand All @@ -130,7 +130,7 @@ impl graphics_hardware_interface::GraphicsHardwareInterface for VulkanGHI {
}
}
graphics_hardware_interface::ShaderSource::SPIRV(spirv) => {
self.create_vulkan_shader(stage, spirv, shader_binding_descriptors)
self.create_vulkan_shader(name, stage, spirv, shader_binding_descriptors)
}
}
}
Expand Down Expand Up @@ -2103,7 +2103,7 @@ impl VulkanGHI {

fn get_log_count(&self) -> u64 { self.debug_data.error_count }

fn create_vulkan_shader(&mut self, stage: graphics_hardware_interface::ShaderTypes, shader: &[u8], shader_binding_descriptors: &[ShaderBindingDescriptor]) -> graphics_hardware_interface::ShaderHandle {
fn create_vulkan_shader(&mut self, name: Option<&str>, stage: graphics_hardware_interface::ShaderTypes, shader: &[u8], shader_binding_descriptors: &[ShaderBindingDescriptor]) -> graphics_hardware_interface::ShaderHandle {
let shader_module_create_info = vk::ShaderModuleCreateInfo::default().code(unsafe { shader.align_to::<u32>().1 });

let shader_module = unsafe { self.device.create_shader_module(&shader_module_create_info, None).expect("No shader module") };
Expand All @@ -2116,6 +2116,8 @@ impl VulkanGHI {
shader_binding_descriptors: shader_binding_descriptors.to_vec(),
});

self.set_name(shader_module, name);

handle
}

Expand Down Expand Up @@ -3088,21 +3090,41 @@ impl graphics_hardware_interface::CommandBufferRecording for VulkanCommandBuffer
for (texture_handle, clear_value) in textures {
let (_, texture) = self.get_texture(*texture_handle);

let clear_value = match clear_value {
graphics_hardware_interface::ClearValue::None => vk::ClearColorValue{ float32: [0.0, 0.0, 0.0, 0.0] },
graphics_hardware_interface::ClearValue::Color(color) => vk::ClearColorValue{ float32: [color.r, color.g, color.b, color.a] },
graphics_hardware_interface::ClearValue::Depth(depth) => vk::ClearColorValue{ float32: [*depth, 0.0, 0.0, 0.0] },
graphics_hardware_interface::ClearValue::Integer(r, g, b, a) => vk::ClearColorValue{ uint32: [*r, *g, *b, *a] },
};

unsafe {
self.ghi.device.cmd_clear_color_image(self.get_command_buffer().command_buffer, texture.image, vk::ImageLayout::TRANSFER_DST_OPTIMAL, &clear_value, &[vk::ImageSubresourceRange {
aspect_mask: vk::ImageAspectFlags::COLOR,
base_mip_level: 0,
level_count: vk::REMAINING_MIP_LEVELS,
base_array_layer: 0,
layer_count: vk::REMAINING_ARRAY_LAYERS,
}]);

if texture.format_ != graphics_hardware_interface::Formats::Depth32 {
let clear_value = match clear_value {
graphics_hardware_interface::ClearValue::None => vk::ClearColorValue{ float32: [0.0, 0.0, 0.0, 0.0] },
graphics_hardware_interface::ClearValue::Color(color) => vk::ClearColorValue{ float32: [color.r, color.g, color.b, color.a] },
graphics_hardware_interface::ClearValue::Depth(depth) => vk::ClearColorValue{ float32: [*depth, 0.0, 0.0, 0.0] },
graphics_hardware_interface::ClearValue::Integer(r, g, b, a) => vk::ClearColorValue{ uint32: [*r, *g, *b, *a] },
};

unsafe {
self.ghi.device.cmd_clear_color_image(self.get_command_buffer().command_buffer, texture.image, vk::ImageLayout::TRANSFER_DST_OPTIMAL, &clear_value, &[vk::ImageSubresourceRange {
aspect_mask: vk::ImageAspectFlags::COLOR,
base_mip_level: 0,
level_count: vk::REMAINING_MIP_LEVELS,
base_array_layer: 0,
layer_count: vk::REMAINING_ARRAY_LAYERS,
}]);
}
} else {
let clear_value = match clear_value {
graphics_hardware_interface::ClearValue::None => vk::ClearDepthStencilValue{ depth: 0.0, stencil: 0 },
graphics_hardware_interface::ClearValue::Color(_) => panic!("Color clear value for depth texture"),
graphics_hardware_interface::ClearValue::Depth(depth) => vk::ClearDepthStencilValue{ depth: *depth, stencil: 0 },
graphics_hardware_interface::ClearValue::Integer(_, _, _, _) => panic!("Integer clear value for depth texture"),
};

unsafe {
self.ghi.device.cmd_clear_depth_stencil_image(self.get_command_buffer().command_buffer, texture.image, vk::ImageLayout::TRANSFER_DST_OPTIMAL, &clear_value, &[vk::ImageSubresourceRange {
aspect_mask: vk::ImageAspectFlags::DEPTH,
base_mip_level: 0,
level_count: vk::REMAINING_MIP_LEVELS,
base_array_layer: 0,
layer_count: vk::REMAINING_ARRAY_LAYERS,
}]);
}
}
}
}
Expand Down
70 changes: 66 additions & 4 deletions src/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,72 @@ pub fn projection_matrix(fov: f32, aspect_ratio: f32, near_plane: f32, far_plane
}

pub fn orthographic_matrix(width: f32, height: f32, near_plane: f32, far_plane: f32) -> maths_rs::Mat4f {
let near_minus_far = near_plane - far_plane;
maths_rs::Mat4f::from((
maths_rs::Vec4f::from((2f32 / width, 0f32, 0f32, 0f32)),
maths_rs::Vec4f::from((0f32, 2f32 / height, 0f32, 0f32)),
maths_rs::Vec4f::from((0f32, 0f32, 2f32 / (far_plane - near_plane), 0f32)),
maths_rs::Vec4f::from((0f32, 0f32, -((far_plane + near_plane) / (far_plane - near_plane)), 1f32)),
maths_rs::Vec4f::from((2f32 / width, 0f32, 0f32, 0f32 )),
maths_rs::Vec4f::from((0f32, 2f32 / height, 0f32, 0f32 )),
maths_rs::Vec4f::from((0f32, 0f32, 1f32 / near_minus_far, near_plane / near_minus_far)),
maths_rs::Vec4f::from((0f32, 0f32, 0f32, 1f32 )),
))
}

pub fn from_normal(normal: crate::Vector3) -> maths_rs::Mat4f {
let x_basis;
let y_basis;
let z_basis = normal;

if maths_rs::dot(normal, crate::Vector3::new(0f32, 1f32, 0f32)).abs() < 0.99f32 {
// If not colinear
x_basis = maths_rs::normalize(maths_rs::cross(crate::Vector3::new(0f32, 1f32, 0f32), maths_rs::normalize(normal)));
y_basis = maths_rs::normalize(maths_rs::cross(maths_rs::normalize(normal), x_basis));
} else {
// If colinear
x_basis = maths_rs::normalize(maths_rs::cross(maths_rs::normalize(normal), crate::Vector3::new(0f32, 0f32, 1f32)));
y_basis = maths_rs::normalize(maths_rs::cross(x_basis, maths_rs::normalize(normal)));
}

maths_rs::Mat4f::from((
maths_rs::Vec4f::from((x_basis, 0f32)),
maths_rs::Vec4f::from((y_basis, 0f32)),
maths_rs::Vec4f::from((z_basis, 0f32)),
maths_rs::Vec4f::from((0f32, 0f32, 0f32, 1f32)),
))
}

#[cfg(test)]
mod tests {
#[test]
fn test_from_normal() {
let value = super::from_normal(crate::Vector3::new(0f32, 0f32, 1f32));
assert_eq!(value, maths_rs::Mat4f::from((
maths_rs::Vec4f::from((1f32, 0f32, 0f32, 0f32)),
maths_rs::Vec4f::from((0f32, 1f32, 0f32, 0f32)),
maths_rs::Vec4f::from((0f32, 0f32, 1f32, 0f32)),
maths_rs::Vec4f::from((0f32, 0f32, 0f32, 1f32)),
)));

let value = super::from_normal(crate::Vector3::new(0f32, 1f32, 0f32));
assert_eq!(value, maths_rs::Mat4f::from((
maths_rs::Vec4f::from((1f32, 0f32, 0f32, 0f32)),
maths_rs::Vec4f::from((0f32, 0f32, 1f32, 0f32)),
maths_rs::Vec4f::from((0f32, 1f32, 0f32, 0f32)),
maths_rs::Vec4f::from((0f32, 0f32, 0f32, 1f32)),
)));

let value = super::from_normal(crate::Vector3::new(1f32, 0f32, 0f32));
assert_eq!(value, maths_rs::Mat4f::from((
maths_rs::Vec4f::from((0f32, 0f32, -1f32, 0f32)),
maths_rs::Vec4f::from((0f32, 1f32, 0f32, 0f32)),
maths_rs::Vec4f::from((1f32, 0f32, 0f32, 0f32)),
maths_rs::Vec4f::from((0f32, 0f32, 0f32, 1f32)),
)));

let value = super::from_normal(crate::Vector3::new(-1f32, 0f32, 0f32));
assert_eq!(value, maths_rs::Mat4f::from((
maths_rs::Vec4f::from((0f32, 0f32, 1f32, 0f32)),
maths_rs::Vec4f::from((0f32, 1f32, 0f32, 0f32)),
maths_rs::Vec4f::from((-1f32, 0f32, 0f32, 0f32)),
maths_rs::Vec4f::from((0f32, 0f32, 0f32, 1f32)),
)));
}
}
2 changes: 1 addition & 1 deletion src/rendering/aces_tonemap_render_pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl AcesToneMapPass {
ghi::DescriptorWrite::image(result_binding, result_image, ghi::Layouts::General),
]);

let tone_mapping_shader = ghi.create_shader(ghi::ShaderSource::GLSL(TONE_MAPPING_SHADER.to_string()), ghi::ShaderTypes::Compute, &[
let tone_mapping_shader = ghi.create_shader(Some("ACES Tone Mapping Compute Shader"), ghi::ShaderSource::GLSL(TONE_MAPPING_SHADER.to_string()), ghi::ShaderTypes::Compute, &[
ghi::ShaderBindingDescriptor::new(0, 0, ghi::AccessPolicies::READ),
ghi::ShaderBindingDescriptor::new(0, 1, ghi::AccessPolicies::WRITE),
]);
Expand Down
19 changes: 0 additions & 19 deletions src/rendering/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ pub struct Renderer {
window_system: EntityHandle<window_system::WindowSystem>,

visibility_render_model: EntityHandle<VisibilityWorldRenderDomain>,
shadow_render_pass: EntityHandle<ShadowRenderingPass>,
ui_render_model: EntityHandle<UIRenderModel>,
tonemap_render_model: EntityHandle<AcesToneMapPass>,
}
Expand All @@ -38,18 +37,6 @@ impl Renderer {

let visibility_render_model: EntityHandle<VisibilityWorldRenderDomain> = core::spawn(VisibilityWorldRenderDomain::new(listener, ghi_instance.clone(), resource_manager_handle));

let shadow_render_pass = {
let mut ghi = ghi_instance.write().unwrap();
core::spawn(ShadowRenderingPass::new(ghi.deref_mut(), visibility_render_model.read_sync().deref()))
};

{
let mut ghi = ghi_instance.write().unwrap();
let mut vis_rp = visibility_render_model.write_sync();
let srp = shadow_render_pass.read_sync();
vis_rp.write_shadow_descriptor(ghi.deref_mut(), srp.get_shadow_map_image());
}

let ui_render_model = core::spawn(UIRenderModel::new_as_system());

let render_command_buffer;
Expand Down Expand Up @@ -86,7 +73,6 @@ impl Renderer {
window_system: window_system_handle,

visibility_render_model,
shadow_render_pass,
ui_render_model,
tonemap_render_model,
}
Expand All @@ -112,11 +98,6 @@ impl Renderer {
let mut vis_rp = vis_rp.write_sync();
vis_rp.render_a(ghi.deref(), command_buffer_recording.as_mut());

self.shadow_render_pass.map(|shadow_rp| {
let shadow_rp = shadow_rp.write_sync();
shadow_rp.render(command_buffer_recording.as_mut(), vis_rp.deref());
});

vis_rp.render_b(ghi.deref(), command_buffer_recording.as_mut());
});

Expand Down
Loading

0 comments on commit f8b6a90

Please sign in to comment.