Skip to content

Commit

Permalink
Added normal mapping.
Browse files Browse the repository at this point in the history
  • Loading branch information
facundo-villa committed Apr 16, 2024
1 parent 38d43fa commit 33d0285
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 24 deletions.
46 changes: 46 additions & 0 deletions ghi/src/graphics_hardware_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,29 @@ pub enum Formats {
RGBA16(Encodings),
}

pub trait Size {
fn size(&self) -> usize;
}

impl Size for Formats {
fn size(&self) -> usize {
match self {
Formats::RGBu10u10u11 => 4,
Formats::BGRAu8 => 4,
Formats::Depth32 => 4,
Formats::U32 => 4,
Formats::R8(_) => 1,
Formats::R16(_) => 2,
Formats::R32(_) => 4,
Formats::RG16(_) => 4,
Formats::RGB8(_) => 3,
Formats::RGB16(_) => 6,
Formats::RGBA8(_) => 4,
Formats::RGBA16(_) => 8,
}
}
}

#[derive(Clone, Copy, Debug)]
pub enum CompressionSchemes {
BC7,
Expand Down Expand Up @@ -942,6 +965,16 @@ impl DescriptorSetBindingTemplate {
}
}

pub fn new_array(binding: u32, descriptor_type: DescriptorType, stages: Stages, count: u32) -> Self {
Self {
binding,
descriptor_type,
descriptor_count: count,
stages,
immutable_samplers: None,
}
}

pub fn new_with_immutable_samplers(binding: u32, stages: Stages, samplers: Option<Vec<SamplerHandle>>) -> Self {
Self {
binding,
Expand Down Expand Up @@ -1049,6 +1082,19 @@ impl DescriptorWrite {
}
}

pub fn combined_image_sampler_array(binding_handle: DescriptorSetBindingHandle, image_handle: ImageHandle, sampler_handle: SamplerHandle, layout: Layouts, index: u32) -> DescriptorWrite {
DescriptorWrite {
binding_handle,
array_element: index,
descriptor: Descriptor::CombinedImageSampler {
image_handle: image_handle,
sampler_handle,
layout,
},
frame_offset: None,
}
}

pub fn acceleration_structure(binding_handle: DescriptorSetBindingHandle, acceleration_structure_handle: TopLevelAccelerationStructureHandle) -> DescriptorWrite {
DescriptorWrite {
binding_handle,
Expand Down
24 changes: 17 additions & 7 deletions ghi/src/vulkan_ghi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{borrow::Cow, collections::HashMap, mem::align_of};
use ash::vk::{self, Handle as _};
use utils::{partition, Extent};

use crate::{graphics_hardware_interface, render_debugger::RenderDebugger, shader_compilation, window};
use crate::{graphics_hardware_interface, render_debugger::RenderDebugger, shader_compilation, window, CompressionSchemes, Size};

#[cfg(test)]
use std::{println as error, println as warn, println as debug};
Expand Down Expand Up @@ -911,7 +911,21 @@ impl graphics_hardware_interface::GraphicsHardwareInterface for VulkanGHI {
}

fn create_image(&mut self, name: Option<&str>, extent: Extent, format: graphics_hardware_interface::Formats, compression: Option<graphics_hardware_interface::CompressionSchemes>, resource_uses: graphics_hardware_interface::Uses, device_accesses: graphics_hardware_interface::DeviceAccesses, use_case: graphics_hardware_interface::UseCases) -> graphics_hardware_interface::ImageHandle {
let size = (extent.width() * extent.height() * extent.depth() * 4) as usize; // TODO. fix this
let size = if let Some(compression) = compression {
let block_size = match compression {
CompressionSchemes::BC7 => {
match format {
graphics_hardware_interface::Formats::RGBA8(_) => { 16usize }
graphics_hardware_interface::Formats::RGBA16(_) => { 16usize }
_ => { panic!("Invalid format for BC7 compression"); }
}
}
};

(((extent.width() + 3) / 4) * ((extent.height() + 3) / 4)) as usize * block_size
} else {
(extent.width() * extent.height() * extent.depth()) as usize * format.size()
};

let texture_handle = graphics_hardware_interface::ImageHandle(self.images.len() as u64);

Expand All @@ -922,7 +936,7 @@ impl graphics_hardware_interface::GraphicsHardwareInterface for VulkanGHI {
for _ in 0..(match use_case { graphics_hardware_interface::UseCases::DYNAMIC => { self.frames } graphics_hardware_interface::UseCases::STATIC => { 1 }}) {
let resource_uses = resource_uses | if device_accesses.contains(graphics_hardware_interface::DeviceAccesses::CpuWrite) { graphics_hardware_interface::Uses::TransferDestination } else { graphics_hardware_interface::Uses::empty() };

let texture_creation_result = self.create_vulkan_texture(name, extent, format, compression, resource_uses | graphics_hardware_interface::Uses::TransferSource, device_accesses, graphics_hardware_interface::AccessPolicies::WRITE, 1);
let texture_creation_result = self.create_vulkan_texture(name, extent, format, compression, resource_uses | graphics_hardware_interface::Uses::TransferSource, device_accesses, graphics_hardware_interface::AccessPolicies::WRITE, 1); // TODO: check if image is being created as linear layout

let (allocation_handle, _) = self.create_allocation_internal(texture_creation_result.size, device_accesses);

Expand Down Expand Up @@ -1833,10 +1847,6 @@ impl Into<vk::Format> for graphics_hardware_interface::DataTypes {
}
}

trait Size {
fn size(&self) -> usize;
}

impl Size for graphics_hardware_interface::DataTypes {
fn size(&self) -> usize {
match self {
Expand Down
26 changes: 22 additions & 4 deletions resource_management/src/asset/image_asset_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ impl AssetHandler for ImageAssetHandler {
let (image, data) = self.produce(&ImageDescription {
format,
extent,
semantic: if url.contains("Normal") { Semantic::Normal } else { Semantic::Other }
}, &buffer);

let resource_document = GenericResourceSerialization::new(url, image);
Expand All @@ -96,7 +97,9 @@ impl AssetHandler for ImageAssetHandler {

impl ImageAssetHandler {
fn produce(&self, description: &ImageDescription, buffer: &[u8]) -> (Image, Box<[u8]>) {
let ImageDescription { format, extent } = description;
let ImageDescription { format, extent, semantic } = description;

let compress = *semantic != Semantic::Normal;

let (data, format, compression) = match format {
Formats::RGB8 => {
Expand All @@ -112,7 +115,7 @@ impl ImageAssetHandler {
}
}

if true { // TODO: make this a setting
if compress { // TODO: make this a setting
let rgba_surface = intel_tex_2::RgbaSurface {
data: &buf,
width: extent.width(),
Expand Down Expand Up @@ -140,7 +143,7 @@ impl ImageAssetHandler {
}
}

if true {
if compress {
let rgba_surface = intel_tex_2::RgbaSurface {
data: &buf,
width: extent.width(),
Expand All @@ -150,7 +153,7 @@ impl ImageAssetHandler {

let settings = intel_tex_2::bc7::opaque_ultra_fast_settings();

(intel_tex_2::bc7::compress_blocks(&settings, &rgba_surface), Formats::RGBA16, Some(CompressionSchemes::BC7))
(intel_tex_2::bc7::compress_blocks(&settings, &rgba_surface), Formats::RGBA8, Some(CompressionSchemes::BC7))
} else {
(buf, Formats::RGBA16, None)
}
Expand All @@ -169,9 +172,24 @@ impl ImageAssetHandler {
}
}

#[derive(Debug, PartialEq, Eq)]
pub enum Semantic {
Albedo,
Normal,
Metallic,
Roughness,
Emissive,
Height,
Opacity,
Displacement,
AO,
Other,
}

pub struct ImageDescription {
pub format: Formats,
pub extent: Extent,
pub semantic: Semantic,
}

impl Description for ImageDescription {
Expand Down
1 change: 1 addition & 0 deletions resource_management/src/asset/mesh_asset_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ impl AssetHandler for MeshAssetHandler {
let image_description = crate::asset::image_asset_handler::ImageDescription {
format,
extent,
semantic: if url.contains("Normal") { crate::asset::image_asset_handler::Semantic::Normal } else { crate::asset::image_asset_handler::Semantic::Other },
};

let resource: TypedResource<Image> = asset_manager.produce(&url, "image/png", &image_description, &image.pixels).await;
Expand Down
35 changes: 24 additions & 11 deletions src/rendering/visibility_model/render_domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ pub struct VisibilityWorldRenderDomain {

vertex_positions_buffer: ghi::BaseBufferHandle,
vertex_normals_buffer: ghi::BaseBufferHandle,
vertex_tangents_buffer: ghi::BaseBufferHandle,
// vertex_tangents_buffer: ghi::BaseBufferHandle,
vertex_uvs_buffer: ghi::BaseBufferHandle,

/// Indices laid out as a triangle list
Expand Down Expand Up @@ -149,6 +149,8 @@ pub struct VisibilityWorldRenderDomain {
shadow_map_binding: ghi::DescriptorSetBindingHandle,

lights: Vec<LightData>,

texture_count: u32,
}

impl VisibilityWorldRenderDomain {
Expand All @@ -160,7 +162,7 @@ impl VisibilityWorldRenderDomain {
let pipeline_layout_handle;
let vertex_positions_buffer_handle;
let vertex_normals_buffer_handle;
let vertex_tangents_buffer_handle;
// let vertex_tangents_buffer_handle;
let vertex_uv_buffer_handle;
let triangle_indices_buffer_handle;
let vertex_indices_buffer_handle;
Expand Down Expand Up @@ -207,7 +209,7 @@ impl VisibilityWorldRenderDomain {
ghi::DescriptorSetBindingTemplate::new(6, ghi::DescriptorType::StorageBuffer, ghi::Stages::MESH | ghi::Stages::COMPUTE),
ghi::DescriptorSetBindingTemplate::new(7, ghi::DescriptorType::StorageBuffer, ghi::Stages::MESH | ghi::Stages::COMPUTE),
ghi::DescriptorSetBindingTemplate::new(8, ghi::DescriptorType::StorageBuffer, ghi::Stages::MESH | ghi::Stages::COMPUTE),
ghi::DescriptorSetBindingTemplate::new(9, ghi::DescriptorType::CombinedImageSampler, ghi::Stages::COMPUTE),
ghi::DescriptorSetBindingTemplate::new_array(9, ghi::DescriptorType::CombinedImageSampler, ghi::Stages::COMPUTE, 16),
];

descriptor_set_layout = ghi_instance.create_descriptor_set_template(Some("Base Set Layout"), &bindings);
Expand All @@ -218,7 +220,7 @@ impl VisibilityWorldRenderDomain {
let meshes_data_binding = ghi_instance.create_descriptor_binding(descriptor_set, &bindings[1]);
let vertex_positions_binding = ghi_instance.create_descriptor_binding(descriptor_set, &bindings[2]);
let vertex_normals_binding = ghi_instance.create_descriptor_binding(descriptor_set, &bindings[3]);
let vertex_tangents_binding = ghi_instance.create_descriptor_binding(descriptor_set, &bindings[4]);
// let vertex_tangents_binding = ghi_instance.create_descriptor_binding(descriptor_set, &bindings[4]);
let vertex_uv_binding = ghi_instance.create_descriptor_binding(descriptor_set, &bindings[5]);
let vertex_indices_binding = ghi_instance.create_descriptor_binding(descriptor_set, &bindings[6]);
let primitive_indices_binding = ghi_instance.create_descriptor_binding(descriptor_set, &bindings[7]);
Expand All @@ -229,7 +231,7 @@ impl VisibilityWorldRenderDomain {

vertex_positions_buffer_handle = ghi_instance.create_buffer(Some("Visibility Vertex Positions Buffer"), std::mem::size_of::<[[f32; 3]; MAX_VERTICES]>(), ghi::Uses::Vertex | ghi::Uses::AccelerationStructureBuild | ghi::Uses::Storage, ghi::DeviceAccesses::CpuWrite | ghi::DeviceAccesses::GpuRead, ghi::UseCases::STATIC);
vertex_normals_buffer_handle = ghi_instance.create_buffer(Some("Visibility Vertex Normals Buffer"), std::mem::size_of::<[[f32; 3]; MAX_VERTICES]>(), ghi::Uses::Vertex | ghi::Uses::AccelerationStructureBuild | ghi::Uses::Storage, ghi::DeviceAccesses::CpuWrite | ghi::DeviceAccesses::GpuRead, ghi::UseCases::STATIC);
vertex_tangents_buffer_handle = ghi_instance.create_buffer(Some("Visibility Vertex Tangents Buffer"), std::mem::size_of::<[[f32; 3]; MAX_VERTICES]>(), ghi::Uses::Vertex | ghi::Uses::AccelerationStructureBuild | ghi::Uses::Storage, ghi::DeviceAccesses::CpuWrite | ghi::DeviceAccesses::GpuRead, ghi::UseCases::STATIC);
// vertex_tangents_buffer_handle = ghi_instance.create_buffer(Some("Visibility Vertex Tangents Buffer"), std::mem::size_of::<[[f32; 3]; MAX_VERTICES]>(), ghi::Uses::Vertex | ghi::Uses::AccelerationStructureBuild | ghi::Uses::Storage, ghi::DeviceAccesses::CpuWrite | ghi::DeviceAccesses::GpuRead, ghi::UseCases::STATIC);
vertex_uv_buffer_handle = ghi_instance.create_buffer(Some("Visibility Vertex UV Buffer"), std::mem::size_of::<[[f32; 2]; MAX_VERTICES]>(), ghi::Uses::Vertex | ghi::Uses::AccelerationStructureBuild | ghi::Uses::Storage, ghi::DeviceAccesses::CpuWrite | ghi::DeviceAccesses::GpuRead, ghi::UseCases::STATIC);

triangle_indices_buffer_handle = ghi_instance.create_buffer(Some("Visibility Triangle Indices Buffer"), std::mem::size_of::<[[u16; 3]; MAX_TRIANGLES]>(), ghi::Uses::Index | ghi::Uses::AccelerationStructureBuild | ghi::Uses::Storage, ghi::DeviceAccesses::CpuWrite | ghi::DeviceAccesses::GpuRead, ghi::UseCases::STATIC);
Expand All @@ -250,7 +252,7 @@ impl VisibilityWorldRenderDomain {
ghi::DescriptorWrite::buffer(meshes_data_binding, meshes_data_buffer),
ghi::DescriptorWrite::buffer(vertex_positions_binding, vertex_positions_buffer_handle),
ghi::DescriptorWrite::buffer(vertex_normals_binding, vertex_normals_buffer_handle),
ghi::DescriptorWrite::buffer(vertex_tangents_binding, vertex_tangents_buffer_handle),
// ghi::DescriptorWrite::buffer(vertex_tangents_binding, vertex_tangents_buffer_handle),
ghi::DescriptorWrite::buffer(vertex_uv_binding, vertex_uv_buffer_handle),
ghi::DescriptorWrite::buffer(vertex_indices_binding, vertex_indices_buffer_handle),
ghi::DescriptorWrite::buffer(primitive_indices_binding, primitive_indices_buffer_handle),
Expand Down Expand Up @@ -393,7 +395,7 @@ impl VisibilityWorldRenderDomain {

vertex_positions_buffer: vertex_positions_buffer_handle,
vertex_normals_buffer: vertex_normals_buffer_handle,
vertex_tangents_buffer: vertex_tangents_buffer_handle,
// vertex_tangents_buffer: vertex_tangents_buffer_handle,
vertex_uvs_buffer: vertex_uv_buffer_handle,

triangle_indices_buffer: triangle_indices_buffer_handle,
Expand Down Expand Up @@ -430,6 +432,8 @@ impl VisibilityWorldRenderDomain {
shadow_map_binding,

lights: Vec::new(),

texture_count: 0,
}
})
.listen_to::<camera::Camera>()
Expand All @@ -438,7 +442,7 @@ impl VisibilityWorldRenderDomain {
.listen_to::<dyn mesh::RenderEntity>()
}

fn load_image<'a>(resource: &impl resource_management::ResourceStore<'a>, ghi: &mut dyn ghi::GraphicsHardwareInterface, pending_texture_loads: &mut Vec<ImageHandle>, textures_binding: ghi::DescriptorSetBindingHandle) {
fn load_image<'a>(resource: &impl resource_management::ResourceStore<'a>, ghi: &mut dyn ghi::GraphicsHardwareInterface, pending_texture_loads: &mut Vec<ImageHandle>, textures_binding: ghi::DescriptorSetBindingHandle, texture_count: &mut u32) {
if let Some(texture) = resource.resource().downcast_ref::<Image>() {
let compression = texture.compression.map(|compression| {
match compression {
Expand Down Expand Up @@ -486,7 +490,9 @@ impl VisibilityWorldRenderDomain {

let sampler = ghi.create_sampler(ghi::FilteringModes::Linear, ghi::SamplingReductionModes::WeightedAverage, ghi::FilteringModes::Linear, ghi::SamplerAddressingModes::Clamp, None, 0f32, 0f32); // TODO: use actual sampler

ghi.write(&[ghi::DescriptorWrite::combined_image_sampler(textures_binding, image, sampler, ghi::Layouts::Read),]);
ghi.write(&[ghi::DescriptorWrite::combined_image_sampler_array(textures_binding, image, sampler, ghi::Layouts::Read, *texture_count),]);

*texture_count += 1;

pending_texture_loads.push(image);
}
Expand Down Expand Up @@ -712,7 +718,7 @@ impl VisibilityWorldRenderDomain {
for parameter in &material.parameters {
match &parameter.value {
resource_management::types::Value::Image(image) => {
Self::load_image(image, ghi.deref_mut(), &mut self.pending_texture_loads, self.textures_binding);
Self::load_image(image, ghi.deref_mut(), &mut self.pending_texture_loads, self.textures_binding, &mut self.texture_count);
}
_ => {}
}
Expand All @@ -724,7 +730,9 @@ impl VisibilityWorldRenderDomain {

let material_data = unsafe { material_data.as_mut().unwrap() };

material_data.textures[0] = 0; // TODO: make dynamic based on supplied textures
for (i, e) in material.parameters.iter().enumerate() {
material_data.textures[i] = i as u32; // TODO: make dynamic based on supplied textures
}

match material.model.name.as_str() {
"Visibility" => {
Expand Down Expand Up @@ -958,6 +966,7 @@ impl EntitySubscriber<dyn mesh::RenderEntity> for VisibilityWorldRenderDomain {

let mut vertex_positions_buffer = ghi.get_splitter(self.vertex_positions_buffer, self.visibility_info.vertex_count as usize * std::mem::size_of::<Vector3>());
let mut vertex_normals_buffer = ghi.get_splitter(self.vertex_normals_buffer, self.visibility_info.vertex_count as usize * std::mem::size_of::<Vector3>());
// let mut vertex_tangents_buffer = ghi.get_splitter(self.vertex_tangents_buffer, self.visibility_info.vertex_count as usize * std::mem::size_of::<Vector3>());
let mut vertex_uv_buffer = ghi.get_splitter(self.vertex_uvs_buffer, self.visibility_info.vertex_count as usize * std::mem::size_of::<Vector2>());
let mut triangle_indices_buffer = ghi.get_splitter(self.vertex_indices_buffer, self.visibility_info.triangle_count as usize * 3 * std::mem::size_of::<u16>());
let mut vertex_indices_buffer = ghi.get_splitter(self.vertex_indices_buffer, self.visibility_info.vertex_count as usize * std::mem::size_of::<u16>());
Expand All @@ -969,6 +978,7 @@ impl EntitySubscriber<dyn mesh::RenderEntity> for VisibilityWorldRenderDomain {

let total_vertex_positions_count;
let total_vertex_normals_count;
// let total_vertex_tangent_count;
let total_vertex_uv_count;
let total_triangle_indices_count;
let total_vertex_indices_count;
Expand All @@ -980,6 +990,7 @@ impl EntitySubscriber<dyn mesh::RenderEntity> for VisibilityWorldRenderDomain {

total_vertex_positions_count = mesh_resource.sub_meshes.iter().map(|sm| sm.primitives.iter().map(|p| p.vertex_count).sum::<u32>()).sum::<u32>();
total_vertex_normals_count = mesh_resource.sub_meshes.iter().map(|sm| sm.primitives.iter().map(|p| p.vertex_count).sum::<u32>()).sum::<u32>();
// total_vertex_tangent_count = mesh_resource.sub_meshes.iter().map(|sm| sm.primitives.iter().map(|p| p.vertex_count).sum::<u32>()).sum::<u32>();
total_vertex_uv_count = mesh_resource.sub_meshes.iter().map(|sm| sm.primitives.iter().map(|p| p.vertex_count).sum::<u32>()).sum::<u32>();
total_triangle_indices_count = mesh_resource.index_streams.iter().find(|is| is.stream_type == IndexStreamTypes::Triangles).unwrap().count;
total_vertex_indices_count = mesh_resource.index_streams.iter().find(|is| is.stream_type == IndexStreamTypes::Vertices).unwrap().count;
Expand All @@ -988,6 +999,7 @@ impl EntitySubscriber<dyn mesh::RenderEntity> for VisibilityWorldRenderDomain {

let vertex_positions_buffer = vertex_positions_buffer.take(total_vertex_positions_count as usize * std::mem::size_of::<Vector3>());
let vertex_normals_buffer = vertex_normals_buffer.take(total_vertex_normals_count as usize * std::mem::size_of::<Vector3>());
// let vertex_tangents_buffer = vertex_tangents_buffer.take(total_vertex_tangent_count as usize * std::mem::size_of::<Vector3>());
let vertex_uv_buffer = vertex_uv_buffer.take(total_vertex_uv_count as usize * std::mem::size_of::<Vector2>());
let triangle_indices_buffer = triangle_indices_buffer.take(total_triangle_indices_count as usize * std::mem::size_of::<u16>());
let vertex_indices_buffer = vertex_indices_buffer.take(total_vertex_indices_count as usize * std::mem::size_of::<u16>());
Expand All @@ -997,6 +1009,7 @@ impl EntitySubscriber<dyn mesh::RenderEntity> for VisibilityWorldRenderDomain {
let streams = vec![
resource_management::Stream::new("Vertex.Position", vertex_positions_buffer),
resource_management::Stream::new("Vertex.Normal", vertex_normals_buffer),
// resource_management::Stream::new("Vertex.Tangent", vertex_tangents_buffer),
resource_management::Stream::new("Vertex.UV", vertex_uv_buffer),
resource_management::Stream::new("TriangleIndices", triangle_indices_buffer),
resource_management::Stream::new("VertexIndices", vertex_indices_buffer),
Expand Down
Loading

0 comments on commit 33d0285

Please sign in to comment.