diff --git a/CMakeLists.txt b/CMakeLists.txt index 08519d9..9998678 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ enable_testing() set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_MESSAGE_LOG_LEVEL DEBUG CACHE STRING "CMake messaging level") diff --git a/cmake_modules/dependencies/glm.cmake b/cmake_modules/dependencies/glm.cmake index 41e8843..cef7777 100644 --- a/cmake_modules/dependencies/glm.cmake +++ b/cmake_modules/dependencies/glm.cmake @@ -1 +1,3 @@ + +set(GLM_ENABLE_CXX_20 ON) add_subdirectory(${CMAKE_SOURCE_DIR}/dependencies/glm) \ No newline at end of file diff --git a/src/editor/src/gui/preview.cpp b/src/editor/src/gui/preview.cpp index 3fd1e7b..77acaeb 100644 --- a/src/editor/src/gui/preview.cpp +++ b/src/editor/src/gui/preview.cpp @@ -209,7 +209,7 @@ namespace fgl::engine::gui camera.getSwapchain().g_buffer_composite_img[ frame_index ]->drawImGui( target_size ); break; case Albedo: - camera.getSwapchain().g_buffer_albedo_img[ frame_index ]->drawImGui( target_size ); + camera.getSwapchain().g_buffer_color_img[ frame_index ]->drawImGui( target_size ); break; case Normal: camera.getSwapchain().g_buffer_normal_img[ frame_index ]->drawImGui( target_size ); diff --git a/src/engine/FGL_DEFINES.hpp b/src/engine/FGL_DEFINES.hpp index 4796cb7..1e30adc 100644 --- a/src/engine/FGL_DEFINES.hpp +++ b/src/engine/FGL_DEFINES.hpp @@ -14,6 +14,8 @@ #define FGL_DELETE_ALL_Ro5( ClassName ) \ FGL_DELETE_DEFAULT_CTOR( ClassName ) FGL_DELETE_COPY( ClassName ) FGL_DELETE_MOVE( ClassName ) +#define FGL_PACKED __attribute__(( packed )) +#define FGL_PACKED_ALIGNED( al ) __attribute__(( packed, aligned( al ) )) #define FGL_FLATTEN [[gnu::flatten]] #define FGL_ARTIFICIAL [[gnu::artificial]] #define FGL_HOT [[gnu::hot]] diff --git a/src/engine/FrameInfo.hpp b/src/engine/FrameInfo.hpp index 10fcac7..43aaa7a 100644 --- a/src/engine/FrameInfo.hpp +++ b/src/engine/FrameInfo.hpp @@ -53,12 +53,14 @@ namespace fgl::engine constexpr vk::ShaderStageFlags FRAG_STAGE { vk::ShaderStageFlagBits::eFragment }; - constexpr descriptors::AttachmentDescriptor position_descriptor { 0, FRAG_STAGE }; - constexpr descriptors::AttachmentDescriptor normal_descriptor { 1, FRAG_STAGE }; - constexpr descriptors::AttachmentDescriptor albedo_descriptor { 2, FRAG_STAGE }; + constexpr descriptors::AttachmentDescriptor color_descriptor { 0, FRAG_STAGE }; + constexpr descriptors::AttachmentDescriptor position_descriptor { 1, FRAG_STAGE }; + constexpr descriptors::AttachmentDescriptor normal_descriptor { 2, FRAG_STAGE }; + constexpr descriptors::AttachmentDescriptor metallic_descriptor { 3, FRAG_STAGE }; + constexpr descriptors::AttachmentDescriptor emissive_descriptor { 4, FRAG_STAGE }; inline static descriptors::DescriptorSetLayout gbuffer_set { - 0, position_descriptor, normal_descriptor, albedo_descriptor + 0, color_descriptor, position_descriptor, normal_descriptor, metallic_descriptor, emissive_descriptor }; constexpr descriptors::AttachmentDescriptor input_descriptor { 0, vk::ShaderStageFlagBits::eFragment }; diff --git a/src/engine/assets/material/Material.cpp b/src/engine/assets/material/Material.cpp index f063dcb..28fbad4 100644 --- a/src/engine/assets/material/Material.cpp +++ b/src/engine/assets/material/Material.cpp @@ -55,7 +55,6 @@ namespace fgl::engine Material::Material() : m_id( material_id_counter.getID() ) { - update(); getDescriptorSet().bindArray( 0, getDeviceMaterialGPUData().getHandle(), m_id, sizeof( DeviceMaterialData ) ); getDescriptorSet().update(); } @@ -131,7 +130,6 @@ namespace fgl::engine { set = material_descriptor_set.create(); assert( set->setIDX() == MATERIAL_SET_ID ); - set->setMaxIDX( 1 ); //set->bindUniformBuffer( 0, getDeviceMaterialGPUData() ); //set->update(); //set = std::make_unique< descriptors::DescriptorSet >( std::move( set_layout.value() ) ); diff --git a/src/engine/assets/material/Material.hpp b/src/engine/assets/material/Material.hpp index db391e0..e353faf 100644 --- a/src/engine/assets/material/Material.hpp +++ b/src/engine/assets/material/Material.hpp @@ -75,16 +75,19 @@ namespace fgl::engine using MaterialID = std::uint32_t; +#define PAD( id, size ) std::byte pad_##id[ size ]; + //! Material data to be sent to the device // Alignas to prevent the struct from becoming bigger then needed struct DeviceMaterialData { TextureID color_texture_id { constants::INVALID_TEXTURE_ID }; + + PAD( 0, 12 ); + glm::vec4 color_factors { 0.0f, 0.0f, 0.0f, 0.0f }; // Padding to shove metallic_texture_id to offset 32 - std::byte padd1[ 12 ]; - TextureID metallic_texture_id { constants::INVALID_TEXTURE_ID }; float metallic_factor { 0.0f }; float roughness_factor { 0.0f }; @@ -100,6 +103,7 @@ namespace fgl::engine }; static_assert( sizeof( DeviceMaterialData ) == 76 ); + static_assert( offsetof( DeviceMaterialData, color_factors ) == 16 ); static_assert( offsetof( DeviceMaterialData, metallic_texture_id ) == 32 ); static_assert( offsetof( DeviceMaterialData, normal_texture_id ) == 44 ); static_assert( offsetof( DeviceMaterialData, occlusion_texture_id ) == 52 ); diff --git a/src/engine/assets/model/builders/SceneBuilder.cpp b/src/engine/assets/model/builders/SceneBuilder.cpp index 517ab8a..4e82f4d 100644 --- a/src/engine/assets/model/builders/SceneBuilder.cpp +++ b/src/engine/assets/model/builders/SceneBuilder.cpp @@ -98,7 +98,7 @@ namespace fgl::engine if ( accessor.type == TINYGLTF_TYPE_SCALAR && T_SIZE >= byte_count ) { // If the type is a smaller scalar then we want can still copy the data. - log::warn( "Attempting to copy data of size {} into type of size {}", byte_count, T_SIZE ); + // log::warn( "Attempting to copy data of size {} into type of size {}", byte_count, T_SIZE ); if constexpr ( std::is_scalar_v< T > ) { @@ -308,8 +308,6 @@ namespace fgl::engine std::vector< glm::vec2 > SceneBuilder::extractUVInfo( const tinygltf::Primitive& prim, const tinygltf::Model& root ) { ZoneScoped; - log::debug( "Extracting UV info" ); - //TODO: Figure out how I can use multiple textures for various things. if ( !hasAttribute( prim, "TEXCOORD_0" ) ) return {}; @@ -328,7 +326,6 @@ namespace fgl::engine extractVertexInfo( const tinygltf::Primitive& prim, const tinygltf::Model& root ) { ZoneScoped; - log::debug( "Extracting vert info" ); const auto pos { extractPositionInfo( prim, root ) }; std::vector< ModelVertex > verts {}; @@ -355,12 +352,6 @@ namespace fgl::engine verts.emplace_back( vert ); } - log::debug( - "Found {} verts. Has UV info: {}, Has normals: {}", - verts.size(), - has_uv ? "Yes" : "No", - has_normals ? "Yes" : "No" ); - return verts; } @@ -373,8 +364,6 @@ namespace fgl::engine att_str += attrib.first + ", "; } - log::debug( "Attributes for primitive: [{}]", att_str ); - //TODO: Get normal colors from texture [[maybe_unused]] const bool has_normal { hasAttribute( prim, "NORMAL" ) }; const bool has_position { hasAttribute( prim, "POSITION" ) }; @@ -572,7 +561,19 @@ namespace fgl::engine const auto& metallic_roughness { gltf_material.pbrMetallicRoughness }; const auto& pbr_tex_id { metallic_roughness.baseColorTexture.index }; material->properties.pbr.color_tex = loadTexture( pbr_tex_id, root ); - material->properties.pbr.color_factors = convertToVec4( metallic_roughness.baseColorFactor ); + log::debug( + "Color factors: {}, {}, {}, {}", + metallic_roughness.baseColorFactor[ 0 ], + metallic_roughness.baseColorFactor[ 1 ], + metallic_roughness.baseColorFactor[ 2 ], + metallic_roughness.baseColorFactor[ 3 ] + + ); + + material->properties.pbr.color_factors = { metallic_roughness.baseColorFactor[ 0 ], + metallic_roughness.baseColorFactor[ 1 ], + metallic_roughness.baseColorFactor[ 2 ], + metallic_roughness.baseColorFactor[ 3 ] }; material->properties.pbr.metallic_roughness_tex = loadTexture( metallic_roughness.metallicRoughnessTexture.index, root ); diff --git a/src/engine/assets/texture/Texture.cpp b/src/engine/assets/texture/Texture.cpp index 76e1c5e..ea6b56c 100644 --- a/src/engine/assets/texture/Texture.cpp +++ b/src/engine/assets/texture/Texture.cpp @@ -236,7 +236,6 @@ namespace fgl::engine else { set = texture_descriptor_set.create(); - set->setMaxIDX( 1 ); set->setName( "Texture descriptor set" ); return *set; } diff --git a/src/engine/camera/Camera.cpp b/src/engine/camera/Camera.cpp index 2a7121e..a19b7d6 100644 --- a/src/engine/camera/Camera.cpp +++ b/src/engine/camera/Camera.cpp @@ -342,7 +342,6 @@ namespace fgl::engine for ( std::uint8_t i = 0; i < SwapChain::MAX_FRAMES_IN_FLIGHT; ++i ) { auto set { camera_descriptor_set.create() }; - set->setMaxIDX( 0 ); set->bindUniformBuffer( 0, m_camera_frame_info[ i ] ); set->update(); diff --git a/src/engine/camera/CameraRenderer.cpp b/src/engine/camera/CameraRenderer.cpp index b14e552..88164da 100644 --- a/src/engine/camera/CameraRenderer.cpp +++ b/src/engine/camera/CameraRenderer.cpp @@ -15,31 +15,42 @@ namespace fgl::engine { rendering::RenderPassBuilder builder {}; - constexpr std::size_t PositionIndex { 0 }; - constexpr std::size_t NormalIndex { 1 }; - constexpr std::size_t AlbedoIndex { 2 }; - constexpr std::size_t CompositeIndex { 3 }; - constexpr std::size_t DepthIndex { 4 }; - - builder.setAttachmentCount( 5 ); + builder.setAttachmentCount( 7 ); // Set formats for each item in the swapchain + + //XYZ in world space auto position { builder.attachment( PositionIndex ) }; position.setFormat( vk::Format::eR16G16B16A16Sfloat ); // position position.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal ); position.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore ); + //RGBA auto normal { builder.attachment( NormalIndex ) }; normal.setFormat( vk::Format::eR16G16B16A16Sfloat ); // normal normal.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal ); normal.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore ); - auto albedo { builder.attachment( AlbedoIndex ) }; - albedo.setFormat( vk::Format::eR8G8B8A8Unorm ); // albedo - albedo.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal ); - albedo.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore ); + // RGBA + auto color { builder.attachment( ColorIndex ) }; + color.setFormat( vk::Format::eR8G8B8A8Unorm ); // color + color.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal ); + color.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore ); + + // Metallic, Roughness, Occlusion + auto metallic_roughness { builder.attachment( MetallicIndex ) }; + metallic_roughness.setFormat( vk::Format::eR16G16B16A16Sfloat ); + metallic_roughness.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal ); + metallic_roughness.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore ); + + // RGB + auto emissive { builder.attachment( EmissiveIndex ) }; + emissive.setFormat( vk::Format::eR16G16B16A16Sfloat ); + emissive.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal ); + emissive.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore ); auto composite { builder.attachment( CompositeIndex ) }; + //TODO: For HDR I think this needs to be a bigger range then 8bits per channel. composite.setFormat( vk::Format::eR8G8B8A8Unorm ); // composite composite.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal ); composite.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore ); @@ -51,9 +62,11 @@ namespace fgl::engine auto& g_buffer_subpass { builder.createSubpass( 0 ) }; g_buffer_subpass.setDepthLayout( DepthIndex, vk::ImageLayout::eDepthStencilAttachmentOptimal ); + g_buffer_subpass.addRenderLayout( ColorIndex, vk::ImageLayout::eColorAttachmentOptimal ); g_buffer_subpass.addRenderLayout( PositionIndex, vk::ImageLayout::eColorAttachmentOptimal ); g_buffer_subpass.addRenderLayout( NormalIndex, vk::ImageLayout::eColorAttachmentOptimal ); - g_buffer_subpass.addRenderLayout( AlbedoIndex, vk::ImageLayout::eColorAttachmentOptimal ); + g_buffer_subpass.addRenderLayout( MetallicIndex, vk::ImageLayout::eColorAttachmentOptimal ); + g_buffer_subpass.addRenderLayout( EmissiveIndex, vk::ImageLayout::eColorAttachmentOptimal ); g_buffer_subpass.addDependencyFromExternal( vk::AccessFlagBits::eDepthStencilAttachmentWrite, @@ -64,9 +77,11 @@ namespace fgl::engine auto& composite_subpass { builder.createSubpass( 1 ) }; composite_subpass.addRenderLayout( CompositeIndex, vk::ImageLayout::eColorAttachmentOptimal ); + composite_subpass.addInputLayout( ColorIndex, vk::ImageLayout::eShaderReadOnlyOptimal ); composite_subpass.addInputLayout( PositionIndex, vk::ImageLayout::eShaderReadOnlyOptimal ); composite_subpass.addInputLayout( NormalIndex, vk::ImageLayout::eShaderReadOnlyOptimal ); - composite_subpass.addInputLayout( AlbedoIndex, vk::ImageLayout::eShaderReadOnlyOptimal ); + composite_subpass.addInputLayout( MetallicIndex, vk::ImageLayout::eShaderReadOnlyOptimal ); + composite_subpass.addInputLayout( EmissiveIndex, vk::ImageLayout::eShaderReadOnlyOptimal ); composite_subpass.addDependency( g_buffer_subpass, diff --git a/src/engine/camera/CameraSwapchain.cpp b/src/engine/camera/CameraSwapchain.cpp index 5114a6f..8af60ee 100644 --- a/src/engine/camera/CameraSwapchain.cpp +++ b/src/engine/camera/CameraSwapchain.cpp @@ -19,13 +19,15 @@ namespace fgl::engine //auto set { std::make_unique< descriptors::DescriptorSet >( GBufferDescriptorSet::createLayout() ) }; auto set { gbuffer_set.create() }; - set->setMaxIDX( 2 ); + set->bindAttachment( 0, gbuffer.color.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); - set->bindAttachment( 0, gbuffer.position.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); + set->bindAttachment( 1, gbuffer.position.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); - set->bindAttachment( 1, gbuffer.normal.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); + set->bindAttachment( 2, gbuffer.normal.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); - set->bindAttachment( 2, gbuffer.albedo.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); + set->bindAttachment( 3, gbuffer.metallic.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); + + set->bindAttachment( 4, gbuffer.emissive.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); set->update(); @@ -44,9 +46,12 @@ namespace fgl::engine std::vector< vk::raii::Framebuffer > CameraSwapchain::createFrambuffers() { constexpr auto image_count { SwapChain::MAX_FRAMES_IN_FLIGHT }; + + gbuffer.color.createResources( image_count, m_extent ); gbuffer.position.createResources( image_count, m_extent ); gbuffer.normal.createResources( image_count, m_extent ); - gbuffer.albedo.createResources( image_count, m_extent ); + gbuffer.metallic.createResources( image_count, m_extent ); + gbuffer.emissive.createResources( image_count, m_extent ); gbuffer.composite.createResources( image_count, m_extent, vk::ImageUsageFlagBits::eTransferSrc ); gbuffer.depth.createResources( image_count, m_extent ); @@ -58,7 +63,14 @@ namespace fgl::engine for ( FrameIndex i = 0; i < image_count; ++i ) { std::vector< vk::ImageView > attachments { getViewsForFrame( - i, gbuffer.position, gbuffer.normal, gbuffer.albedo, gbuffer.composite, gbuffer.depth ) }; + i, + gbuffer.color, + gbuffer.position, + gbuffer.normal, + gbuffer.metallic, + gbuffer.emissive, + gbuffer.composite, + gbuffer.depth ) }; vk::FramebufferCreateInfo info {}; info.renderPass = m_renderpass; @@ -69,20 +81,29 @@ namespace fgl::engine buffers.emplace_back( Device::getInstance()->createFramebuffer( info ) ); + g_buffer_color_img.emplace_back( std::make_unique< Texture >( gbuffer.color.m_attachment_resources + .m_images[ i ] + ->setName( "GBufferColor" ) ) ); + auto& position_resources { gbuffer.position.m_attachment_resources }; assert( position_resources.m_images[ i ] ); assert( position_resources.m_image_views[ i ] ); auto& position_image { *position_resources.m_images[ i ] }; position_image.setName( format_ns::format( "GBufferPosition: {}", i ) ); - g_buffer_position_img.emplace_back( std::make_unique< Texture >( position_image ) ); g_buffer_normal_img.emplace_back( std::make_unique< Texture >( gbuffer.normal.m_attachment_resources .m_images[ i ] ->setName( "GBufferNormal" ) ) ); - g_buffer_albedo_img.emplace_back( std::make_unique< Texture >( gbuffer.albedo.m_attachment_resources - .m_images[ i ] - ->setName( "GBufferAlbedo" ) ) ); + + g_buffer_metallic_img.emplace_back( std::make_unique< Texture >( gbuffer.metallic.m_attachment_resources + .m_images[ i ] + ->setName( "GBufferMetallic" ) ) ); + + g_buffer_emissive_img.emplace_back( std::make_unique< Texture >( gbuffer.emissive.m_attachment_resources + .m_images[ i ] + ->setName( "GBufferEmissive" ) ) ); + g_buffer_composite_img.emplace_back( std::make_unique< Texture >( gbuffer.composite.m_attachment_resources .m_images[ i ] ->setName( "GBufferComposite" ) ) ); @@ -121,8 +142,14 @@ namespace fgl::engine m_extent( extent ), m_renderpass( renderpass ), m_framebuffers( createFrambuffers() ), - m_clear_values( - gatherClearValues( gbuffer.albedo, gbuffer.composite, gbuffer.depth, gbuffer.normal, gbuffer.position ) ), + m_clear_values( gatherClearValues( + gbuffer.color, + gbuffer.position, + gbuffer.normal, + gbuffer.metallic, + gbuffer.emissive, + gbuffer.composite, + gbuffer.depth ) ), m_gbuffer_descriptor_set( createGBufferDescriptors() ) { gbuffer.depth.setName( "Depth" ); diff --git a/src/engine/camera/CameraSwapchain.hpp b/src/engine/camera/CameraSwapchain.hpp index 6e6caf2..08e0cda 100644 --- a/src/engine/camera/CameraSwapchain.hpp +++ b/src/engine/camera/CameraSwapchain.hpp @@ -4,29 +4,44 @@ #pragma once -#include "engine/rendering/pipelines/Attachment.hpp" #include "engine/descriptors/DescriptorSet.hpp" #include "engine/rendering/SwapChain.hpp" +#include "engine/rendering/pipelines/Attachment.hpp" namespace fgl::engine { + constexpr std::size_t ColorIndex { 0 }; + constexpr std::size_t PositionIndex { 1 }; + constexpr std::size_t NormalIndex { 2 }; + constexpr std::size_t MetallicIndex { 3 }; + constexpr std::size_t EmissiveIndex { 4 }; + + constexpr std::size_t CompositeIndex { 5 }; + constexpr std::size_t DepthIndex { 6 }; + class CameraSwapchain { struct { - ColorAttachment< 0 > position { vk::Format::eR16G16B16A16Sfloat }; - ColorAttachment< 1 > normal { vk::Format::eR16G16B16A16Sfloat }; - ColorAttachment< 2 > albedo { vk::Format::eR8G8B8A8Unorm }; - ColorAttachment< 3 > composite { vk::Format::eR8G8B8A8Unorm }; - DepthAttachment< 4 > depth { SwapChain::findDepthFormat() }; + ColorAttachment< ColorIndex > color { vk::Format::eR8G8B8A8Unorm }; + ColorAttachment< PositionIndex > position { vk::Format::eR16G16B16A16Sfloat }; + ColorAttachment< NormalIndex > normal { vk::Format::eR16G16B16A16Sfloat }; + ColorAttachment< MetallicIndex > metallic { vk::Format::eR16G16B16A16Sfloat }; + ColorAttachment< EmissiveIndex > emissive { vk::Format::eR16G16B16A16Sfloat }; + + ColorAttachment< CompositeIndex > composite { vk::Format::eR8G8B8A8Unorm }; + DepthAttachment< DepthIndex > depth { SwapChain::findDepthFormat() }; } gbuffer {}; public: + std::vector< std::unique_ptr< Texture > > g_buffer_color_img {}; std::vector< std::unique_ptr< Texture > > g_buffer_position_img {}; std::vector< std::unique_ptr< Texture > > g_buffer_normal_img {}; - std::vector< std::unique_ptr< Texture > > g_buffer_albedo_img {}; + std::vector< std::unique_ptr< Texture > > g_buffer_metallic_img {}; + std::vector< std::unique_ptr< Texture > > g_buffer_emissive_img {}; + std::vector< std::unique_ptr< Texture > > g_buffer_composite_img {}; private: diff --git a/src/engine/descriptors/DescriptorSet.cpp b/src/engine/descriptors/DescriptorSet.cpp index bfe152c..c41a822 100644 --- a/src/engine/descriptors/DescriptorSet.cpp +++ b/src/engine/descriptors/DescriptorSet.cpp @@ -18,10 +18,14 @@ namespace fgl::engine::descriptors { - DescriptorSet::DescriptorSet( const vk::raii::DescriptorSetLayout& layout, DescriptorIDX idx ) : + DescriptorSet::DescriptorSet( + const vk::raii::DescriptorSetLayout& layout, const DescriptorIDX idx, const std::size_t binding_count ) : m_set_idx( idx ), - m_set( DescriptorPool::getInstance().allocateSet( layout ) ) - {} + m_set( DescriptorPool::getInstance().allocateSet( layout ) ), + m_binding_count( binding_count ) + { + m_infos.resize( m_binding_count ); + } DescriptorSet::DescriptorSet( DescriptorSet&& other ) noexcept : m_set_idx( other.m_set_idx ), @@ -29,9 +33,10 @@ namespace fgl::engine::descriptors descriptor_writes( std::move( other.descriptor_writes ) ), m_resources( std::move( other.m_resources ) ), m_set( std::move( other.m_set ) ), - m_max_idx( other.m_max_idx ) + m_binding_count( other.m_binding_count ) { other.m_set = VK_NULL_HANDLE; + other.m_binding_count = 0; } DescriptorSet& DescriptorSet::operator=( DescriptorSet&& other ) noexcept @@ -42,7 +47,9 @@ namespace fgl::engine::descriptors m_resources = std::move( other.m_resources ); m_set = std::move( other.m_set ); other.m_set = VK_NULL_HANDLE; - m_max_idx = other.m_max_idx; + m_binding_count = other.m_binding_count; + other.m_binding_count = 0; + return *this; } @@ -156,13 +163,7 @@ namespace fgl::engine::descriptors //Clear all writes descriptor_writes.clear(); - setMaxIDX( m_max_idx ); - } - - void DescriptorSet::setMaxIDX( std::uint32_t max_idx ) - { - m_max_idx = max_idx; - m_infos.resize( max_idx + 1 ); + m_infos.resize( m_binding_count ); } void DescriptorSet::bindAttachment( diff --git a/src/engine/descriptors/DescriptorSet.hpp b/src/engine/descriptors/DescriptorSet.hpp index 40fec43..51fb53f 100644 --- a/src/engine/descriptors/DescriptorSet.hpp +++ b/src/engine/descriptors/DescriptorSet.hpp @@ -39,7 +39,7 @@ namespace fgl::engine::descriptors vk::raii::DescriptorSet m_set; - std::uint32_t m_max_idx { 0 }; + std::size_t m_binding_count; public: @@ -47,8 +47,6 @@ namespace fgl::engine::descriptors void update(); - void setMaxIDX( std::uint32_t max_idx ); - VkDescriptorSet operator*() const { return *m_set; } VkDescriptorSet getVkDescriptorSet() const { return *m_set; } @@ -56,7 +54,7 @@ namespace fgl::engine::descriptors inline DescriptorIDX setIDX() const { return m_set_idx; } DescriptorSet() = delete; - DescriptorSet( const vk::raii::DescriptorSetLayout& layout, const DescriptorIDX idx ); + DescriptorSet( const vk::raii::DescriptorSetLayout& layout, const DescriptorIDX idx, std::size_t binding_count ); //Copy DescriptorSet( const DescriptorSet& other ) = delete; diff --git a/src/engine/descriptors/DescriptorSetLayout.cpp b/src/engine/descriptors/DescriptorSetLayout.cpp index 3dc2380..d9aa3ad 100644 --- a/src/engine/descriptors/DescriptorSetLayout.cpp +++ b/src/engine/descriptors/DescriptorSetLayout.cpp @@ -12,7 +12,8 @@ namespace fgl::engine::descriptors DescriptorSetLayout::DescriptorSetLayout( const DescriptorIDX set_idx, const std::vector< std::reference_wrapper< const Descriptor > >& descriptors ) : - m_set_idx( set_idx ) + m_set_idx( set_idx ), + m_binding_count( descriptors.size() ) { FGL_ASSERT( descriptors.size() > 0, "Must have more then 1 descriptor set" ); @@ -38,7 +39,7 @@ namespace fgl::engine::descriptors std::unique_ptr< DescriptorSet > DescriptorSetLayout::create() { if ( !m_layout.has_value() ) m_layout = createLayout(); - return std::make_unique< DescriptorSet >( *m_layout, m_set_idx ); + return std::make_unique< DescriptorSet >( *m_layout, m_set_idx, m_binding_count ); } vk::raii::DescriptorSetLayout DescriptorSetLayout::createLayout() const diff --git a/src/engine/descriptors/DescriptorSetLayout.hpp b/src/engine/descriptors/DescriptorSetLayout.hpp index a3bbc6b..0b54170 100644 --- a/src/engine/descriptors/DescriptorSetLayout.hpp +++ b/src/engine/descriptors/DescriptorSetLayout.hpp @@ -26,6 +26,8 @@ namespace fgl::engine::descriptors DescriptorIDX m_set_idx; + std::size_t m_binding_count; + DescriptorSetLayout( DescriptorIDX set_idx, const std::vector< std::reference_wrapper< const Descriptor > >& descriptors ); diff --git a/src/engine/memory/buffers/Buffer.cpp b/src/engine/memory/buffers/Buffer.cpp index 2181246..9467ea6 100644 --- a/src/engine/memory/buffers/Buffer.cpp +++ b/src/engine/memory/buffers/Buffer.cpp @@ -130,7 +130,7 @@ namespace fgl::engine::memory } std::shared_ptr< BufferSuballocationHandle > Buffer:: - allocate( vk::DeviceSize memory_size, std::uint32_t t_alignment ) + allocate( vk::DeviceSize memory_size, const std::uint32_t t_alignment ) { ZoneScoped; //Calculate alignment from alignment, ubo_alignment, and atom_size_alignment @@ -189,14 +189,14 @@ namespace fgl::engine::memory #ifndef NDEBUG //Check that we haven't lost any memory std::size_t sum { 0 }; - for ( const auto& free_blocks : this->m_free_blocks ) + for ( const auto& [ _, free_size ] : this->m_free_blocks ) { - sum += free_blocks.second; + sum += free_size; } - for ( const auto& allocated : this->m_allocations ) + for ( const auto& [ _, allocated_size ] : this->m_allocations ) { - sum += allocated.second; + sum += allocated_size; } assert( sum == this->size() ); @@ -227,10 +227,7 @@ namespace fgl::engine::memory if ( m_free_blocks.size() <= 1 ) return; //Sort the blocks by offset - std::sort( - m_free_blocks.begin(), - m_free_blocks.end(), - []( const auto& a, const auto& b ) -> bool { return a.first < b.first; } ); + std::ranges::sort( m_free_blocks, []( const auto& a, const auto& b ) -> bool { return a.first < b.first; } ); auto itter { m_free_blocks.begin() }; auto next_block { std::next( itter ) }; @@ -318,7 +315,10 @@ namespace fgl::engine::memory if ( m_allocations.size() == 0 ) return total_size; - for ( const auto& [ offset, size ] : m_allocations ) total_size += size; + for ( const auto& [ offset, size ] : m_allocations ) + { + total_size += size; + } return total_size; } diff --git a/src/engine/memory/buffers/Buffer.hpp b/src/engine/memory/buffers/Buffer.hpp index 073d68f..ada3d8c 100644 --- a/src/engine/memory/buffers/Buffer.hpp +++ b/src/engine/memory/buffers/Buffer.hpp @@ -10,9 +10,10 @@ #include #include #include -#include #include #include +#include +#include #include #include "vma/vma_impl.hpp" @@ -87,7 +88,9 @@ namespace fgl::engine::memory //! @brief List of all active suballocations //! - std::map< vk::DeviceSize, vk::DeviceSize > m_allocations {}; + using AllocationSize = vk::DeviceSize; + + std::map< vk::DeviceSize, AllocationSize > m_allocations {}; //! @brief list of any free blocks //! @note All blocks are amalgamated to the largest they can expand to. @@ -123,6 +126,7 @@ namespace fgl::engine::memory /** * @param memory_size Size of each N * @param alignment The alignment to use. + * @param source_loc Source location. * @return * * @note Alignment is forced to be at least the size of the largest alignment required by the device. diff --git a/src/engine/memory/buffers/vector/DeviceVector.hpp b/src/engine/memory/buffers/vector/DeviceVector.hpp index cb0ac40..6310327 100644 --- a/src/engine/memory/buffers/vector/DeviceVector.hpp +++ b/src/engine/memory/buffers/vector/DeviceVector.hpp @@ -31,7 +31,6 @@ namespace fgl::engine BufferVector( buffer, count, sizeof( T ) ) { const auto size_str { fgl::literals::size_literals::to_string( count * sizeof( T ) ) }; - log::debug( "Creating DeviceVector of size {}", size_str ); assert( count != 0 && "BufferSuballocationVector::BufferSuballocationVector() called with count == 0" ); } diff --git a/src/engine/rendering/SwapChain.cpp b/src/engine/rendering/SwapChain.cpp index 2c0a629..e057fdd 100644 --- a/src/engine/rendering/SwapChain.cpp +++ b/src/engine/rendering/SwapChain.cpp @@ -69,8 +69,6 @@ namespace fgl::engine auto set { gui_descriptor_set.create() }; //auto set { std::make_unique< descriptors::DescriptorSet >( GuiInputDescriptorSet::createLayout() ) }; - set->setMaxIDX( 0 ); - // set->bindAttachment( // 0, render_attachments.input_color.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal ); diff --git a/src/engine/rendering/renderpass/RenderPass.cpp b/src/engine/rendering/renderpass/RenderPass.cpp index ae583f4..c77e4a2 100644 --- a/src/engine/rendering/renderpass/RenderPass.cpp +++ b/src/engine/rendering/renderpass/RenderPass.cpp @@ -157,6 +157,7 @@ namespace fgl::engine::rendering { m_builder.setFormat( m_index, format ); #ifndef NDEBUG + assert( !set_format ); set_format = true; #endif } @@ -165,6 +166,7 @@ namespace fgl::engine::rendering { m_builder.setLayouts( m_index, image_layout, final_layout ); #ifndef NDEBUG + assert( !set_layout ); set_layout = true; #endif } @@ -173,6 +175,7 @@ namespace fgl::engine::rendering { m_builder.setOps( m_index, load_op, store_op ); #ifndef NDEBUG + assert( !set_ops ); set_ops = true; #endif } diff --git a/src/engine/systems/EntityRendererSystem.cpp b/src/engine/systems/EntityRendererSystem.cpp index b859753..fc35578 100644 --- a/src/engine/systems/EntityRendererSystem.cpp +++ b/src/engine/systems/EntityRendererSystem.cpp @@ -30,6 +30,8 @@ namespace fgl::engine builder.addDescriptorSet( Camera::getDescriptorLayout() ); + builder.addColorAttachment().finish(); + builder.addColorAttachment().finish(); builder.addColorAttachment().finish(); builder.addColorAttachment().finish(); builder.addColorAttachment().finish(); @@ -51,6 +53,8 @@ namespace fgl::engine PipelineBuilder builder { render_pass, 0 }; + builder.addColorAttachment().finish(); + builder.addColorAttachment().finish(); builder.addColorAttachment().finish(); builder.addColorAttachment().finish(); builder.addColorAttachment().finish(); diff --git a/src/engine/systems/LineDrawer.cpp b/src/engine/systems/LineDrawer.cpp index c1325ee..69bcb17 100644 --- a/src/engine/systems/LineDrawer.cpp +++ b/src/engine/systems/LineDrawer.cpp @@ -30,6 +30,8 @@ namespace fgl::engine builder.addDescriptorSet( Camera::getDescriptorLayout() ); + builder.addColorAttachment().finish(); + builder.addColorAttachment().finish(); builder.addColorAttachment().finish(); builder.addColorAttachment().finish(); builder.addColorAttachment().finish(); diff --git a/src/shaders/composition.frag b/src/shaders/composition.frag index 55df4b6..521f296 100644 --- a/src/shaders/composition.frag +++ b/src/shaders/composition.frag @@ -1,32 +1,20 @@ #version 450 -layout (input_attachment_index = 0, binding = 0) uniform subpassInput i_position; -layout (input_attachment_index = 1, binding = 1) uniform subpassInput i_normal; -layout (input_attachment_index = 2, binding = 2) uniform subpassInput i_albedo; +layout (input_attachment_index = 0, binding = 0) uniform subpassInput i_color; +layout (input_attachment_index = 1, binding = 1) uniform subpassInput i_position; +layout (input_attachment_index = 2, binding = 2) uniform subpassInput i_normal; +layout (input_attachment_index = 3, binding = 3) uniform subpassInput i_metallic; +layout (input_attachment_index = 4, binding = 4) uniform subpassInput i_emissive; layout (location = 0) in vec2 in_uv; layout (location = 0) out vec4 out_color; -/* -struct Light -{ - vec4 position; - vec3 color; - float radius; -}; - -layout (std410, binding = 3) buffer LightBuffer -{ - Light lights[]; -}; -*/ - void main() { vec3 position = subpassLoad(i_position).xyz; vec3 normal = subpassLoad(i_normal).xyz; - vec3 albedo = subpassLoad(i_albedo).xyz; + vec3 color = subpassLoad(i_color).xyz; #define ambient 0.5 @@ -41,7 +29,7 @@ void main() //float diff = max(dot(normalize(normal), sun_dir), 0.0); vec3 diffuse = diff * sun_color; - vec3 frag_color = (ambient + diffuse) * albedo; + vec3 frag_color = (ambient + diffuse) * color; out_color = vec4(frag_color, 1.0); } diff --git a/src/shaders/include/gbuffer_out.glsl b/src/shaders/include/gbuffer_out.glsl index cd50f21..06da35a 100644 --- a/src/shaders/include/gbuffer_out.glsl +++ b/src/shaders/include/gbuffer_out.glsl @@ -1,3 +1,5 @@ -layout (location = 0) out vec4 out_position; -layout (location = 1) out vec4 out_normal; -layout (location = 2) out vec4 out_albedo; +layout (location = 0) out vec4 out_color; +layout (location = 1) out vec3 out_position; +layout (location = 2) out vec4 out_normal; +layout (location = 3) out vec3 out_metallic; +layout (location = 4) out vec3 out_emissive; diff --git a/src/shaders/include/material.glsl b/src/shaders/include/material.glsl index b944094..d55991e 100644 --- a/src/shaders/include/material.glsl +++ b/src/shaders/include/material.glsl @@ -16,7 +16,6 @@ layout (set = 3, binding = 0) uniform Material { vec3 emissive_factors; } materials[]; - bool hasColorTexture() { return materials[in_material_id].color_texture_id != INVALID_TEXTURE_ID; diff --git a/src/shaders/include/pbr.glsl b/src/shaders/include/pbr.glsl new file mode 100644 index 0000000..6f6f000 --- /dev/null +++ b/src/shaders/include/pbr.glsl @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/src/shaders/line.frag b/src/shaders/line.frag index e135aac..7fd4f0a 100644 --- a/src/shaders/line.frag +++ b/src/shaders/line.frag @@ -5,6 +5,6 @@ layout(location = 0) in vec3 in_color; #include "include/gbuffer_out.glsl" void main() { - out_albedo = vec4(in_color, 1.0f); + out_color = vec4(in_color, 1.0f); out_normal = vec4(1.0f); } \ No newline at end of file diff --git a/src/shaders/textured-gbuffer.frag b/src/shaders/textured-gbuffer.frag index 41a3092..9ab15ac 100644 --- a/src/shaders/textured-gbuffer.frag +++ b/src/shaders/textured-gbuffer.frag @@ -19,50 +19,73 @@ layout (set = 2, binding = 0) uniform sampler2D tex[]; #include "include/material.glsl" +// Include all helper functions for glsl. +#include "include/pbr.glsl" + float linearDepth(float depth) { float z = depth * 2.0f - 1.0f; return (2.0f * NEAR_PLANE * FAR_PLANE) / (FAR_PLANE + NEAR_PLANE - z * (FAR_PLANE - NEAR_PLANE)); } +vec3 error_color = vec3(0.475, 0.0, 0.686); + +float MIN_ROUGHNESS = 0.04; + void main() { - out_position = vec4(in_world_pos, 1.0f); + out_position = in_world_pos; - if (in_material_id == INVALID_TEXTURE_ID) + vec3 diffuse_color; + vec4 base_color; + + vec3 f0 = vec3(0.04); + + uint mat_id = in_material_id; + + if (mat_id == INVALID_TEXTURE_ID) { - out_albedo = vec4(255.0f / 255.0f, 192.0f / 255.0f, 203.0f / 255.0f, 1.0f); - return; + discard; } - uint normal_id = materials[in_material_id].normal_texture_id; - if (isValidTex(normal_id)) + // The Vulkan-glTF-PBR example does some alpha mask stuff. I'm not exactly sure what it's used for + // So for now we will just set the base_color to be the texture color + uint color_texture_id = materials[mat_id].color_texture_id; + if (color_texture_id != INVALID_TEXTURE_ID) { - vec3 normal_vec = texture(tex[normal_id], in_uv).xyz; - out_normal = vec4(normal_vec, 1.0); + // Load the texture and multiply it against the color factors + vec4 color = texture(tex[color_texture_id], in_uv).rgba; + vec4 factors = materials[mat_id].color_factors; + out_color = color * factors; } else { - out_normal = vec4(in_normal, 1.0f); + // If we have no color texture, Simply use the color factors as our color + out_color = materials[mat_id].color_factors; } - uint albedo_id = materials[in_material_id].color_texture_id; + float metallic_scalar = 0.0; + float roughness_scalar = 0.0; - if (albedo_id == INVALID_TEXTURE_ID) + uint metallic_id = materials[mat_id].metallic_texture_id; + if (metallic_id != INVALID_TEXTURE_ID)// If the metallic texture is assigned, Then we should use it. Otherwise we want to use the metallic factor { - out_albedo = vec4(1.0f, 1.0f, 1.0f, 1.0f); + vec4 tex_sample = texture(tex[metallic_id], in_uv).rgba; + // r channel is for occlusion data (optional) + // g channel is for roughnes factor + // b channel is for metallic factor + metallic_scalar = tex_sample.b * materials[mat_id].metallic_factor; + roughness_scalar = tex_sample.g * materials[mat_id].roughness_factor; } - else + else // Texture was not present, So we instead use the factor values as our values { - vec4 tex_value = texture(tex[albedo_id], in_uv); - - if (tex_value.a < 1.0) - { - discard; - } - - out_albedo = tex_value; + metallic_scalar = clamp(materials[mat_id].metallic_factor, MIN_ROUGHNESS, 1.0); + roughness_scalar = clamp(materials[mat_id].roughness_factor, 0.0, 1.0); } - out_position.a = linearDepth(out_position.z); + // The example does some magic here that I don't understand? + // https://github.com/SaschaWillems/Vulkan-glTF-PBR/blob/master/data/shaders/material_pbr.frag#L242 + float occlusion_scalar = 0.0; + + out_metallic = vec3(metallic_scalar, roughness_scalar, occlusion_scalar); } \ No newline at end of file