Skip to content

Commit

Permalink
Support rendering of arbitrary meshes.
Browse files Browse the repository at this point in the history
  • Loading branch information
facundo-villa committed Nov 9, 2023
1 parent 58225e9 commit 6b5fefe
Show file tree
Hide file tree
Showing 9 changed files with 230 additions and 119 deletions.
143 changes: 101 additions & 42 deletions src/render_domain.rs

Large diffs are not rendered by default.

65 changes: 40 additions & 25 deletions src/rendering/visibility_shader_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,32 @@ impl VisibilityShaderGenerator {
fn fragment_transform(&self, material: &json::JsonValue, shader_node: &lexer::Node) -> String {
let mut string = shader_generator::generate_glsl_header_block(&json::object! { "glsl": { "version": "450" }, "stage": "Compute" });

string.push_str("layout(set=0,binding=5) uniform sampler2D textures[1];
string.push_str("
struct Mesh {
mat4 model;
uint material_id;
uint32_t base_vertex_index;
};
layout(set=0, binding=1, scalar) buffer readonly MeshBuffer {
Mesh meshes[];
};
layout(set=0, binding=2, scalar) buffer readonly Positions {
vec3 positions[];
};
layout(set=0, binding=3, scalar) buffer readonly Normals {
vec3 normals[];
};
layout(set=0, binding=4, scalar) buffer readonly VertexIndices {
uint16_t vertex_indices[];
};
layout(set=0, binding=5, scalar) buffer readonly PrimitiveIndeces {
uint8_t primitive_indeces[];
};
struct Meshlet {
uint32_t instance_index;
Expand All @@ -116,15 +141,20 @@ layout(set=0,binding=6,scalar) buffer readonly MeshletsBuffer {
Meshlet meshlets[];
};
layout(set=0,binding=7) uniform sampler2D textures[1];
layout(set=1,binding=0,scalar) buffer MaterialCount {
uint material_count[];
};
layout(set=1,binding=1,scalar) buffer MaterialOffset {
uint material_offset[];
};
layout(set=1,binding=4,scalar) buffer PixelMapping {
u16vec2 pixel_mapping[];
};
layout(set=1, binding=6, r32ui) uniform readonly uimage2D triangle_index;
layout(set=1, binding=7, r32ui) uniform readonly uimage2D instance_id;
layout(set=2, binding=0, rgba16) uniform image2D out_albedo;
Expand Down Expand Up @@ -177,27 +207,6 @@ BarycentricDeriv CalcFullBary(vec4 pt0, vec4 pt1, vec4 pt2, vec2 pixelNdc, vec2
return ret;
}
struct Mesh {
mat4 model;
uint material_id;
};
layout(set=2, binding=1, scalar) buffer readonly MeshBuffer {
Mesh meshes[];
};
layout(set=2, binding=2, scalar) buffer readonly Positions {
vec3 positions[];
};
layout(set=2, binding=3, scalar) buffer readonly Normals {
vec3 normals[];
};
layout(set=2, binding=4, scalar) buffer readonly Indeces {
uint8_t indeces[];
};
const float PI = 3.14159265359;
float DistributionGGX(vec3 N, vec3 H, float roughness) {
Expand Down Expand Up @@ -338,10 +347,16 @@ void main() {
Material material = materials[pc.material_id];
Meshlet meshlet = meshlets[BE_MESHLET_INDEX];
uint primitive_indices[3] = uint[3](
uint(primitive_indeces[(meshlet.triangle_offset + BE_MESHLET_TRIANGLE_INDEX) * 3 + 0]),
uint(primitive_indeces[(meshlet.triangle_offset + BE_MESHLET_TRIANGLE_INDEX) * 3 + 1]),
uint(primitive_indeces[(meshlet.triangle_offset + BE_MESHLET_TRIANGLE_INDEX) * 3 + 2])
);
uint vertex_indeces[3] = uint[3](
uint(indeces[meshlet.triangle_offset * 3 + BE_MESHLET_TRIANGLE_INDEX * 3 + 0] + meshlet.vertex_offset),
uint(indeces[meshlet.triangle_offset * 3 + BE_MESHLET_TRIANGLE_INDEX * 3 + 1] + meshlet.vertex_offset),
uint(indeces[meshlet.triangle_offset * 3 + BE_MESHLET_TRIANGLE_INDEX * 3 + 2] + meshlet.vertex_offset)
mesh.base_vertex_index + uint(vertex_indices[meshlet.vertex_offset + primitive_indices[0]]),
mesh.base_vertex_index + uint(vertex_indices[meshlet.vertex_offset + primitive_indices[1]]),
mesh.base_vertex_index + uint(vertex_indices[meshlet.vertex_offset + primitive_indices[2]])
);
vec4 vertex_positions[3] = vec4[3](
Expand Down
32 changes: 18 additions & 14 deletions src/rendering/vulkan_render_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,11 @@ impl render_system::RenderSystem for VulkanRenderSystem {
let mut error_string = String::new();

for (error_line_index, error) in errors {
error_string.push_str(&format!("{} Error: {}\n", shader_text.lines().nth(error_line_index).unwrap(), error));
let previous_line = shader_text.lines().nth(error_line_index - 1).unwrap_or("");
let current_line = shader_text.lines().nth(error_line_index).unwrap_or("");
let next_line = shader_text.lines().nth(error_line_index + 1).unwrap_or("");

error_string.push_str(&format!("{}\n{} Error: {}\n{}\n", previous_line, current_line, error, next_line));
}

error!("Error compiling shader:\n{}", error_string);
Expand Down Expand Up @@ -3098,19 +3102,19 @@ impl render_system::CommandBufferRecording for VulkanCommandBufferRecording<'_>

buffer_memory_barriers.push(buffer_memory_barrier);

// let memory_barrier = if let Some(source) = self.states.get(&consumption.handle) {
// vk::MemoryBarrier2::default()
// .src_stage_mask(source.stage)
// .src_access_mask(source.access)
// } else {
// vk::MemoryBarrier2::default()
// .src_stage_mask(vk::PipelineStageFlags2::empty())
// .src_access_mask(vk::AccessFlags2KHR::empty())
// }
// .dst_stage_mask(new_stage_mask)
// .dst_access_mask(new_access_mask);

// memory_barriers.push(memory_barrier);
let memory_barrier = if let Some(source) = self.states.get(&consumption.handle) {
vk::MemoryBarrier2::default()
.src_stage_mask(source.stage)
.src_access_mask(source.access)
} else {
vk::MemoryBarrier2::default()
.src_stage_mask(vk::PipelineStageFlags2::empty())
.src_access_mask(vk::AccessFlags2KHR::empty())
}
.dst_stage_mask(new_stage_mask)
.dst_access_mask(new_access_mask);

memory_barriers.push(memory_barrier);
},
render_system::Handle::TopLevelAccelerationStructure(_) | render_system::Handle::BottomLevelAccelerationStructure(_)=> {
// let (handle, acceleration_structure) = self.get_top_level_acceleration_structure(handle);
Expand Down
17 changes: 14 additions & 3 deletions src/resource_manager/material_resource_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ impl ResourceHandler for MaterialResourcerHandler {
}
}

fn read(&self, _resource: &Box<dyn std::any::Any>, file: &mut std::fs::File, buffers: &mut [super::Buffer]) {
fn read(&self, _resource: &Box<dyn std::any::Any>, file: &mut std::fs::File, buffers: &mut [super::Stream]) {
file.read_exact(buffers[0].buffer).unwrap();
}

Expand Down Expand Up @@ -191,8 +191,19 @@ impl MaterialResourcerHandler {
// TODO: if shader fails to compile try to generate a failsafe shader

let compilation_artifact = match binary { Ok(binary) => { binary } Err(err) => {
error!("Failed to compile shader: {}", err);
error!("{}", &glsl);
let error_string = err.to_string();
let errors = error_string.lines().filter(|error| error.starts_with("shader_name:")).map(|error| (error.split(':').nth(1).unwrap(), error.split(':').nth(4).unwrap())).map(|(error_line_number_string, error)| (error_line_number_string.trim().parse::<usize>().unwrap(), error.trim())).collect::<Vec<_>>();
let mut error_string = String::new();

for (error_line_index, error) in errors {
let previous_line = glsl.lines().nth(error_line_index - 1).unwrap_or("");
let current_line = glsl.lines().nth(error_line_index).unwrap_or("");
let next_line = glsl.lines().nth(error_line_index + 1).unwrap_or("");

error_string.push_str(&format!("{} Error: {}\n{}\n{}\n", previous_line, current_line, next_line, error));
}

error!("Error compiling shader:\n{}", error_string);
return Some(Err(err.to_string()));
} };

Expand Down
78 changes: 50 additions & 28 deletions src/resource_manager/mesh_resource_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ impl ResourceHandler for MeshResourceHandler {

if let Some(tangents) = reader.read_tangents() {
tangents.for_each(|tangent| tangent.iter().for_each(|m| m.to_le_bytes().iter().for_each(|byte| buffer.push(*byte))));
vertex_components.push(VertexComponent { semantic: VertexSemantics::Tangent, format: "vec3f".to_string(), channel: 2 });
vertex_components.push(VertexComponent { semantic: VertexSemantics::Tangent, format: "vec4f".to_string(), channel: 2 });
}

if let Some(uv) = reader.read_tex_coords(0) {
Expand All @@ -91,27 +91,33 @@ impl ResourceHandler for MeshResourceHandler {

let mut index_streams = Vec::with_capacity(2);

let offset = buffer.len();

{
let index_type = IntegralTypes::U16;

match index_type {
IntegralTypes::U16 => {
optimized_indices.iter().map(|i| *i as u16).for_each(|index| index.to_le_bytes().iter().for_each(|byte| buffer.push(*byte)));
index_streams.push(IndexStream{ data_type: IntegralTypes::U16, stream_type: IndexStreamTypes::Raw, offset, count: optimized_indices.len() as u32 });
}
_ => panic!("Unsupported index type")
}
}

let offset = buffer.len();

let meshlet_stream;

if MESHLETIZE {
let meshlets = meshopt::clusterize::build_meshlets(&optimized_indices, vertex_count, 64, 126);

let offset = buffer.len();

{
let index_type = IntegralTypes::U16;

match index_type {
IntegralTypes::U16 => {
let mut index_count = 0usize;
for meshlet in &meshlets {
index_count += meshlet.vertex_count as usize;
for i in 0..meshlet.vertex_count as usize {
(meshlet.vertices[i] as u16).to_le_bytes().iter().for_each(|byte| buffer.push(*byte));
}
}
index_streams.push(IndexStream{ data_type: IntegralTypes::U16, stream_type: IndexStreamTypes::Raw, offset, count: index_count as u32 });
}
_ => panic!("Unsupported index type")
}
}

let offset = buffer.len();

let mut index_count: usize = 0;

for meshlet in &meshlets {
Expand All @@ -126,7 +132,7 @@ impl ResourceHandler for MeshResourceHandler {

assert_eq!(index_count, optimized_indices.len());

index_streams.push(IndexStream{ data_type: IntegralTypes::U8, stream_type: IndexStreamTypes::Meshlets, offset, count: optimized_indices.len() as u32 });
index_streams.push(IndexStream{ data_type: IntegralTypes::U8, stream_type: IndexStreamTypes::Meshlets, offset, count: index_count as u32 });

let offset = buffer.len();

Expand All @@ -137,6 +143,20 @@ impl ResourceHandler for MeshResourceHandler {
buffer.push(meshlet.triangle_count);
}
} else {
let offset = buffer.len();

{
let index_type = IntegralTypes::U16;

match index_type {
IntegralTypes::U16 => {
optimized_indices.iter().map(|i| *i as u16).for_each(|i| i.to_le_bytes().iter().for_each(|byte| buffer.push(*byte)));
index_streams.push(IndexStream{ data_type: IntegralTypes::U16, stream_type: IndexStreamTypes::Raw, offset, count: optimized_indices.len() as u32 });
}
_ => panic!("Unsupported index type")
}
}

meshlet_stream = None;
}

Expand Down Expand Up @@ -165,11 +185,11 @@ impl ResourceHandler for MeshResourceHandler {
}))]
}

fn read(&self, resource: &Box<dyn std::any::Any>, file: &mut std::fs::File, buffers: &mut [super::Buffer]) {
fn read(&self, resource: &Box<dyn std::any::Any>, file: &mut std::fs::File, buffers: &mut [super::Stream]) {
let mesh: &Mesh = resource.downcast_ref().unwrap();

for buffer in buffers {
match buffer.tag.as_str() {
match buffer.name.as_str() {
"Vertex" => {
file.seek(std::io::SeekFrom::Start(0)).unwrap();
file.read(&mut buffer.buffer[0..(mesh.vertex_count as usize * mesh.vertex_components.size())]).unwrap();
Expand Down Expand Up @@ -213,7 +233,7 @@ impl ResourceHandler for MeshResourceHandler {
file.read(&mut buffer.buffer[0..(meshlet_stream.count as usize * 2)]).unwrap();
}
_ => {
error!("Unknown buffer tag: {}", buffer.tag);
error!("Unknown buffer tag: {}", buffer.name);
}
}
}
Expand Down Expand Up @@ -375,7 +395,7 @@ impl Size for IntegralTypes {

#[cfg(test)]
mod tests {
use crate::{resource_manager::{resource_manager::ResourceManager, Options, OptionResource, Buffer}, Vector3};
use crate::{resource_manager::{resource_manager::ResourceManager, Options, OptionResource, Stream}, Vector3};

use super::*;

Expand Down Expand Up @@ -430,6 +450,8 @@ mod tests {
assert_eq!(mesh.index_streams[0].count, 36);
assert_eq!(mesh.index_streams[0].data_type, IntegralTypes::U16);

let meshlet_stream_info = mesh.meshlet_stream.as_ref().unwrap();

let offset = offset + mesh.index_streams[0].count as usize * mesh.index_streams[0].data_type.size();

assert_eq!(mesh.index_streams[1].stream_type, IndexStreamTypes::Meshlets);
Expand All @@ -452,7 +474,7 @@ mod tests {
"Mesh" => {
options.resources.push(OptionResource {
url: resource.url.clone(),
buffers: vec![Buffer{ buffer: vertex_buffer.as_mut_slice(), tag: "Vertex".to_string() }, Buffer{ buffer: index_buffer.as_mut_slice(), tag: "Indices".to_string() }],
streams: vec![Stream{ buffer: vertex_buffer.as_mut_slice(), name: "Vertex".to_string() }, Stream{ buffer: index_buffer.as_mut_slice(), name: "Indices".to_string() }],
});
}
_ => {}
Expand Down Expand Up @@ -621,7 +643,7 @@ mod tests {
"Mesh" => {
options.resources.push(OptionResource {
url: resource.url.clone(),
buffers: vec![Buffer{ buffer: vertex_buffer.as_mut_slice(), tag: "Vertex".to_string() }, Buffer{ buffer: index_buffer.as_mut_slice(), tag: "Indices".to_string() }],
streams: vec![Stream{ buffer: vertex_buffer.as_mut_slice(), name: "Vertex".to_string() }, Stream{ buffer: index_buffer.as_mut_slice(), name: "Indices".to_string() }],
});
}
_ => {}
Expand Down Expand Up @@ -684,10 +706,10 @@ mod tests {
"Mesh" => {
options.resources.push(OptionResource {
url: resource.url.clone(),
buffers: vec![
Buffer{ buffer: vertex_positions_buffer.as_mut_slice(), tag: "Vertex.Position".to_string() },
Buffer{ buffer: vertex_normals_buffer.as_mut_slice(), tag: "Vertex.Normal".to_string() },
Buffer{ buffer: index_buffer.as_mut_slice(), tag: "Indices".to_string() }
streams: vec![
Stream{ buffer: vertex_positions_buffer.as_mut_slice(), name: "Vertex.Position".to_string() },
Stream{ buffer: vertex_normals_buffer.as_mut_slice(), name: "Vertex.Normal".to_string() },
Stream{ buffer: index_buffer.as_mut_slice(), name: "Indices".to_string() }
],
});
}
Expand Down
6 changes: 3 additions & 3 deletions src/resource_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ pub enum ProcessedResources {
Ref(String),
}

pub struct Buffer<'a> {
pub struct Stream<'a> {
/// The slice of the buffer to load the resource binary data into.
pub buffer: &'a mut [u8],
/// The subresource tag. This is used to identify the subresource. (EJ: "Vertex", "Index", etc.)
pub tag: String,
pub name: String,
}

/// Enumaration for all the possible results of a resource load fails.
Expand Down Expand Up @@ -113,7 +113,7 @@ pub struct OptionResource<'a> {
/// The resource to apply this option to.
pub url: String,
/// The buffers to load the resource binary data into.
pub buffers: Vec<Buffer<'a>>,
pub streams: Vec<Stream<'a>>,
}

/// Represents the options for performing a bundled/batch resource load.
Expand Down
4 changes: 2 additions & 2 deletions src/resource_manager/resource_handler.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{resource_manager, ProcessedResources, Buffer};
use super::{resource_manager, ProcessedResources, Stream};

pub trait ResourceHandler {
fn can_handle_type(&self, resource_type: &str) -> bool;
Expand All @@ -18,5 +18,5 @@ pub trait ResourceHandler {

fn get_deserializers(&self) -> Vec<(&'static str, Box<dyn Fn(&polodb_core::bson::Document) -> Box<dyn std::any::Any> + Send>)>;

fn read(&self, _resource: &Box<dyn std::any::Any>, file: &mut std::fs::File, buffers: &mut [Buffer]);
fn read(&self, _resource: &Box<dyn std::any::Any>, file: &mut std::fs::File, buffers: &mut [Stream]);
}
2 changes: 1 addition & 1 deletion src/resource_manager/resource_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ impl ResourceManager {
let _slice = if let Some(options) = &mut options {
if let Some(x) = options.resources.iter_mut().find(|e| e.url == resource_container.url) {
self.resource_handlers.iter().find(|h| h.can_handle_type(resource_container.class.as_str())).unwrap().
read(&response.resource, &mut file, x.buffers.as_mut_slice());
read(&response.resource, &mut file, x.streams.as_mut_slice());
} else {
let range = &mut buffer[offset..(offset + resource_container.size as usize)];
offset += resource_container.size as usize;
Expand Down
2 changes: 1 addition & 1 deletion src/resource_manager/texture_resource_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ impl ResourceHandler for ImageResourceHandler {
Ok(vec![ProcessedResources::Generated((resource_document, intel_tex_2::bc7::compress_blocks(&settings, &rgba_surface)))])
}

fn read(&self, _resource: &Box<dyn std::any::Any>, file: &mut std::fs::File, buffers: &mut [super::Buffer]) {
fn read(&self, _resource: &Box<dyn std::any::Any>, file: &mut std::fs::File, buffers: &mut [super::Stream]) {
file.read_exact(buffers[0].buffer).unwrap();
}

Expand Down

0 comments on commit 6b5fefe

Please sign in to comment.