Implement extra render outputs for metallic and emissives

This commit is contained in:
2024-10-15 05:24:48 -04:00
parent 20a24512b7
commit 7a85b0eb5a
30 changed files with 239 additions and 136 deletions

View File

@@ -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")

View File

@@ -1 +1,3 @@
set(GLM_ENABLE_CXX_20 ON)
add_subdirectory(${CMAKE_SOURCE_DIR}/dependencies/glm)

View File

@@ -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 );

View File

@@ -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]]

View File

@@ -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 };

View File

@@ -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() ) );

View File

@@ -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 );

View File

@@ -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 );

View File

@@ -236,7 +236,6 @@ namespace fgl::engine
else
{
set = texture_descriptor_set.create();
set->setMaxIDX( 1 );
set->setName( "Texture descriptor set" );
return *set;
}

View File

@@ -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();

View File

@@ -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,

View File

@@ -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
g_buffer_metallic_img.emplace_back( std::make_unique< Texture >( gbuffer.metallic.m_attachment_resources
.m_images[ i ]
->setName( "GBufferAlbedo" ) ) );
->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" );

View File

@@ -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:

View File

@@ -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(

View File

@@ -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;

View File

@@ -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

View File

@@ -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 );

View File

@@ -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;
}

View File

@@ -10,9 +10,10 @@
#include <cassert>
#include <cmath>
#include <cstdint>
#include <iostream>
#include <map>
#include <memory>
#include <source_location>
#include <stacktrace>
#include <unordered_map>
#include "vma/vma_impl.hpp"
@@ -87,7 +88,9 @@ namespace fgl::engine::memory
//! @brief List of all active suballocations
//! <offset, size>
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.

View File

@@ -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" );
}

View File

@@ -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 );

View File

@@ -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
}

View File

@@ -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();

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -0,0 +1,15 @@

View File

@@ -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);
}

View File

@@ -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)
{
out_albedo = vec4(255.0f / 255.0f, 192.0f / 255.0f, 203.0f / 255.0f, 1.0f);
return;
}
vec3 diffuse_color;
vec4 base_color;
uint normal_id = materials[in_material_id].normal_texture_id;
if (isValidTex(normal_id))
{
vec3 normal_vec = texture(tex[normal_id], in_uv).xyz;
out_normal = vec4(normal_vec, 1.0);
}
else
{
out_normal = vec4(in_normal, 1.0f);
}
vec3 f0 = vec3(0.04);
uint albedo_id = materials[in_material_id].color_texture_id;
uint mat_id = in_material_id;
if (albedo_id == INVALID_TEXTURE_ID)
{
out_albedo = vec4(1.0f, 1.0f, 1.0f, 1.0f);
}
else
{
vec4 tex_value = texture(tex[albedo_id], in_uv);
if (tex_value.a < 1.0)
if (mat_id == INVALID_TEXTURE_ID)
{
discard;
}
out_albedo = tex_value;
// 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)
{
// 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
{
// If we have no color texture, Simply use the color factors as our color
out_color = materials[mat_id].color_factors;
}
out_position.a = linearDepth(out_position.z);
float metallic_scalar = 0.0;
float roughness_scalar = 0.0;
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
{
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 // Texture was not present, So we instead use the factor values as our values
{
metallic_scalar = clamp(materials[mat_id].metallic_factor, MIN_ROUGHNESS, 1.0);
roughness_scalar = clamp(materials[mat_id].roughness_factor, 0.0, 1.0);
}
// 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);
}