From a3b748c83cc59efac742257b2fec36f16bf90f42 Mon Sep 17 00:00:00 2001 From: Ilja Kartashov Date: Thu, 5 Dec 2024 13:35:28 +0100 Subject: [PATCH 1/2] Extend materials with images in renderer and shaders --- README.md | 8 +- src/graphics/vulkan.rs | 42 ++ src/models/materials.rs | 9 +- src/models/renderer.rs | 434 ++++++++++++++++-- .../{only_mesh.frag.glsl => only_mesh.frag} | 15 +- src/models/shaders/only_mesh.frag.spv | Bin 1608 -> 1952 bytes .../{only_mesh.vert.glsl => only_mesh.vert} | 0 .../{skin_mesh.frag.glsl => skin_mesh.frag} | 16 +- src/models/shaders/skin_mesh.frag.spv | Bin 1608 -> 1952 bytes .../{skin_mesh.vert.glsl => skin_mesh.vert} | 27 +- src/models/shaders/skin_mesh.vert.spv | Bin 6176 -> 6488 bytes 11 files changed, 472 insertions(+), 79 deletions(-) rename src/models/shaders/{only_mesh.frag.glsl => only_mesh.frag} (54%) rename src/models/shaders/{only_mesh.vert.glsl => only_mesh.vert} (100%) rename src/models/shaders/{skin_mesh.frag.glsl => skin_mesh.frag} (54%) rename src/models/shaders/{skin_mesh.vert.glsl => skin_mesh.vert} (66%) diff --git a/README.md b/README.md index f967263..c819619 100644 --- a/README.md +++ b/README.md @@ -33,10 +33,10 @@ cargo run --release We are using GLSL shaders. There is no auto-compilation to SPV right now, so please use `glslc`: ``` -glslc -fshader-stage=vertex src/models/shaders/only_mesh.vert.glsl -o src/models/shaders/only_mesh.vert.spv -glslc -fshader-stage=fragment src/models/shaders/only_mesh.frag.glsl -o src/models/shaders/only_mesh.frag.spv -glslc -fshader-stage=vertex src/models/shaders/skin_mesh.vert.glsl -o src/models/shaders/skin_mesh.vert.spv -glslc -fshader-stage=fragment src/models/shaders/skin_mesh.frag.glsl -o src/models/shaders/skin_mesh.frag.spv +glslc -fshader-stage=vertex src/models/shaders/only_mesh.vert -o src/models/shaders/only_mesh.vert.spv +glslc -fshader-stage=fragment src/models/shaders/only_mesh.frag -o src/models/shaders/only_mesh.frag.spv +glslc -fshader-stage=vertex src/models/shaders/skin_mesh.vert -o src/models/shaders/skin_mesh.vert.spv +glslc -fshader-stage=fragment src/models/shaders/skin_mesh.frag -o src/models/shaders/skin_mesh.frag.spv ``` ## Sponsors diff --git a/src/graphics/vulkan.rs b/src/graphics/vulkan.rs index c1c442a..8df31b9 100644 --- a/src/graphics/vulkan.rs +++ b/src/graphics/vulkan.rs @@ -579,6 +579,27 @@ impl Gpu { self.device.vk_device.destroy_buffer(buffer, None); } + /// # Safety + /// + /// This function requires valid Vulkan entities + #[inline(always)] + pub unsafe fn create_sampler( + &self, + sampler_create_info: &vk::SamplerCreateInfo, + ) -> Result { + self.device + .vk_device + .create_sampler(sampler_create_info, None) + } + + /// # Safety + /// + /// This function requires valid Vulkan entities + #[inline(always)] + pub unsafe fn destroy_sampler(&self, sampler: vk::Sampler) { + self.device.vk_device.destroy_sampler(sampler, None); + } + /// # Safety /// /// This function requires valid Vulkan entities @@ -1035,6 +1056,27 @@ impl Gpu { ) } + /// # Safety + /// + /// This function requires valid Vulkan entities + #[allow(clippy::too_many_arguments)] + pub unsafe fn cmd_copy_buffer_to_image( + &self, + command_buffer: vk::CommandBuffer, + src_buffer: vk::Buffer, + dst_image: vk::Image, + dst_image_layout: vk::ImageLayout, + regions: &[vk::BufferImageCopy], + ) { + self.device.vk_device.cmd_copy_buffer_to_image( + command_buffer, + src_buffer, + dst_image, + dst_image_layout, + regions, + ); + } + // Utils pub fn find_memory_type_index( &self, diff --git a/src/models/materials.rs b/src/models/materials.rs index af307ac..4778d0c 100644 --- a/src/models/materials.rs +++ b/src/models/materials.rs @@ -2,6 +2,9 @@ use super::{Color, Image}; use crate::loaders::Asset; use crate::utils::Id; +// NOTE: 1:albedo_map, 2:occlusion_map, 3:metallic_map, 4:normal_map, 5:roughness_map +pub const MAX_MATERIAL_IMAGES: u32 = 5; + /// Material component #[derive(Debug)] pub struct Material { @@ -51,10 +54,10 @@ pub struct MaterialUniform { pub color: [f32; 4], /// Order: ambient_occlusion, metallic, roughness pub options: [f32; 4], - /// Indices of PBR maps in the buffer - /// Order: ambient_occlusion, metallic, normal, roughness - pub maps_1: [u32; 4], /// Index of Color map in the buffer + 3 reserved value¨ + pub maps_1: [u32; 4], + /// Indice2 of PBR maps in the buffer + /// Order: ambient_occlusion, metallic, normal, roughness pub maps_2: [u32; 4], } diff --git a/src/models/renderer.rs b/src/models/renderer.rs index e4f6e0c..19b09e6 100644 --- a/src/models/renderer.rs +++ b/src/models/renderer.rs @@ -5,11 +5,11 @@ use std::io::Cursor; use crate::graphics::vk; use crate::graphics::{Buffer, RenderPass}; use crate::loaders::Assets; -use crate::math::{Mat4, Vec3}; +use crate::models::materials::MAX_MATERIAL_IMAGES; use crate::utils::Id; use crate::world::{Camera, Entity, World}; use crate::{log, VertexJoints, VertexWeights}; -use crate::{Any, Asset, Display, Extent2D, Frame, Gpu, Ref, Task}; +use crate::{Any, Asset, Display, Extent2D, Frame, Gpu, Image, Ref, Task}; use super::materials::MaterialUniform; use super::{ @@ -21,8 +21,6 @@ use super::{ pub struct LayoutInBuffer { /// Offset inside of the buffer in bytes pub offset: u64, - /// Size of the buffer used for the mesh data - pub size: u64, /// Offset of the first item (vertex or index) pub base: u32, /// Number of items (vertices or indices) @@ -102,6 +100,23 @@ pub struct RenderModels { material_buffer_index: HashMap, u32>, /// Materials buffer data material_buffer_data: Vec, + /// Material sampler + material_sampler: vk::Sampler, + /// Material image view + material_image_view: vk::ImageView, + /// Material image memory + material_image_memory: vk::DeviceMemory, + /// Material image + material_image: vk::Image, + /// Buffer to copy material images to material_image + material_staging_buffer: Buffer, + /// Number of layers in material image buffer + material_layer_count: u32, + material_layer_size: Extent2D, + /// Material layer index in the material_image + material_layer_index: HashMap, usize>, + /// Usage of layers in material image buffer + material_layer_usage: u32, /// Mesh layouts of non-rigged models mesh_registry: HashMap, MeshLayout>, /// descriptor sets @@ -166,6 +181,18 @@ impl Drop for RenderModels { self.instance_buffer.free_memory_and_destroy(&self.gpu); self.material_buffer.free_memory_and_destroy(&self.gpu); self.transform_buffer.free_memory_and_destroy(&self.gpu); + self.material_staging_buffer + .free_memory_and_destroy(&self.gpu); + + // samplers + self.gpu.destroy_sampler(self.material_sampler); + + // image views + self.gpu.destroy_image_view(self.material_image_view); + + // images and memory + self.gpu.free_memory(self.material_image_memory); + self.gpu.destroy_image(self.material_image); // descriptors for &descriptor_set_layout in self.desc_set_layouts.iter() { @@ -398,6 +425,101 @@ impl RenderModels { Self::load_shader_module(&gpu, include_bytes!("shaders/skin_mesh.frag.spv")) .expect("Failed to load skin-mesh fragment shader module") }; + let material_sampler_create_info = vk::SamplerCreateInfo { + mag_filter: vk::Filter::LINEAR, + min_filter: vk::Filter::LINEAR, + mipmap_mode: vk::SamplerMipmapMode::LINEAR, + address_mode_u: vk::SamplerAddressMode::MIRRORED_REPEAT, + address_mode_v: vk::SamplerAddressMode::MIRRORED_REPEAT, + address_mode_w: vk::SamplerAddressMode::MIRRORED_REPEAT, + max_anisotropy: 1.0, + border_color: vk::BorderColor::FLOAT_OPAQUE_WHITE, + compare_op: vk::CompareOp::NEVER, + ..Default::default() + }; + + let material_sampler = unsafe { + gpu.create_sampler(&material_sampler_create_info) + .expect("Failed to create materials sampler") + }; + + let material_layer_count = setup.material_count * MAX_MATERIAL_IMAGES; + + let material_image_create_info = vk::ImageCreateInfo { + image_type: vk::ImageType::TYPE_2D, + format: vk::Format::R8G8B8A8_UNORM, + extent: vk::Extent3D { + width: setup.material_image_size.width, + height: setup.material_image_size.height, + depth: 1, + }, + mip_levels: 1, + array_layers: material_layer_count, + samples: vk::SampleCountFlags::TYPE_1, + tiling: vk::ImageTiling::OPTIMAL, + usage: vk::ImageUsageFlags::TRANSFER_DST | vk::ImageUsageFlags::SAMPLED, + sharing_mode: vk::SharingMode::EXCLUSIVE, + ..Default::default() + }; + let material_image = unsafe { + gpu.create_image(&material_image_create_info) + .expect("Failed to create material image") + }; + let material_image_memory_req = + unsafe { gpu.get_image_memory_requirements(material_image) }; + let material_image_memory_index = gpu + .find_memory_type_index( + &material_image_memory_req, + vk::MemoryPropertyFlags::DEVICE_LOCAL, + ) + .expect("Unable to find suitable memory index for depth image."); + + let material_image_allocate_info = vk::MemoryAllocateInfo { + allocation_size: material_image_memory_req.size, + memory_type_index: material_image_memory_index, + ..Default::default() + }; + let material_image_memory = unsafe { + gpu.allocate_memory(&material_image_allocate_info) + .expect("Failed to allocate material image") + }; + unsafe { + gpu.bind_image_memory(material_image, material_image_memory, 0) + .expect("Unable to bind depth image memory"); + }; + + let material_image_view_info = vk::ImageViewCreateInfo { + view_type: vk::ImageViewType::TYPE_2D_ARRAY, + format: material_image_create_info.format, + components: vk::ComponentMapping { + r: vk::ComponentSwizzle::R, + g: vk::ComponentSwizzle::G, + b: vk::ComponentSwizzle::B, + a: vk::ComponentSwizzle::A, + }, + subresource_range: vk::ImageSubresourceRange { + aspect_mask: vk::ImageAspectFlags::COLOR, + level_count: 1, + layer_count: material_layer_count, + ..Default::default() + }, + image: material_image, + ..Default::default() + }; + let material_image_view = unsafe { + gpu.create_image_view(&material_image_view_info) + .expect("Failed to create material image view") + }; + + let material_staging_buffer_size = MAX_MATERIAL_IMAGES + * setup.material_image_size.width + * setup.material_image_size.height + * std::mem::size_of::() as u32; + + let material_staging_buffer = unsafe { + Self::create_transfer_buffer(&gpu, material_staging_buffer_size as u64) + .expect("Could not allocate material staging buffer") + }; // bindings layout let descriptor_sizes = [ @@ -421,10 +543,11 @@ impl RenderModels { ty: vk::DescriptorType::STORAGE_BUFFER, descriptor_count: 1, }, - // vk::DescriptorPoolSize { - // ty: vk::DescriptorType::COMBINED_IMAGE_SAMPLER, - // descriptor_count: 1, - // }, + // Materials textures sampler + vk::DescriptorPoolSize { + ty: vk::DescriptorType::COMBINED_IMAGE_SAMPLER, + descriptor_count: 1, + }, ]; let descriptor_pool_info = vk::DescriptorPoolCreateInfo::default() .pool_sizes(&descriptor_sizes) @@ -445,7 +568,7 @@ impl RenderModels { binding: 1, descriptor_type: vk::DescriptorType::STORAGE_BUFFER, descriptor_count: 1, - stage_flags: vk::ShaderStageFlags::VERTEX, + stage_flags: vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::FRAGMENT, ..Default::default() }, // Material @@ -453,7 +576,7 @@ impl RenderModels { binding: 2, descriptor_type: vk::DescriptorType::STORAGE_BUFFER, descriptor_count: 1, - stage_flags: vk::ShaderStageFlags::VERTEX, + stage_flags: vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::FRAGMENT, ..Default::default() }, // Transform @@ -464,14 +587,14 @@ impl RenderModels { stage_flags: vk::ShaderStageFlags::VERTEX, ..Default::default() }, - // Materials - //vk::DescriptorSetLayoutBinding { - // binding: 1, - // descriptor_type: vk::DescriptorType::COMBINED_IMAGE_SAMPLER, - // descriptor_count: 1, - // stage_flags: vk::ShaderStageFlags::FRAGMENT, - // ..Default::default() - //}, + // Materials textures sampler + vk::DescriptorSetLayoutBinding { + binding: 4, + descriptor_type: vk::DescriptorType::COMBINED_IMAGE_SAMPLER, + descriptor_count: 1, + stage_flags: vk::ShaderStageFlags::FRAGMENT, + ..Default::default() + }, ]; let descriptor_info = vk::DescriptorSetLayoutCreateInfo::default().bindings(&desc_layout_bindings); @@ -507,11 +630,11 @@ impl RenderModels { offset: 0, range: transform_buffer.size, }; - // let tex_descriptor = vk::DescriptorImageInfo { - // image_layout: vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL, - // image_view: tex_image_view, - // sampler, - // }; + let tex_descriptor = vk::DescriptorImageInfo { + image_layout: vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL, + image_view: material_image_view, + sampler: material_sampler, + }; let only_mesh_write_desc_sets = [ vk::WriteDescriptorSet { @@ -546,14 +669,14 @@ impl RenderModels { p_buffer_info: &transform_storage_buffer_descriptor, ..Default::default() }, - //vk::WriteDescriptorSet { - // dst_set: descriptor_sets[0], - // dst_binding: 1, - // descriptor_count: 1, - // descriptor_type: vk::DescriptorType::COMBINED_IMAGE_SAMPLER, - // p_image_info: &tex_descriptor, - // ..Default::default() - //}, + vk::WriteDescriptorSet { + dst_binding: 4, + dst_set: descriptor_sets[0], + descriptor_count: 1, + descriptor_type: vk::DescriptorType::COMBINED_IMAGE_SAMPLER, + p_image_info: &tex_descriptor, + ..Default::default() + }, ]; unsafe { @@ -598,6 +721,15 @@ impl RenderModels { transform_buffer, material_buffer_index: HashMap::new(), material_buffer_data: Vec::new(), + material_sampler, + material_image_view, + material_image, + material_image_memory, + material_staging_buffer, + material_layer_count, + material_layer_usage: 0, + material_layer_index: HashMap::new(), + material_layer_size: setup.material_image_size, mesh_registry: HashMap::new(), descriptor_pool, desc_set_layouts, @@ -983,7 +1115,6 @@ impl RenderModels { }); if let Some((vertex_data, vertex_size, has_skin)) = vertex_data_and_skin_info { - let data_size = vertex_data.len() as u64; let vertex_offset = if has_skin { self.vertex_buffer_skin_mesh_usage } else { @@ -994,13 +1125,11 @@ impl RenderModels { let mesh_layout = MeshLayout { vertices: LayoutInBuffer { offset: vertex_offset, - size: data_size, base: (vertex_offset / vertex_size) as u32, count: mesh.count_vertices() as u32, }, indices: index_data.map(|data| LayoutInBuffer { offset: self.index_buffer_usage, - size: (data.len() * std::mem::size_of::()) as u64, base: (self.index_buffer_usage / (std::mem::size_of::() as u64)) as u32, count: data.len() as u32, @@ -1072,21 +1201,212 @@ impl RenderModels { } fn register_material(&mut self, material_id: Id, assets: &Assets) -> Option { - assets.get(material_id).and_then(|material| { - self.material_buffer_index - .get(&material_id) - .cloned() - .or_else(|| { - let index = self.material_buffer_index.len() as u32; - self.material_buffer_data.push(MaterialUniform::default()); - self.material_buffer_index.insert(material_id, index); - Some(index) - }) - .map(|material_index| { - self.material_buffer_data[material_index as usize] = material.into(); - material_index + let material_uniform: MaterialUniform = if let Some(material) = assets.get(material_id) { + let mut staging_layer_count: u32 = 0; + let (albedo_map_index, base_array_layer) = assets + .get(material.albedo_map) + .map(|image| { + let base_array_layer = self.material_layer_index.len(); + if !self.material_layer_index.contains_key(&material.albedo_map) { + // write to buffer + // TODO: verify material extent + unsafe { + self.material_staging_buffer.map_and_write_to_device_memory( + &self.gpu, + (staging_layer_count + * self.material_layer_size.width + * self.material_layer_size.height + * std::mem::size_of::() as u32) + as u64, + image.data(), + ); + }; + self.material_layer_index + .insert(material.albedo_map, base_array_layer); + staging_layer_count += 1; + } + let albedo_map_index = self + .material_layer_index + .get(&material.albedo_map) + .cloned() + .expect("Layer index must be inserted at this stage") + as u32; + (albedo_map_index, base_array_layer) }) - }) + .unwrap_or((0, 0)); + // flush material staging buffer + unsafe { + self.flush_material_staging_buffer(staging_layer_count, base_array_layer as u32); + }; + let mut material_uniform: MaterialUniform = material.into(); + material_uniform.maps_1 = [ + albedo_map_index, + std::u32::MAX, + std::u32::MAX, + std::u32::MAX, + ]; + material_uniform.maps_2 = [std::u32::MAX; 4]; + material_uniform + } else { + return None; + }; + // NOTE: most likely there will be need of having an index for relations + // between Id and material layer index + self.material_buffer_index + .get(&material_id) + .cloned() + .map(|material_index| { + self.material_buffer_data[material_index as usize] = material_uniform; + material_index + }) + .or_else(|| { + let material_index = self.material_buffer_index.len() as u32; + self.material_buffer_data.push(material_uniform); + self.material_buffer_index + .insert(material_id, material_index); + Some(material_index) + }) + } + + unsafe fn flush_material_staging_buffer( + &self, + staging_layer_count: u32, + base_array_layer: u32, + ) { + if staging_layer_count == 0 { + return; + } + log::debug!("copy material to vk:Image ({} layers)", staging_layer_count); + // begin + self.gpu + .wait_for_fences(&[self.command_buffer_setup_reuse_fence], true, u64::MAX) + .expect("Wait for fence failed."); + + self.gpu + .reset_fences(&[self.command_buffer_setup_reuse_fence]) + .expect("Reset fences failed."); + + self.gpu + .reset_command_buffer( + self.command_buffer_setup, + vk::CommandBufferResetFlags::RELEASE_RESOURCES, + ) + .expect("Reset command buffer failed."); + + let command_buffer_begin_info = vk::CommandBufferBeginInfo::default() + .flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT); + + self.gpu + .begin_command_buffer(self.command_buffer_setup, &command_buffer_begin_info) + .expect("Begin commandbuffer"); + + // Command buffer + // let buffer_copy_regions = (0..staging_layer_count) + // .into_iter() + // .map(|_| { + // vk::BufferImageCopy::default() + // .image_subresource( + // vk::ImageSubresourceLayers::default() + // .aspect_mask(vk::ImageAspectFlags::COLOR) + // .base_array_layer(base_array_layer) + // .layer_count(1), + // ) + // .image_extent(vk::Extent3D { + // width: self.material_layer_size.width, + // height: self.material_layer_size.height, + // depth: 1, + // }) + // }) + // .collect::>(); + let buffer_copy_regions = [vk::BufferImageCopy::default() + .image_subresource( + vk::ImageSubresourceLayers::default() + .aspect_mask(vk::ImageAspectFlags::COLOR) + .base_array_layer(base_array_layer) + .layer_count(staging_layer_count), + ) + .image_extent(vk::Extent3D { + width: self.material_layer_size.width, + height: self.material_layer_size.height, + depth: 1, + })]; + let texture_barrier = vk::ImageMemoryBarrier { + dst_access_mask: vk::AccessFlags::TRANSFER_WRITE, + new_layout: vk::ImageLayout::TRANSFER_DST_OPTIMAL, + image: self.material_image, + subresource_range: vk::ImageSubresourceRange { + aspect_mask: vk::ImageAspectFlags::COLOR, + level_count: 1, + layer_count: self.material_layer_count, // TODO: shouldn't there be total number? + ..Default::default() + }, + ..Default::default() + }; + self.gpu.cmd_pipeline_barrier( + self.command_buffer_setup, + vk::PipelineStageFlags::BOTTOM_OF_PIPE, + vk::PipelineStageFlags::TRANSFER, + vk::DependencyFlags::empty(), + &[], + &[], + &[texture_barrier], + ); + self.gpu.cmd_copy_buffer_to_image( + self.command_buffer_setup, + self.material_staging_buffer.handle, + self.material_image, + vk::ImageLayout::TRANSFER_DST_OPTIMAL, + buffer_copy_regions.as_slice(), + ); + let texture_barrier_end = vk::ImageMemoryBarrier { + src_access_mask: vk::AccessFlags::TRANSFER_WRITE, + dst_access_mask: vk::AccessFlags::SHADER_READ, + old_layout: vk::ImageLayout::TRANSFER_DST_OPTIMAL, + new_layout: vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL, // TODO: shouldn't there be total number? + image: self.material_image, + subresource_range: vk::ImageSubresourceRange { + aspect_mask: vk::ImageAspectFlags::COLOR, + level_count: 1, + layer_count: self.material_layer_count, + ..Default::default() + }, + ..Default::default() + }; + self.gpu.cmd_pipeline_barrier( + self.command_buffer_setup, + vk::PipelineStageFlags::TRANSFER, + vk::PipelineStageFlags::FRAGMENT_SHADER, + vk::DependencyFlags::empty(), + &[], + &[], + &[texture_barrier_end], + ); + // end + self.gpu + .end_command_buffer(self.command_buffer_setup) + .expect("End commandbuffer"); + + let command_buffers = vec![self.command_buffer_setup]; + let wait_semaphores = []; + let wait_mask = []; + let signal_semaphores = []; + + let submit_info = vk::SubmitInfo::default() + .wait_semaphores(&wait_semaphores) + .wait_dst_stage_mask(&wait_mask) + .command_buffers(&command_buffers) + .signal_semaphores(&signal_semaphores); + + log::debug!("submit image copy"); + self.gpu + .submit_queue(&[submit_info], self.command_buffer_setup_reuse_fence) + .expect("queue submit failed."); + // wait + let fences = [self.command_buffer_setup_reuse_fence]; + self.gpu + .wait_for_fences(&fences, true, std::u64::MAX) + .expect("Failed to wait until end of textures bufering"); + log::debug!("wait_for_fences: done"); } /// Returns Buffer, binded memory and allocated size @@ -1145,6 +1465,17 @@ impl RenderModels { Buffer::create_and_allocate(gpu, &buffer_create_info) } + unsafe fn create_transfer_buffer(gpu: &Gpu, size: u64) -> Result { + let buffer_create_info = vk::BufferCreateInfo { + size, + usage: vk::BufferUsageFlags::TRANSFER_SRC, + sharing_mode: vk::SharingMode::EXCLUSIVE, + ..Default::default() + }; + + Buffer::create_and_allocate(gpu, &buffer_create_info) + } + unsafe fn load_shader_module(gpu: &Gpu, bytes: &[u8]) -> Result { // let bytes = include_bytes!("shaders/non-rigged.frag.spv"); let mut cursor = Cursor::new(bytes); @@ -1745,6 +2076,8 @@ pub struct RenderModelsSetup { instance_buffer_size: u64, material_buffer_size: u64, transform_buffer_size: u64, + material_count: u32, + material_image_size: Extent2D, } impl Default for RenderModelsSetup { @@ -1760,6 +2093,11 @@ impl Default for RenderModelsSetup { instance_buffer_size: 1000 * std::mem::size_of::() as u64, material_buffer_size: 1000 * std::mem::size_of::() as u64, transform_buffer_size: 1000 * std::mem::size_of::() as u64, + material_count: 2, + material_image_size: Extent2D { + width: 1024, + height: 1024, + }, } } } diff --git a/src/models/shaders/only_mesh.frag.glsl b/src/models/shaders/only_mesh.frag similarity index 54% rename from src/models/shaders/only_mesh.frag.glsl rename to src/models/shaders/only_mesh.frag index 3e624e1..c267d24 100644 --- a/src/models/shaders/only_mesh.frag.glsl +++ b/src/models/shaders/only_mesh.frag @@ -2,21 +2,24 @@ #extension GL_ARB_separate_shader_objects : enable #extension GL_ARB_shading_language_420pack : enable -layout (location = 0) in vec3 world_position; -layout (location = 1) in vec3 world_normal; -layout (location = 2) in vec4 vertex_color; -layout (location = 0) out vec4 o_frag_color; +layout(location = 0) in vec3 world_position; +layout(location = 1) in vec3 world_normal; +layout(location = 2) in vec4 vertex_color; +layout(location = 3) in vec3 vertex_texture; +layout(location = 0) out vec4 o_frag_color; +layout(binding = 4) uniform sampler2DArray dtx_material_sampler; void main() { vec3 ambient_light = vec3(0.5, 0.5, 0.5); vec4 color = vec4(0.0, 0.0, 0.0, 0.0); vec3 light_color = vec3(1.0, 1.0, 1.0); - vec3 light_position = vec3(10.0, 10.0, 10.0); + vec3 light_position = vec3(10.0, 10.0, 10.0); vec3 normal = normalize(world_normal); vec3 light_direction = normalize(light_position - world_position); vec3 diffuse = max(dot(normal, light_direction), 0.0) * light_color; + vec4 texture_color = texture(dtx_material_sampler, vertex_texture); - o_frag_color = vec4((ambient_light + diffuse), 1.0) * vertex_color; + o_frag_color = vec4((ambient_light + diffuse), 1.0) * vertex_color * texture_color; } diff --git a/src/models/shaders/only_mesh.frag.spv b/src/models/shaders/only_mesh.frag.spv index 2727349b18f8d8fb84fd164a879a21668b0900b5..d74515cec2abc5d902c6218e9ebab9e811371b61 100644 GIT binary patch delta 693 zcmZ8e%SyvQ6upzyYP3Ocqg4>KAk??k+G^8BR^8f_%Mdh+LSiLGDYz&u`T>$3@E4@` z5B`Lo;ZpFNJWw1s%suCxx%bY@NAY#h$Z6$S5hV*^i1lLB%JY&JiQzkgTZB>q)`3Hy z3Yc%slj>Ixh3+VP2weMm=nVt#8JUxP>^I@a_MOlT299UnJN}*LGL3v8uJY&xIBKWI z6TKRJs%2$HU#f1g#ug7?^)L(hCcw$aISD7qrJPfdb1`pDTUtkrOQOpTqynIr!}`Ck zp~xyW;{Cq{Fun(@#C~bP)3r6WLB~ T*ae}H3Eq%z*#*8aN(1--zhOL@ delta 353 zcmXw!u}%U(5Qb-$I}PzJMjK)y1S$|zTu_OEP!T$P1PcobcmWGy;RBef=y(Of6VUlm zB!2&e+vLm6d^5YVyFUF((voi+n>jnN)b4-Nezk0oS!;p66 zZK%Vy#d+Q#R*(D}?uh*wKAk??k+G^8BR^8f_%Mdh+LSiLGDYz&u`T>$3@E4@` z5B`Lo;ZpFNJWw1s%suCxx%bY@NAY#h$Z6$S5hV*^i1lLB%JY&JiQzkgTZB>q)`3Hy z3Yc%slj>Ixh3+VP2weMm=nVt#8JUxP>^I@a_MOlT299UnJN}*LGL3v8uJY&xIBKWI z6TKRJs%2$HU#f1g#ug7?^)L(hCcw$aISD7qrJPfdb1`pDTUtkrOQOpTqynIr!}`Ck zp~xyW;{Cq{Fun(@#C~bP)3r6WLB~ T*ae}H3Eq%z*#*8aN(1--zhOL@ delta 353 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 literal 6176 zcmZ9OiI>||6~}+=Ofm&670afUnrSN{#SyVo7J*J%m{tc{DB|vqbP}d%Gf7M`U2vf& zD!3uITdk;AmvLVZcZ4e9zWyyP=Xj2vPx8CrwQtVtz4v>Uci+9g_tLTD>nE~oS@w)< zW%kc(xX#X&gJfXk0iT)OGdtDm*QPdIahV=xWn%+JeOB@38iy9Djh6D+&<^O;& zdIWkDIte`m{R0}~Z#n#N5{+kPWHYn*^etQSUcFQ8R{Qn5x35~Ock}k%{q?zi?^GX5 zjn;hLthVMCtMm1I)8&_Ss&fa(bEbJ_cI}#(y&<3Lbn;&RNVA?d8?Aa?YjnxfI9NB= zio~zcnrklBQil>A>6uFOVg-;3he=fwh+d-iD+iWg4reys%;O9@2ZtN@m9z8Vr`KaY)_|XWKJg9W?OMH=k4`wK z^CEEibZfM*S5#`9+FaK8bkwlUi-#t1l(Q-1(VlbdX1l9TDf7c5_f18+@f>1?7H%WV z-nTpbM!VG;VfK8X+UeylwQs{%dp*D|ANB~A?r}<=wYjW6>QlGRn-o~qe-*rUpwUVX z>9^*6IaF`V@8d&P_wMX(H(Gx8p6?iXr`z72A8gbQA&Y$$&Y5SL?Y-3|e%3AK(pMgs zXD&hqvB%M^b-oDpJMyl!^F!@!vzB+-y@nkE!hdXVhry7`gS#AlEv`bfsn7V}ey6&3 zy`2xcZ`_mUd}F)o-P`KjK9`48E^uXSv8~^P{?3~NRR!jA$%tA zu`X*6iyFLZX$|VupxyYv4*+tSQ!IKEXBCScRgfdrJjQDGOkB6*45cjYQRKHiG2`_2 zE~WLUTc3Mr_a3cj6 zb7}4B*6y88()svK z7P7s%0DT=?Ox;|5U!GmuGkSNGJ>x}ib^TrlcTX{ERQC>wX}_e9ja7d!+`N;Jb-V;_ zz3yv|y=U4aZIb(Y@3gtU_eW-d13tFQD7g(Cn^M{cukn#F|xsb*6S3gl;+P{u$tzlPRDzNbPtuddvcHbIfjDG^IZ4%P1 zezL&Up#KKB0(oY?!6)JRRv>Ld`*`+SWbb^r_ zn|bf_8;4xx_%}!iuI~hV1tbsM|JSDannYiZydlxOXH$u;-T%u)y!x?1zn1-cW1bE9 zzD(ogTXHV65?TdmTMg-3hMxy%zmCeSQ$6xrfSl%eE_&qA=9?6Go`m@Y?t8Qmx)?HEn|^+~mqOaiVK3Dq#}&xtwKtpL zFNb_*%%Lr6nMA%4(rzASpssBHw?L6|8rd^1G4*Zm?U2}3=wJBX2zULL`n25uiTRx< zPZQ@|eyiQ)cJbkw9Yr6TW7>r*Bc@6sPj$8#)(IrZ$^$f zwMU(ALDm*^=E!2!aWl0$zuO_}cLi2O*4K4+;kOt0c1T(9@Z{72TOdj5F&(;xV%xvT@=uvp#anOnc015m{Tz>>#q3b;S7( zA$ty2V26?Qb;bFQAnU6w{O&|HHl5kq(2Y%J_I7lAwMFbZkc~}e_D*zT)0y3cuCKO; zJ&J5>ItgkC(_7P-#wT0gU z$i}8Kdl22&bY>q#*H>G_ehk^zbY>q%H#VKwC(!lP7O|g1Hg+t*K80+oSk(M!WPP>8 z%szwcS**$2`o!;ow*RpEjd0(0x%0dP{(0y)ve- zrF;FVz|ylm4rcsgkao}d2wdE=PQrf;O+ngD7JBsIcj$gAG4tOe+pDPK56EJ!!2XCV sme%&C0!#bwXE5XS*Piy_FX-;AkKg$d@V`P&L8~BZRoCx->~tmce>EgsHUIzs From 60c18e88a670d64e542254ae33a27087a7c327bf Mon Sep 17 00:00:00 2001 From: Ilja Kartashov Date: Thu, 12 Dec 2024 09:26:16 +0100 Subject: [PATCH 2/2] Update CI --- .github/workflows/ci.yml | 4 ++-- .github/workflows/style.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b31e7b7..af48f0a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,9 +2,9 @@ name: CI on: push: - branches: [ main, style_checks ] + branches: [ master, main, style_checks ] pull_request: - branches: [ main, style_checks ] + branches: [ master, main, style_checks ] env: CARGO_TERM_COLOR: always diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index c3cfd4d..317ba7f 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -2,9 +2,9 @@ name: Style on: push: - branches: [ main, style_checks ] + branches: [ master, main, style_checks ] pull_request: - branches: [ main, style_checks ] + branches: [ master, main, style_checks ] jobs: check_clippy: