Get basics of material system implemented and working

This commit is contained in:
2024-10-14 04:29:41 -04:00
parent b3945e600b
commit 9e919060f3
63 changed files with 943 additions and 364 deletions

View File

@@ -73,7 +73,7 @@
#Note: padded is for masochists. That's coming from me. Only really enable this if your ready for a fun time.
#AppendFlag("-Wpadded")
AppendFlag("-Wredundant-decls") #Warns about declarations that happen more then once.
AppendFlag("-Wctor-dtor-privacy") #Warns if a class appears unusable due to private ctor/dtors
#AppendFlag("-Wctor-dtor-privacy") #Warns if a class appears unusable due to private ctor/dtors
AppendFlag("-Wdelete-non-virtual-dtor") #Warns about using `delete` on a class that has virtual functions without a virtual dtor
AppendFlag("-Winvalid-constexpr") #Warns that a function marked as constexpr can't possibly produce a constexpr expression
# Disabled due to spdlog

View File

@@ -11,7 +11,7 @@
#include "engine/filesystem/scanner/FileScanner.hpp"
#include "engine/filesystem/types.hpp"
#include "engine/assets/image/ImageView.hpp"
#include "engine/texture/Texture.hpp"
#include "engine/assets/texture/Texture.hpp"
#include "safe_include.hpp"
namespace fgl::engine::filesystem

View File

@@ -12,6 +12,7 @@
#include <iostream>
#include "KeyboardMovementController.hpp"
#include "assets/material/Material.hpp"
#include "camera/Camera.hpp"
#include "camera/CameraManager.hpp"
#include "engine/assets/model/builders/SceneBuilder.hpp"
@@ -25,7 +26,11 @@ namespace fgl::engine
constexpr float MAX_DELTA_TIME { 0.5 };
EngineContext::EngineContext() :
m_ubo_buffer_pool( 512_KiB, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostVisible ),
m_ubo_buffer_pool( 1_MiB, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostVisible ),
m_material_data_pool(
1_MiB,
vk::BufferUsageFlagBits::eUniformBuffer | vk::BufferUsageFlagBits::eTransferDst,
vk::MemoryPropertyFlagBits::eDeviceLocal | vk::MemoryPropertyFlagBits::eHostVisible ),
m_matrix_info_pool(
256_MiB,
vk::BufferUsageFlagBits::eVertexBuffer,
@@ -46,6 +51,26 @@ namespace fgl::engine
m_vertex_buffer->setDebugName( "Vertex buffer" );
m_index_buffer->setDebugName( "Index buffer" );
m_material_data_pool.setDebugName( "Material data pool" );
initMaterialDataVec( m_material_data_pool );
/*
const std::filesystem::path path {
"/home/kj16609/Desktop/Projects/cxx/Mecha/src/assets/khronos-sponza/Sponza.gltf"
};
SceneBuilder builder { *m_vertex_buffer, *m_index_buffer };
builder.loadScene( path );
std::vector< GameObject > objs { builder.getGameObjects() };
for ( auto& obj : objs )
{
m_game_objects_root.addGameObject( std::move( obj ) );
}*/
}
static Average< float, 60 * 15 > rolling_ms_average;
@@ -115,7 +140,7 @@ namespace fgl::engine
m_draw_parameter_pool,
*this->m_vertex_buffer,
*this->m_index_buffer,
m_renderer.getSwapChain().getInputDescriptor( present_idx ),
// m_renderer.getSwapChain().getInputDescriptor( present_idx ),
this->m_renderer.getSwapChain() };
TracyVkCollect( frame_info.tracy_ctx, *command_buffer );
@@ -126,10 +151,10 @@ namespace fgl::engine
//TODO: Add some way of 'activating' cameras. We don't need to render cameras that aren't active.
renderCameras( frame_info );
m_renderer.clearInputImage( command_buffer );
// m_renderer.clearInputImage( command_buffer );
//primary_camera
// .copyOutput( command_buffer, frame_index, m_renderer.getSwapChain().getInputImage( present_idx ) );
// camera_manager.getPrimary()
// .copyOutput( command_buffer, frame_index, m_renderer.getSwapChain().getInputImage( present_idx ) );
m_renderer.beginSwapchainRendererPass( command_buffer );

View File

@@ -58,6 +58,8 @@ namespace fgl::engine
// Memory pool for shader uniforms.
memory::Buffer m_ubo_buffer_pool;
memory::Buffer m_material_data_pool;
// Memory pool for matrix info and draw parameters
memory::Buffer m_matrix_info_pool;
memory::Buffer m_draw_parameter_pool;

View File

@@ -49,7 +49,7 @@ namespace fgl::engine
vk::DescriptorBindingFlagBits::eUpdateAfterBind
| vk::DescriptorBindingFlagBits::ePartiallyBound };
inline static descriptors::DescriptorSetLayout texture_descriptor_set { 2, texture_descriptor };
constexpr std::uint32_t TEXTURE_SET_ID { 2 };
constexpr vk::ShaderStageFlags FRAG_STAGE { vk::ShaderStageFlagBits::eFragment };
@@ -90,7 +90,7 @@ namespace fgl::engine
memory::Buffer& model_vertex_buffer;
memory::Buffer& model_index_buffer;
descriptors::DescriptorSet& gui_input_descriptor;
// descriptors::DescriptorSet& gui_input_descriptor;
descriptors::DescriptorSet& getGBufferDescriptor() const;
descriptors::DescriptorSet& getCameraDescriptor() const;

View File

@@ -0,0 +1,12 @@
//
// Created by kj16609 on 10/12/24.
//
#include "UBOBuffer.hpp"
namespace fgl::engine
{
UBOBuffer::UBOBuffer( std::size_t reserve_size, std::size_t TSize )
{}
} // namespace fgl::engine

View File

@@ -0,0 +1,24 @@
//
// Created by kj16609 on 10/12/24.
//
#include <cstdint>
#include "engine/descriptors/Descriptor.hpp"
namespace fgl::engine
{
class UBOBuffer
{
// descriptors::Descriptor descriptor;
public:
UBOBuffer( std::size_t reserve_size, std::size_t TSize );
//! Updates a index with the given `data` pointer. `data + TSize` must be valid
void updateData( std::size_t idx, void* data );
};
} // namespace fgl::engine

View File

@@ -0,0 +1,144 @@
//
// Created by kj16609 on 10/12/24.
//
#include "Material.hpp"
#include "engine/FrameInfo.hpp"
#include "engine/assets/texture/Texture.hpp"
#include "engine/descriptors/DescriptorSet.hpp"
#include "engine/memory/buffers/vector/DeviceVector.hpp"
#include "engine/utility/IDPool.hpp"
namespace fgl::engine
{
inline static IDPool< MaterialID > material_id_counter { 1 };
void MaterialProperties::writeData( DeviceMaterialData& data ) const
{
auto getTexID = []( const std::shared_ptr< Texture >& tex )
{
if ( tex ) return tex->getID();
return constants::INVALID_TEXTURE_ID;
};
// PBR
data.color_texture_id = getTexID( pbr.color_tex );
data.color_factors = pbr.color_factors;
data.metallic_texture_id = getTexID( pbr.metallic_roughness_tex );
data.roughness_factor = pbr.roughness_factor;
data.roughness_factor = pbr.roughness_factor;
// Normal
data.normal_texture_id = getTexID( normal.texture );
data.normal_tex_scale = normal.scale;
// Occlusion
data.occlusion_texture_id = getTexID( occlusion.texture );
data.occlusion_tex_strength = occlusion.strength;
// Emissive
data.emissive_texture_id = getTexID( emissive.texture );
data.emissive_factors = emissive.factors;
}
DeviceMaterialData MaterialProperties::data() const
{
DeviceMaterialData data {};
writeData( data );
return data;
}
Material::Material() : m_id( material_id_counter.getID() )
{
update();
getDescriptorSet().bindArray( 0, getDeviceMaterialGPUData().getHandle(), m_id, sizeof( DeviceMaterialData ) );
getDescriptorSet().update();
}
bool Material::ready() const
{
auto checkTex = []( const std::shared_ptr< Texture >& tex )
{
if ( tex )
{
return tex->ready();
}
return true;
};
return checkTex( properties.pbr.color_tex ) && checkTex( properties.pbr.metallic_roughness_tex )
&& checkTex( properties.normal.texture ) && checkTex( properties.occlusion.texture )
&& checkTex( properties.emissive.texture );
}
std::shared_ptr< Material > Material::createMaterial()
{
return std::shared_ptr< Material >( new Material() );
}
Material::~Material()
{
material_id_counter.markUnused( m_id );
}
inline static std::unique_ptr< DeviceVector< DeviceMaterialData > > material_data {};
void initMaterialDataVec( memory::Buffer& buffer )
{
material_data = std::make_unique< DeviceVector< DeviceMaterialData > >( buffer, MAX_MATERIAL_COUNT );
}
DeviceVector< DeviceMaterialData >& getDeviceMaterialGPUData()
{
if ( material_data )
return *material_data;
else
throw std::runtime_error( "Material data gpu buffer not initalized!" );
}
void Material::update()
{
auto& data_vec { getDeviceMaterialGPUData() };
data_vec.updateData( m_id, properties.data() );
}
MaterialID Material::getID() const
{
return m_id;
}
inline static descriptors::DescriptorSetLayout material_descriptor_set { MATERIAL_SET_ID, material_descriptor };
descriptors::DescriptorSetLayout& Material::getDescriptorLayout()
{
return material_descriptor_set;
}
descriptors::DescriptorSet& Material::getDescriptorSet()
{
static std::unique_ptr< descriptors::DescriptorSet > set { nullptr };
if ( set ) [[likely]]
return *set;
else
{
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() ) );
set->setName( "Material descriptor set" );
return *set;
}
}
} // namespace fgl::engine

View File

@@ -0,0 +1,136 @@
//
// Created by kj16609 on 10/12/24.
//
#pragma once
#include <memory>
#include "engine/types.hpp"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#include "engine/constants.hpp"
#include "engine/descriptors/Descriptor.hpp"
#include "engine/descriptors/DescriptorSetLayout.hpp"
#include "engine/memory/buffers/vector/DeviceVector.hpp"
#include "glm/vec3.hpp"
#include "glm/vec4.hpp"
#pragma GCC diagnostic pop
namespace fgl::engine
{
namespace descriptors
{
class DescriptorSet;
}
class Texture;
struct DeviceMaterialData;
constexpr std::size_t MAX_MATERIAL_COUNT { 512 };
constexpr descriptors::Descriptor material_descriptor { 0,
vk::DescriptorType::eUniformBuffer,
vk::ShaderStageFlagBits::eFragment,
MAX_MATERIAL_COUNT,
vk::DescriptorBindingFlagBits::eUpdateAfterBind
| vk::DescriptorBindingFlagBits::ePartiallyBound };
constexpr std::uint16_t MATERIAL_SET_ID { 3 };
struct MaterialProperties
{
struct
{
std::shared_ptr< Texture > color_tex;
glm::vec4 color_factors { 0.0f };
std::shared_ptr< Texture > metallic_roughness_tex;
float metallic_factor { 0.0f };
float roughness_factor { 0.0f };
} pbr;
struct
{
float scale { 0.0f };
std::shared_ptr< Texture > texture;
} normal;
struct
{
float strength { 0.0f };
std::shared_ptr< Texture > texture;
} occlusion;
struct
{
glm::vec3 factors { 0.0f };
std::shared_ptr< Texture > texture;
} emissive;
void writeData( DeviceMaterialData& data ) const;
DeviceMaterialData data() const;
};
using MaterialID = std::uint32_t;
//! 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 };
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 };
TextureID normal_texture_id { constants::INVALID_TEXTURE_ID };
float normal_tex_scale { 0.0f };
TextureID occlusion_texture_id { constants::INVALID_TEXTURE_ID };
float occlusion_tex_strength { 0.0f };
TextureID emissive_texture_id { constants::INVALID_TEXTURE_ID };
glm::vec3 emissive_factors { 0.0f, 0.0f, 0.0f };
};
static_assert( sizeof( DeviceMaterialData ) == 76 );
static_assert( offsetof( DeviceMaterialData, metallic_texture_id ) == 32 );
static_assert( offsetof( DeviceMaterialData, normal_texture_id ) == 44 );
static_assert( offsetof( DeviceMaterialData, occlusion_texture_id ) == 52 );
static_assert( offsetof( DeviceMaterialData, emissive_texture_id ) == 60 );
static_assert( offsetof( DeviceMaterialData, emissive_factors ) == 64 );
class Material
{
MaterialID m_id;
Material();
public:
MaterialProperties properties {};
bool ready() const;
void update();
MaterialID getID() const;
static std::shared_ptr< Material > createMaterial();
~Material();
static descriptors::DescriptorSetLayout& getDescriptorLayout();
static descriptors::DescriptorSet& getDescriptorSet();
};
DeviceVector< DeviceMaterialData >& getDeviceMaterialGPUData();
void initMaterialDataVec( memory::Buffer& buffer );
} // namespace fgl::engine

View File

@@ -15,6 +15,7 @@
#include <vector>
#include "Primitive.hpp"
#include "engine/assets/material/Material.hpp"
#include "engine/primitives/boxes/OrientedBoundingBox.hpp"
namespace fgl::engine
@@ -29,9 +30,7 @@ namespace fgl::engine
struct ModelMatrixInfo
{
glm::mat4 model_matrix;
//MaterialID material_id;
std::uint32_t albedo_id;
std::uint32_t normal_id;
MaterialID material_id { constants::INVALID_TEXTURE_ID };
};
class Model

View File

@@ -55,8 +55,7 @@ namespace fgl::engine
attribute_descriptions.emplace_back( 6, 1, vk::Format::eR32G32B32A32Sfloat, 2 * sizeof( glm::vec4 ) );
attribute_descriptions.emplace_back( 7, 1, vk::Format::eR32G32B32A32Sfloat, 3 * sizeof( glm::vec4 ) );
attribute_descriptions.emplace_back( 8, 1, vk::Format::eR32Uint, offsetof( ModelMatrixInfo, albedo_id ) );
attribute_descriptions.emplace_back( 9, 1, vk::Format::eR32Uint, offsetof( ModelMatrixInfo, normal_id ) );
attribute_descriptions.emplace_back( 8, 1, vk::Format::eR32Uint, offsetof( ModelMatrixInfo, material_id ) );
return attribute_descriptions;
}

View File

@@ -4,9 +4,66 @@
#include "Primitive.hpp"
#include "engine/assets/material/Material.hpp"
#include "engine/assets/texture/Texture.hpp"
namespace fgl::engine
{
bool PrimitiveTextures::ready() const
{
if ( albedo )
{
if ( !albedo->ready() ) return false;
}
if ( normal )
{
if ( !normal->ready() ) return false;
}
if ( metallic_roughness )
{
if ( !metallic_roughness->ready() ) return false;
}
return true;
}
bool Primitive::ready() const
{
return m_material->ready() && m_vertex_buffer.ready() && m_index_buffer.ready();
}
Primitive::Primitive(
VertexBufferSuballocation&& vertex_buffer,
IndexBufferSuballocation&& index_buffer,
const OrientedBoundingBox< CoordinateSpace::Model >& bounding_box,
const PrimitiveMode mode ) noexcept :
m_vertex_buffer( std::move( vertex_buffer ) ),
m_index_buffer( std::move( index_buffer ) ),
m_bounding_box( bounding_box ),
m_mode( mode ),
m_material()
{
assert( m_bounding_box.m_transform.scale != glm::vec3( 0.0f ) );
}
Primitive::Primitive(
VertexBufferSuballocation&& vertex_buffer,
IndexBufferSuballocation&& index_buffer,
const OrientedBoundingBox< CoordinateSpace::Model >& bounding_box,
std::shared_ptr< Material >&& material,
const PrimitiveMode mode ) :
m_vertex_buffer( std::move( vertex_buffer ) ),
m_index_buffer( std::move( index_buffer ) ),
m_bounding_box( bounding_box ),
m_mode( mode ),
m_material( material )
{
assert( m_bounding_box.m_transform.scale != glm::vec3( 0.0f ) );
}
Primitive Primitive::fromVerts(
const std::vector< ModelVertex >&& verts,
const PrimitiveMode mode,
@@ -21,22 +78,6 @@ namespace fgl::engine
return { std::move( vertex_buffer_suballoc ), std::move( index_buffer_suballoc ), bounds, mode };
}
TextureID Primitive::getAlbedoTextureID() const
{
if ( m_textures.albedo )
return m_textures.albedo->getID();
else
return constants::INVALID_TEXTURE_ID;
}
TextureID Primitive::getNormalTextureID() const
{
if ( m_textures.normal )
return m_textures.normal->getID();
else
return constants::INVALID_TEXTURE_ID;
}
OrientedBoundingBox< CoordinateSpace::Model > Primitive::getBoundingBox() const
{
return m_bounding_box;

View File

@@ -6,21 +6,20 @@
#include <cstdint>
#include "ModelVertex.hpp"
#include "engine/memory/buffers/vector/DeviceVector.hpp"
#include "engine/primitives/CoordinateSpace.hpp"
#include "engine/primitives/boxes/OrientedBoundingBox.hpp"
#include "engine/texture/Texture.hpp"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Weffc++"
#include "engine/primitives/TransformComponent.hpp"
#include "ModelVertex.hpp"
#include "engine/memory/buffers/vector/DeviceVector.hpp"
#include "engine/primitives/boxes/OrientedBoundingBox.hpp"
#include "objectloaders/tiny_gltf.h"
#pragma GCC diagnostic pop
namespace fgl::engine
{
class Material;
class Texture;
using VertexBufferSuballocation = DeviceVector< ModelVertex >;
using IndexBufferSuballocation = DeviceVector< std::uint32_t >;
@@ -44,25 +43,7 @@ namespace fgl::engine
bool hasTextures() const { return albedo || normal; }
bool ready() const
{
if ( albedo )
{
if ( !albedo->ready() ) return false;
}
if ( normal )
{
if ( !normal->ready() ) return false;
}
if ( metallic_roughness )
{
if ( !metallic_roughness->ready() ) return false;
}
return true;
}
bool ready() const;
};
struct Primitive
@@ -73,41 +54,27 @@ namespace fgl::engine
OrientedBoundingBox< CoordinateSpace::Model > m_bounding_box;
PrimitiveMode m_mode;
PrimitiveTextures m_textures;
// PrimitiveTextures m_textures;
std::shared_ptr< Material > m_material;
std::string m_name { "Unnamed Primitive" };
//! Returns true if the primitive is ready to be rendered (must have all textures, vertex buffer, and index buffer ready)
bool ready() const { return m_textures.ready() && m_vertex_buffer.ready() && m_index_buffer.ready(); }
bool ready() const;
Primitive(
VertexBufferSuballocation&& vertex_buffer,
IndexBufferSuballocation&& index_buffer,
const OrientedBoundingBox< CoordinateSpace::Model >& bounding_box,
const PrimitiveMode mode ) noexcept :
m_vertex_buffer( std::move( vertex_buffer ) ),
m_index_buffer( std::move( index_buffer ) ),
m_bounding_box( bounding_box ),
m_mode( mode ),
m_textures()
{
assert( m_bounding_box.m_transform.scale != glm::vec3( 0.0f ) );
}
PrimitiveMode mode ) noexcept;
Primitive(
VertexBufferSuballocation&& vertex_buffer,
IndexBufferSuballocation&& index_buffer,
const OrientedBoundingBox< CoordinateSpace::Model >& bounding_box,
PrimitiveTextures&& textures,
const PrimitiveMode mode ) :
m_vertex_buffer( std::move( vertex_buffer ) ),
m_index_buffer( std::move( index_buffer ) ),
m_bounding_box( bounding_box ),
m_mode( mode ),
m_textures( std::forward< decltype( m_textures ) >( textures ) )
{
assert( m_bounding_box.m_transform.scale != glm::vec3( 0.0f ) );
}
std::shared_ptr< Material >&& material,
PrimitiveMode mode );
Primitive() = delete;
Primitive( const Primitive& other ) = delete;
@@ -120,9 +87,6 @@ namespace fgl::engine
memory::Buffer& vertex_buffer,
memory::Buffer& index_buffer );
TextureID getAlbedoTextureID() const;
TextureID getNormalTextureID() const;
OrientedBoundingBox< CoordinateSpace::Model > getBoundingBox() const;
};

View File

@@ -4,6 +4,8 @@
#include "ModelBuilder.hpp"
#include <tracy/Tracy.hpp>
#include "engine/assets/model/Primitive.hpp"
namespace fgl::engine
@@ -20,7 +22,7 @@ namespace fgl::engine
throw std::runtime_error( "Unknown model file extension" );
}
void ModelBuilder::loadVerts( std::vector< ModelVertex > verts, std::vector< std::uint32_t > indicies )
void ModelBuilder::loadVerts( const std::vector< ModelVertex >& verts, std::vector< std::uint32_t > indicies )
{
ZoneScoped;
VertexBufferSuballocation vertex_suballoc { this->m_vertex_buffer, verts };

View File

@@ -36,7 +36,7 @@ namespace fgl::engine
void loadModel( const std::filesystem::path& filepath );
void loadObj( const std::filesystem::path& filepath );
void loadGltf( const std::filesystem::path& filepath );
void loadVerts( std::vector< ModelVertex > verts, std::vector< std::uint32_t > indicies );
void loadVerts( const std::vector< ModelVertex >& verts, std::vector< std::uint32_t > indicies );
};
} // namespace fgl::engine

View File

@@ -215,31 +215,7 @@ namespace fgl::engine
getTextureForParameter( const tinygltf::Parameter& parameter, const tinygltf::Model& root )
{
const auto texture_idx { parameter.TextureIndex() };
const tinygltf::Texture& tex_info { root.textures[ texture_idx ] };
const auto source_idx { tex_info.source };
const tinygltf::Image& source { root.images[ source_idx ] };
if ( source.uri.empty() ) throw std::runtime_error( "Unsupported loading method for image (Must be a file)" );
const std::filesystem::path filepath { source.uri };
const auto full_path { m_root / filepath };
const auto sampler_idx { tex_info.sampler };
const tinygltf::Sampler& sampler_info { root.samplers[ sampler_idx ] };
Sampler sampler { sampler_info.minFilter, sampler_info.magFilter, sampler_info.wrapS, sampler_info.wrapT };
std::shared_ptr< Texture > texture { getTextureStore().load( full_path ) };
texture->getImageView().getSampler() = std::move( sampler );
//Prepare the texture into the global system
Texture::getTextureDescriptorSet().bindTexture( 0, texture );
Texture::getTextureDescriptorSet().update();
return texture;
return loadTexture( texture_idx, root );
}
PrimitiveTextures SceneBuilder::loadTextures( const tinygltf::Primitive& prim, const tinygltf::Model& root )
@@ -436,7 +412,8 @@ namespace fgl::engine
// If we have a texcoord then we have a UV map. Meaning we likely have textures to use
if ( !has_texcoord ) return primitive_mesh;
primitive_mesh.m_textures = loadTextures( prim, root );
//primitive_mesh.m_textures = loadTextures( prim, root );
primitive_mesh.m_material = loadMaterial( prim, root );
return primitive_mesh;
}
@@ -469,6 +446,14 @@ namespace fgl::engine
static_cast< float >( data[ 2 ] ) };
}
glm::vec4 convertToVec4( const std::vector< double >& data )
{
return { static_cast< float >( data[ 0 ] ),
static_cast< float >( data[ 1 ] ),
static_cast< float >( data[ 2 ] ),
static_cast< float >( data[ 3 ] ) };
}
WorldTransform SceneBuilder::loadTransform( int node_idx, const tinygltf::Model& root )
{
const auto node { root.nodes[ node_idx ] };
@@ -545,6 +530,76 @@ namespace fgl::engine
Model >( std::move( finished_primitives ), bounding_box, mesh.name.empty() ? "Unnamed Model" : mesh.name );
}
std::shared_ptr< Texture > SceneBuilder::loadTexture( const int tex_id, const tinygltf::Model& root )
{
if ( tex_id == -1 ) return { nullptr };
const tinygltf::Texture& tex_info { root.textures[ tex_id ] };
const auto source_idx { tex_info.source };
const tinygltf::Image& source { root.images[ source_idx ] };
if ( source.uri.empty() ) throw std::runtime_error( "Unsupported loading method for image (Must be a file)" );
const std::filesystem::path filepath { source.uri };
const auto full_path { m_root / filepath };
const auto sampler_idx { tex_info.sampler };
const tinygltf::Sampler& sampler_info { root.samplers[ sampler_idx ] };
Sampler sampler { sampler_info.minFilter, sampler_info.magFilter, sampler_info.wrapS, sampler_info.wrapT };
std::shared_ptr< Texture > texture { getTextureStore().load( full_path ) };
texture->getImageView().getSampler() = std::move( sampler );
//Prepare the texture into the global system
Texture::getDescriptorSet().bindTexture( 0, texture );
Texture::getDescriptorSet().update();
return texture;
}
std::shared_ptr< Material > SceneBuilder::
loadMaterial( const tinygltf::Primitive& prim, const tinygltf::Model& root )
{
const auto& material_id { prim.material };
const auto& gltf_material { root.materials[ material_id ] };
auto material { Material::createMaterial() };
{
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 );
material->properties.pbr.metallic_roughness_tex =
loadTexture( metallic_roughness.metallicRoughnessTexture.index, root );
material->properties.pbr.metallic_factor = metallic_roughness.metallicFactor;
material->properties.pbr.roughness_factor = metallic_roughness.roughnessFactor;
}
{
material->properties.normal.texture = loadTexture( gltf_material.normalTexture.index, root );
material->properties.normal.scale = gltf_material.normalTexture.scale;
}
{
material->properties.occlusion.texture = loadTexture( gltf_material.occlusionTexture.index, root );
material->properties.occlusion.strength = gltf_material.occlusionTexture.strength;
}
{
material->properties.emissive.texture = loadTexture( gltf_material.emissiveTexture.index, root );
material->properties.emissive.factors = convertToVec3( gltf_material.emissiveFactor );
}
material->update();
return material;
}
void SceneBuilder::handleNode( const int node_idx, const tinygltf::Model& root )
{
ZoneScoped;

View File

@@ -16,6 +16,7 @@
#include <filesystem>
#include <vector>
#include "engine/assets/material/Material.hpp"
#include "engine/gameobjects/GameObject.hpp"
#include "engine/primitives/TransformComponent.hpp"
@@ -59,6 +60,9 @@ namespace fgl::engine
WorldTransform loadTransform( int node_idx, const tinygltf::Model& root );
std::shared_ptr< Model > loadModel( const int mesh_idx, const tinygltf::Model& root );
std::shared_ptr< Texture > loadTexture( int tex_id, const tinygltf::Model& root );
std::shared_ptr< fgl::engine::Material >
loadMaterial( const tinygltf::Primitive& prim, const tinygltf::Model& root );
Primitive loadPrimitive( const tinygltf::Primitive& prim, const tinygltf::Model& model );
int getTexcoordCount( const tinygltf::Primitive& prim ) const;

View File

@@ -4,7 +4,7 @@
#pragma once
#include "engine/texture/Texture.hpp"
#include "engine/assets/texture/Texture.hpp"
namespace fgl::engine
{

View File

@@ -18,6 +18,7 @@
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wconversion"
#include "engine/utility/IDPool.hpp"
#include "imgui/backends/imgui_impl_vulkan.h"
#include "objectloaders/stb_image.h"
#pragma GCC diagnostic pop
@@ -25,24 +26,7 @@
namespace fgl::engine
{
static std::queue< TextureID > unused_ids {};
TextureID getNextID()
{
static TextureID id { 1 };
if ( unused_ids.size() > 0 )
{
const TextureID pulled_id { unused_ids.front() };
unused_ids.pop();
log::debug( "Gave ID {} to texture", pulled_id );
return pulled_id;
}
return id++;
}
static IDPool< TextureID > texture_id_pool { 1 };
std::tuple< std::vector< std::byte >, int, int, vk::Format >
loadTexture( const std::filesystem::path& path, vk::Format format = vk::Format::eUndefined )
@@ -126,7 +110,7 @@ namespace fgl::engine
{}
Texture::Texture( std::vector< std::byte >&& data, const vk::Extent2D extent, const vk::Format format ) :
m_texture_id( getNextID() ),
m_texture_id( texture_id_pool.getID() ),
m_image( std::make_shared< Image >(
extent,
format,
@@ -159,7 +143,7 @@ namespace fgl::engine
Texture::~Texture()
{
if ( m_imgui_set != VK_NULL_HANDLE ) ImGui_ImplVulkan_RemoveTexture( m_imgui_set );
unused_ids.push( m_texture_id );
texture_id_pool.markUnused( m_texture_id );
}
vk::DescriptorImageInfo Texture::getDescriptor() const
@@ -209,7 +193,7 @@ namespace fgl::engine
}
Texture::Texture( Image& image, Sampler sampler ) :
m_texture_id( getNextID() ),
m_texture_id( texture_id_pool.getID() ),
m_image(),
m_image_view( image.getView() ),
//TODO: Figure out how to get extents from images.
@@ -236,7 +220,14 @@ namespace fgl::engine
m_image_view->setName( str + " ImageView" );
}
descriptors::DescriptorSet& Texture::getTextureDescriptorSet()
inline static descriptors::DescriptorSetLayout texture_descriptor_set { TEXTURE_SET_ID, texture_descriptor };
descriptors::DescriptorSetLayout& Texture::getDescriptorLayout()
{
return texture_descriptor_set;
}
descriptors::DescriptorSet& Texture::getDescriptorSet()
{
static std::unique_ptr< descriptors::DescriptorSet > set { nullptr };

View File

@@ -28,8 +28,9 @@ namespace fgl::engine
namespace descriptors
{
class DescriptorSetLayout;
class DescriptorSet;
}
} // namespace descriptors
class TextureHandle;
@@ -115,7 +116,8 @@ namespace fgl::engine
void drawImGui( vk::Extent2D extent = {} );
bool drawImGuiButton( vk::Extent2D extent = {} );
static descriptors::DescriptorSet& getTextureDescriptorSet();
static descriptors::DescriptorSetLayout& getDescriptorLayout();
static descriptors::DescriptorSet& getDescriptorSet();
};
} // namespace fgl::engine

View File

@@ -121,7 +121,7 @@ namespace fgl::engine::memory
auto& target { std::get< TransferBufferHandle >( m_target ) };
const CopyRegionKey key { std::make_pair( source->getBuffer(), target->getBuffer() ) };
const auto copy_info { source->copyRegion( *target ) };
const auto copy_info { source->copyRegion( *target, m_target_offset ) };
if ( auto itter = copy_regions.find( key ); itter != copy_regions.end() )
{
@@ -221,20 +221,25 @@ namespace fgl::engine::memory
//! BUFFER_FROM_BUFFER
TransferData::TransferData(
const std::shared_ptr< BufferSuballocationHandle >& source,
const std::shared_ptr< BufferSuballocationHandle >& target ) :
const std::shared_ptr< BufferSuballocationHandle >& target,
const std::size_t offset ) :
m_type( BUFFER_FROM_BUFFER ),
m_source( source ),
m_target( target )
m_target( target ),
m_target_offset( offset )
{
markBad();
}
//! BUFFER_FROM_RAW
TransferData::
TransferData( std::vector< std::byte >&& source, const std::shared_ptr< BufferSuballocationHandle >& target ) :
TransferData::TransferData(
std::vector< std::byte >&& source,
const std::shared_ptr< BufferSuballocationHandle >& target,
const std::size_t offset ) :
m_type( BUFFER_FROM_RAW ),
m_source( std::forward< std::vector< std::byte > >( source ) ),
m_target( target )
m_target( target ),
m_target_offset( offset )
{
markBad();
}

View File

@@ -73,6 +73,8 @@ namespace fgl::engine::memory
//! Target data. Data type depends on m_type
TargetData m_target;
std::size_t m_target_offset;
//! Performs copy of raw data to the staging buffer
bool convertRawToBuffer( Buffer& staging_buffer );
@@ -123,8 +125,13 @@ namespace fgl::engine::memory
//BUFFER_FROM_X
TransferData(
const std::shared_ptr< BufferSuballocationHandle >& source,
const std::shared_ptr< BufferSuballocationHandle >& target );
TransferData( std::vector< std::byte >&& source, const std::shared_ptr< BufferSuballocationHandle >& target );
const std::shared_ptr< BufferSuballocationHandle >& target,
const std::size_t offset );
TransferData(
std::vector< std::byte >&& source,
const std::shared_ptr< BufferSuballocationHandle >& target,
const std::size_t offset );
//IMAGE_FROM_X
TransferData(

View File

@@ -6,11 +6,11 @@
#include "engine/assets/image/Image.hpp"
#include "engine/assets/image/ImageHandle.hpp"
#include "engine/assets/texture/Texture.hpp"
#include "engine/math/literals/size.hpp"
#include "engine/memory/buffers/Buffer.hpp"
#include "engine/memory/buffers/BufferSuballocation.hpp"
#include "engine/memory/buffers/vector/HostVector.hpp"
#include "engine/texture/Texture.hpp"
namespace fgl::engine::memory
{
@@ -46,7 +46,9 @@ namespace fgl::engine::memory
}
}
std::vector< vk::BufferMemoryBarrier > from_memory_barriers { createFromGraphicsBarriers() };
if ( counter > 0 ) log::debug( "Queued {} objects for transfer", counter );
const std::vector< vk::BufferMemoryBarrier > from_memory_barriers { createFromGraphicsBarriers() };
// Acquire the buffer from the queue family
command_buffer.pipelineBarrier(
@@ -65,7 +67,7 @@ namespace fgl::engine::memory
command_buffer.copyBuffer( source, target, regions );
}
std::vector< vk::BufferMemoryBarrier > to_buffer_memory_barriers { createFromTransferBarriers() };
const std::vector< vk::BufferMemoryBarrier > to_buffer_memory_barriers { createFromTransferBarriers() };
// Release the buffer regions back to the graphics queue
command_buffer.pipelineBarrier(
@@ -261,9 +263,9 @@ namespace fgl::engine::memory
return *global_transfer_manager;
}
void TransferManager::copyToVector( BufferVector& source, BufferVector& target )
void TransferManager::copyToVector( BufferVector& source, BufferVector& target, const std::size_t target_offset )
{
TransferData transfer_data { source.getHandle(), target.getHandle() };
TransferData transfer_data { source.getHandle(), target.getHandle(), target_offset };
queue.emplace( std::move( transfer_data ) );
}

View File

@@ -102,17 +102,33 @@ namespace fgl::engine::memory
//! Queues a buffer to be transfered
template < typename DeviceVectorT >
requires is_device_vector< DeviceVectorT >
void copyToVector( std::vector< std::byte >&& data, DeviceVectorT& device_vector )
void copyToVector( std::vector< std::byte >&& data, DeviceVectorT& device_vector, std::size_t byte_offset = 0 )
{
assert( data.size() > 0 );
TransferData transfer_data { std::forward< std::vector< std::byte > >( data ), device_vector.m_handle };
TransferData transfer_data { std::forward< std::vector< std::byte > >( data ),
device_vector.m_handle,
byte_offset };
queue.emplace( std::move( transfer_data ) );
}
template < typename T, typename DeviceVectorT >
requires is_device_vector< DeviceVectorT > && std::same_as< T, typename DeviceVectorT::Type >
void copyToVector( const T& t, const std::size_t idx, DeviceVectorT& device_vector )
{
std::vector< std::byte > data {};
data.resize( sizeof( T ) );
assert( idx < device_vector.bytesize() / sizeof( T ) );
std::memcpy( data.data(), &t, sizeof( T ) );
copyToVector( std::move( data ), device_vector, idx * sizeof( T ) );
}
//! Queues a data copy from a STL vector to a device vector
template < typename T, typename DeviceVectorT >
requires is_device_vector< DeviceVectorT >
requires is_device_vector< DeviceVectorT > && std::same_as< T, typename DeviceVectorT::Type >
void copyToVector( const std::vector< T >& data, DeviceVectorT& device_vector )
{
assert( data.size() > 0 );
@@ -121,10 +137,10 @@ namespace fgl::engine::memory
std::memcpy( punned_data.data(), data.data(), sizeof( T ) * data.size() );
copyToVector( std::move( punned_data ), device_vector );
copyToVector( std::move( punned_data ), device_vector, 0 );
}
void copyToVector( BufferVector& source, BufferVector& target );
void copyToVector( BufferVector& source, BufferVector& target, std::size_t target_offset );
void copyToImage( std::vector< std::byte >&& data, Image& image );

View File

@@ -8,7 +8,6 @@
#include <glm/gtx/string_cast.hpp>
#include <tracy/Tracy.hpp>
#include "CameraDescriptor.hpp"
#include "CameraInfo.hpp"
#include "CameraRenderer.hpp"
#include "CameraSwapchain.hpp"
@@ -319,6 +318,17 @@ namespace fgl::engine
camera_renderer = std::make_unique< CameraRenderer >();
}
constexpr descriptors::Descriptor camera_descriptor { 0,
vk::DescriptorType::eUniformBuffer,
vk::ShaderStageFlagBits::eAllGraphics };
inline static descriptors::DescriptorSetLayout camera_descriptor_set { 1, camera_descriptor };
descriptors::DescriptorSetLayout& Camera::getDescriptorLayout()
{
return camera_descriptor_set;
}
Camera::Camera( const vk::Extent2D extent, memory::Buffer& buffer ) :
m_transform(),
m_target_extent( extent ),

View File

@@ -28,6 +28,10 @@ namespace vk::raii
namespace fgl::engine
{
namespace descriptors
{
class DescriptorSetLayout;
}
class Image;
struct FrameInfo;
class CameraRenderer;
@@ -185,6 +189,8 @@ namespace fgl::engine
void copyOutput( const vk::raii::CommandBuffer& command_buffer, FrameIndex frame_index, Image& target );
void updateMatrix();
static descriptors::DescriptorSetLayout& getDescriptorLayout();
#ifdef EXPOSE_CAMERA_TESTS
Camera CREATE_TESTING_CAMERA() { return { { 1920, 1080 } }; }
@@ -192,4 +198,6 @@ namespace fgl::engine
#endif
};
descriptors::DescriptorSetLayout& getCameraDescriptorSet();
} // namespace fgl::engine

View File

@@ -1,16 +0,0 @@
//
// Created by kj16609 on 7/27/24.
//
#pragma once
#include "engine/descriptors/DescriptorSetLayout.hpp"
namespace fgl::engine
{
constexpr descriptors::Descriptor camera_descriptor { 0,
vk::DescriptorType::eUniformBuffer,
vk::ShaderStageFlagBits::eAllGraphics };
inline static descriptors::DescriptorSetLayout camera_descriptor_set { 1, camera_descriptor };
} // namespace fgl::engine

View File

@@ -47,8 +47,6 @@ namespace fgl::engine::constants
constexpr glm::vec3 WORLD_LEFT { -WORLD_RIGHT };
constexpr glm::vec3 WORLD_DOWN { -WORLD_UP };
constexpr std::uint32_t INVALID_TEX_ID { std::numeric_limits< std::uint32_t >::max() };
constexpr TextureID INVALID_TEXTURE_ID { 0 };
} // namespace fgl::engine::constants

View File

@@ -11,14 +11,14 @@
#include "DescriptorPool.hpp"
#include "engine/assets/image/ImageView.hpp"
#include "engine/assets/texture/Texture.hpp"
#include "engine/memory/buffers/BufferSuballocation.hpp"
#include "engine/rendering/SwapChain.hpp"
#include "engine/texture/Texture.hpp"
namespace fgl::engine::descriptors
{
DescriptorSet::DescriptorSet( const vk::raii::DescriptorSetLayout& layout, std::uint16_t idx ) :
DescriptorSet::DescriptorSet( const vk::raii::DescriptorSetLayout& layout, DescriptorIDX idx ) :
m_set_idx( idx ),
m_set( DescriptorPool::getInstance().allocateSet( layout ) )
{}
@@ -46,7 +46,7 @@ namespace fgl::engine::descriptors
return *this;
}
void DescriptorSet::bindUniformBuffer( std::uint32_t binding_idx, memory::BufferSuballocation& buffer )
void DescriptorSet::bindUniformBuffer( const std::uint32_t binding_idx, memory::BufferSuballocation& buffer )
{
assert( binding_idx < m_infos.size() && "Binding index out of range" );
@@ -65,6 +65,34 @@ namespace fgl::engine::descriptors
descriptor_writes.push_back( write );
}
void DescriptorSet::bindArray(
const std::uint32_t binding_idx,
const memory::BufferSuballocation& buffer,
const std::size_t array_idx,
const std::size_t item_size )
{
assert( binding_idx < m_infos.size() && "Binding index out of range" );
m_infos[ binding_idx ] = buffer.descriptorInfo( array_idx * item_size );
//HACK: We set the range to something else after getting it
std::get< vk::DescriptorBufferInfo >( m_infos[ binding_idx ] ).range = item_size;
vk::WriteDescriptorSet write {};
write.dstSet = m_set;
write.dstBinding = binding_idx;
write.dstArrayElement = array_idx;
write.descriptorCount = 1;
write.descriptorType = vk::DescriptorType::eUniformBuffer;
write.pBufferInfo = &( std::get< vk::DescriptorBufferInfo >( m_infos.data()[ binding_idx ] ) );
write.pImageInfo = VK_NULL_HANDLE;
write.pTexelBufferView = VK_NULL_HANDLE;
log::info( "Bound idx {} to data", array_idx );
descriptor_writes.push_back( write );
}
void DescriptorSet::
bindImage( std::uint32_t binding_idx, ImageView& view, vk::ImageLayout layout, vk::raii::Sampler sampler )
{

View File

@@ -9,7 +9,6 @@
#include <variant>
#include "engine/memory/buffers/BufferSuballocation.hpp"
#include "engine/rendering/types.hpp"
namespace fgl::engine
{
@@ -26,9 +25,11 @@ namespace fgl::engine
namespace fgl::engine::descriptors
{
using DescriptorIDX = std::uint32_t;
class DescriptorSet
{
std::uint16_t m_set_idx;
DescriptorIDX m_set_idx;
//TODO: Maybe redo this to not be a monostate variant?
std::vector< std::variant< std::monostate, vk::DescriptorImageInfo, vk::DescriptorBufferInfo > > m_infos {};
std::vector< vk::WriteDescriptorSet > descriptor_writes {};
@@ -52,10 +53,10 @@ namespace fgl::engine::descriptors
VkDescriptorSet getVkDescriptorSet() const { return *m_set; }
inline std::uint16_t setIDX() const { return m_set_idx; }
inline DescriptorIDX setIDX() const { return m_set_idx; }
DescriptorSet() = delete;
DescriptorSet( const vk::raii::DescriptorSetLayout& layout, const std::uint16_t idx );
DescriptorSet( const vk::raii::DescriptorSetLayout& layout, const DescriptorIDX idx );
//Copy
DescriptorSet( const DescriptorSet& other ) = delete;
@@ -74,6 +75,11 @@ namespace fgl::engine::descriptors
vk::raii::Sampler sampler = VK_NULL_HANDLE );
void bindUniformBuffer( std::uint32_t binding_idx, memory::BufferSuballocation& buffer );
void bindArray(
std::uint32_t binding_idx,
const memory::BufferSuballocation& buffer,
std::size_t array_idx,
std::size_t item_size );
void bindAttachment(
std::uint32_t binding_idx,

View File

@@ -11,7 +11,7 @@ namespace fgl::engine::descriptors
{
DescriptorSetLayout::DescriptorSetLayout(
const std::uint16_t set_idx, const std::vector< std::reference_wrapper< const Descriptor > >& descriptors ) :
const DescriptorIDX set_idx, const std::vector< std::reference_wrapper< const Descriptor > >& descriptors ) :
m_set_idx( set_idx )
{
FGL_ASSERT( descriptors.size() > 0, "Must have more then 1 descriptor set" );

View File

@@ -24,10 +24,10 @@ namespace fgl::engine::descriptors
std::optional< vk::raii::DescriptorSetLayout > m_layout { std::nullopt };
std::uint16_t m_set_idx;
DescriptorIDX m_set_idx;
DescriptorSetLayout(
std::uint16_t set_idx, const std::vector< std::reference_wrapper< const Descriptor > >& descriptors );
DescriptorIDX set_idx, const std::vector< std::reference_wrapper< const Descriptor > >& descriptors );
DescriptorSetLayout();
@@ -39,7 +39,7 @@ namespace fgl::engine::descriptors
friend class ::fgl::engine::PipelineBuilder;
template < typename... Args >
DescriptorSetLayout( const std::uint16_t set_idx, const Args&... descriptors ) :
DescriptorSetLayout( const DescriptorIDX set_idx, const Args&... descriptors ) :
DescriptorSetLayout( set_idx, std::vector< std::reference_wrapper< const Descriptor > > { descriptors... } )
{}

View File

@@ -93,12 +93,12 @@ namespace fgl::engine::memory
return m_handle->buffer.getVkBuffer();
}
vk::DescriptorBufferInfo BufferSuballocation::descriptorInfo() const
vk::DescriptorBufferInfo BufferSuballocation::descriptorInfo( const std::size_t byte_offset ) const
{
assert( !std::isnan( m_offset ) );
assert( !std::isnan( m_byte_size ) );
return vk::DescriptorBufferInfo( getVkBuffer(), m_offset, m_byte_size );
return vk::DescriptorBufferInfo( getVkBuffer(), m_offset + byte_offset, m_byte_size );
}
SuballocationView BufferSuballocation::view( const vk::DeviceSize offset, const vk::DeviceSize size ) const

View File

@@ -64,7 +64,7 @@ namespace fgl::engine::memory
vk::DeviceSize getOffset() const noexcept { return m_offset; }
vk::DescriptorBufferInfo descriptorInfo() const;
vk::DescriptorBufferInfo descriptorInfo( std::size_t byte_offset = 0 ) const;
const std::shared_ptr< BufferSuballocationHandle >& getHandle() { return m_handle; }

View File

@@ -35,20 +35,21 @@ namespace fgl::engine::memory
buffer.free( *this );
}
vk::BufferCopy BufferSuballocationHandle::copyRegion( BufferSuballocationHandle& target )
vk::BufferCopy BufferSuballocationHandle::copyRegion( BufferSuballocationHandle& target, const std::size_t offset )
{
vk::BufferCopy copy {};
copy.size = std::min( this->m_size, target.m_size );
copy.srcOffset = this->getOffset();
copy.dstOffset = target.getOffset();
copy.dstOffset = target.getOffset() + offset;
return copy;
}
void BufferSuballocationHandle::copyTo( vk::raii::CommandBuffer& cmd_buffer, BufferSuballocationHandle& other )
void BufferSuballocationHandle::
copyTo( vk::raii::CommandBuffer& cmd_buffer, BufferSuballocationHandle& other, const std::size_t offset )
{
vk::BufferCopy copy_region { copyRegion( other ) };
const vk::BufferCopy copy_region { copyRegion( other, offset ) };
std::vector< vk::BufferCopy > copy_regions { copy_region };
const std::vector< vk::BufferCopy > copy_regions { copy_region };
cmd_buffer.copyBuffer( this->getVkBuffer(), other.getVkBuffer(), copy_regions );
}

View File

@@ -45,11 +45,11 @@ namespace fgl::engine::memory
vk::Buffer getBuffer();
vk::Buffer getVkBuffer() const;
vk::BufferCopy copyRegion( BufferSuballocationHandle& target );
vk::BufferCopy copyRegion( BufferSuballocationHandle& target, std::size_t offset );
vk::DeviceSize getOffset() const { return m_offset; }
void copyTo( vk::raii::CommandBuffer& cmd_buffer, BufferSuballocationHandle& other );
void copyTo( vk::raii::CommandBuffer& cmd_buffer, BufferSuballocationHandle& other, std::size_t offset );
bool ready() const { return m_staged; }

View File

@@ -53,7 +53,7 @@ namespace fgl::engine::memory
BufferVector other { this->getBuffer(), count, m_stride };
TransferManager::getInstance().copyToVector( *this, other );
TransferManager::getInstance().copyToVector( *this, other, 0 );
*this = std::move( other );
}

View File

@@ -25,6 +25,8 @@ namespace fgl::engine
{
public:
using Type = T;
DeviceVector( memory::Buffer& buffer, const std::uint32_t count = 1 ) :
BufferVector( buffer, count, sizeof( T ) )
{
@@ -41,7 +43,16 @@ namespace fgl::engine
DeviceVector( memory::Buffer& buffer, const std::vector< T >& data ) :
DeviceVector( buffer, static_cast< std::uint32_t >( data.size() ) )
{
memory::TransferManager::getInstance().copyToVector( data, *this );
memory::TransferManager::getInstance().copyToVector< T, DeviceVector< T > >( data, *this );
}
//TODO: This
void resize( const std::size_t new_size );
void updateData( const std::size_t idx, const T& data )
{
assert( idx < m_count );
memory::TransferManager::getInstance().copyToVector< T, DeviceVector< T > >( data, idx, *this );
}
};

View File

@@ -22,37 +22,49 @@
namespace fgl::engine
{
/*
void Renderer::clearInputImage( vk::raii::CommandBuffer& command_buffer )
{
auto& image { getSwapChain().getInputImage( current_present_index ) };
Image& image { getSwapChain().getInputImage( current_present_index ) };
vk::ImageSubresourceRange range {};
range.aspectMask = vk::ImageAspectFlagBits::eColor;
range.layerCount = 1;
range.baseArrayLayer = 0;
range.levelCount = 1;
range.baseMipLevel = 0;
constexpr vk::ImageSubresourceRange range { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 };
vk::ImageMemoryBarrier in_barrier {};
in_barrier.oldLayout = vk::ImageLayout::eUndefined;
in_barrier.newLayout = vk::ImageLayout::eTransferDstOptimal;
in_barrier.image = image.getVkImage();
in_barrier.subresourceRange = range;
in_barrier.srcAccessMask = {};
in_barrier.dstAccessMask = vk::AccessFlagBits::eTransferWrite;
command_buffer.pipelineBarrier(
vk::PipelineStageFlagBits::eTopOfPipe,
vk::PipelineStageFlagBits::eTransfer,
{},
nullptr,
nullptr,
in_barrier );
/*
command_buffer.clearColorImage(
image.getVkImage(),
vk::ImageLayout::eTransferDstOptimal,
vk::ClearColorValue( 0.0f, 0.0f, 0.0f, 0.0f ),
{ range } );
*/
range );
// Transition the image back to readOnly
vk::ImageMemoryBarrier barrier {};
barrier.oldLayout = vk::ImageLayout::eUndefined;
barrier.newLayout = vk::ImageLayout::eShaderReadOnlyOptimal;
barrier.image = image.getVkImage();
barrier.subresourceRange = range;
barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite;
barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead;
in_barrier.oldLayout = vk::ImageLayout::eTransferDstOptimal;
in_barrier.newLayout = vk::ImageLayout::eShaderReadOnlyOptimal;
in_barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite;
in_barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead;
command_buffer.pipelineBarrier(
vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eFragmentShader, {}, {}, {}, { barrier } );
vk::PipelineStageFlagBits::eTransfer,
vk::PipelineStageFlagBits::eFragmentShader,
{},
nullptr,
nullptr,
in_barrier );
}
*/
Renderer::Renderer( Window& window, PhysicalDevice& phy_device ) :
m_window( window ),

View File

@@ -78,7 +78,7 @@ namespace fgl::engine
SwapChain& getSwapChain() { return *m_swapchain; }
void clearInputImage( vk::raii::CommandBuffer& command_buffer );
// void clearInputImage( vk::raii::CommandBuffer& command_buffer );
Renderer( Window& window, PhysicalDevice& phy_device );
~Renderer();

View File

@@ -28,9 +28,10 @@ namespace fgl::engine
render_attachments( getSwapChainImageFormat(), findDepthFormat() ),
m_render_pass( createRenderPass() ),
m_swap_chain_buffers( createFramebuffers() ),
m_input_descriptors( createInputDescriptors() ),
// m_input_descriptors( createInputDescriptors() ),
m_clear_values(
gatherClearValues( render_attachments.color, render_attachments.depth, render_attachments.input_color ) )
// gatherClearValues( render_attachments.color, render_attachments.depth, render_attachments.input_color ) )
gatherClearValues( render_attachments.color, render_attachments.depth ) )
{
init();
}
@@ -49,9 +50,10 @@ namespace fgl::engine
render_attachments( getSwapChainImageFormat(), findDepthFormat() ),
m_render_pass( createRenderPass() ),
m_swap_chain_buffers( createFramebuffers() ),
m_input_descriptors( createInputDescriptors() ),
// m_input_descriptors( createInputDescriptors() ),
m_clear_values(
gatherClearValues( render_attachments.color, render_attachments.depth, render_attachments.input_color ) )
// gatherClearValues( render_attachments.color, render_attachments.depth, render_attachments.input_color ) )
gatherClearValues( render_attachments.color, render_attachments.depth ) )
{
init();
old_swap_chain.reset();
@@ -69,8 +71,8 @@ namespace fgl::engine
set->setMaxIDX( 0 );
set->bindAttachment(
0, render_attachments.input_color.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal );
// set->bindAttachment(
// 0, render_attachments.input_color.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal );
set->update();
@@ -84,7 +86,7 @@ namespace fgl::engine
{
createSyncObjects();
render_attachments.input_color.setName( "Input Color" );
// render_attachments.input_color.setName( "Input Color" );
}
std::pair< vk::Result, PresentIndex > SwapChain::acquireNextImage()
@@ -244,9 +246,10 @@ namespace fgl::engine
constexpr std::size_t ColorIndex { 0 };
constexpr std::size_t DepthIndex { 1 };
constexpr std::size_t InputColorIndex { 2 };
// constexpr std::size_t InputColorIndex { 2 };
builder.setAttachmentCount( 3 );
// builder.setAttachmentCount( 3 );
builder.setAttachmentCount( 2 );
auto color { builder.attachment( ColorIndex ) };
@@ -260,14 +263,14 @@ namespace fgl::engine
depth.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eDepthStencilAttachmentOptimal );
depth.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eDontCare );
auto color_input { builder.attachment( InputColorIndex ) };
color_input.setFormat( vk::Format::eR8G8B8A8Unorm );
color_input.setLayouts( vk::ImageLayout::eShaderReadOnlyOptimal, vk::ImageLayout::eShaderReadOnlyOptimal );
color_input.setOps( vk::AttachmentLoadOp::eLoad, vk::AttachmentStoreOp::eDontCare );
// auto color_input { builder.attachment( InputColorIndex ) };
// color_input.setFormat( vk::Format::eR8G8B8A8Unorm );
// color_input.setLayouts( vk::ImageLayout::eShaderReadOnlyOptimal, vk::ImageLayout::eShaderReadOnlyOptimal );
// color_input.setOps( vk::AttachmentLoadOp::eLoad, vk::AttachmentStoreOp::eDontCare );
auto& gui_subpass { builder.createSubpass( 0 ) };
gui_subpass.addInputLayout( InputColorIndex, vk::ImageLayout::eShaderReadOnlyOptimal );
// gui_subpass.addInputLayout( InputColorIndex, vk::ImageLayout::eShaderReadOnlyOptimal );
gui_subpass.setDepthLayout( DepthIndex, vk::ImageLayout::eDepthStencilAttachmentOptimal );
gui_subpass.addRenderLayout( ColorIndex, vk::ImageLayout::eColorAttachmentOptimal );
@@ -290,8 +293,8 @@ namespace fgl::engine
render_attachments.depth.createResources( imageCount(), getSwapChainExtent() );
render_attachments.depth.setClear( vk::ClearDepthStencilValue( 1.0f, 0 ) );
render_attachments.input_color
.createResources( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eTransferDst );
// render_attachments.input_color
// .createResources( imageCount(), getSwapChainExtent(), vk::ImageUsageFlagBits::eTransferDst );
std::vector< vk::raii::Framebuffer > framebuffers {};
@@ -300,7 +303,10 @@ namespace fgl::engine
for ( uint8_t i = 0; i < imageCount(); i++ )
{
std::vector< vk::ImageView > attachments { getViewsForFrame(
i, render_attachments.color, render_attachments.depth, render_attachments.input_color ) };
// i, render_attachments.color, render_attachments.depth, render_attachments.input_color ) };
i,
render_attachments.color,
render_attachments.depth ) };
//Fill attachments for this frame
const vk::Extent2D swapChainExtent { getSwapChainExtent() };
@@ -422,16 +428,18 @@ namespace fgl::engine
SwapChain::~SwapChain()
{}
/*
descriptors::DescriptorSet& SwapChain::getInputDescriptor( const PresentIndex present_index )
{
assert( present_index < m_input_descriptors.size() );
return *m_input_descriptors[ present_index ];
}
*/
Image& SwapChain::getInputImage( const PresentIndex present_index ) const
{
return *render_attachments.input_color.m_attachment_resources.m_images[ present_index ];
}
// Image& SwapChain::getInputImage( const PresentIndex present_index ) const
// {
// return *render_attachments.input_color.m_attachment_resources.m_images[ present_index ];
// }
vk::raii::Framebuffer& SwapChain::getFrameBuffer( const PresentIndex present_index )
{

View File

@@ -5,7 +5,7 @@
#include "devices/Device.hpp"
#include "engine/FrameInfo.hpp"
#include "engine/texture/Texture.hpp"
#include "engine/assets/texture/Texture.hpp"
#include "pipelines/Attachment.hpp"
#include "types.hpp"
@@ -38,7 +38,7 @@ namespace fgl::engine
{
ColoredPresentAttachment< 0 > color;
DepthAttachment< 1 > depth;
InputColorAttachment< 2 > input_color { vk::Format::eR8G8B8A8Unorm };
// InputColorAttachment< 2 > input_color { vk::Format::eR8G8B8A8Unorm };
} render_attachments;
vk::raii::RenderPass m_render_pass;
@@ -82,7 +82,7 @@ namespace fgl::engine
descriptors::DescriptorSet& getInputDescriptor( const PresentIndex present_index );
Image& getInputImage( PresentIndex present_index ) const;
// Image& getInputImage( PresentIndex present_index ) const;
const std::vector< vk::ClearValue >& getClearValues() const { return m_clear_values; }

View File

@@ -70,6 +70,7 @@ namespace fgl::engine
indexing_features.setDescriptorBindingPartiallyBound( VK_TRUE );
indexing_features.setShaderSampledImageArrayNonUniformIndexing( VK_TRUE );
indexing_features.setDescriptorBindingSampledImageUpdateAfterBind( VK_TRUE );
indexing_features.setDescriptorBindingUniformBufferUpdateAfterBind( VK_TRUE );
return indexing_features;
}

View File

@@ -21,7 +21,9 @@ namespace fgl::engine
}
void Pipeline::bindDescriptor(
vk::raii::CommandBuffer& command_buffer, DescriptorIDX descriptor_idx, descriptors::DescriptorSet& set )
vk::raii::CommandBuffer& command_buffer,
const descriptors::DescriptorIDX descriptor_idx,
descriptors::DescriptorSet& set )
{
const std::vector< vk::DescriptorSet > sets { *set };
constexpr std::vector< std::uint32_t > offsets {};

View File

@@ -5,12 +5,16 @@
#include <memory>
#include "engine/assets/model/Primitive.hpp"
#include "engine/descriptors/DescriptorSet.hpp"
#include "engine/rendering/pipelines/Shader.hpp"
namespace fgl::engine
{
using DescriptorIDX = std::uint32_t;
{
namespace descriptors
{
class DescriptorSet;
}
class Pipeline
{
@@ -24,7 +28,7 @@ namespace fgl::engine
void bind( vk::raii::CommandBuffer& );
void bindDescriptor( vk::raii::CommandBuffer&, DescriptorIDX descriptor_idx, descriptors::DescriptorSet& set );
void bindDescriptor( vk::raii::CommandBuffer&, descriptors::DescriptorIDX descriptor_idx, descriptors::DescriptorSet& set );
void bindDescriptor( vk::raii::CommandBuffer& comd_buffer, descriptors::DescriptorSet& set );
void setDebugName( const char* str );

View File

@@ -4,8 +4,6 @@
#include "CompositionSystem.hpp"
#include <engine/texture/Texture.hpp>
#include "engine/rendering/pipelines/v2/AttachmentBuilder.hpp"
#include "engine/rendering/pipelines/v2/Pipeline.hpp"
#include "engine/rendering/pipelines/v2/PipelineBuilder.hpp"
@@ -19,8 +17,6 @@ namespace fgl::engine
PipelineBuilder builder { render_pass, SUBPASS };
FGL_ASSERT( gbuffer_set.count() == 3, "Aaaa" );
builder.addDescriptorSet( gbuffer_set );
builder.addColorAttachment().finish();

View File

@@ -66,22 +66,21 @@ namespace fgl::engine
//assert( primitive.m_texture );
const ModelMatrixInfo matrix_info { .model_matrix = matrix,
.albedo_id = primitive.getAlbedoTextureID(),
.normal_id = primitive.getNormalTextureID() };
.material_id = primitive.m_material->getID() };
// If the textureless flag is on and we have a texture then skip the primitive.c
if ( tree_flags & IS_TEXTURELESS )
{
if ( primitive.m_textures.hasTextures() ) continue;
if ( primitive.m_material != nullptr ) continue;
}
else
{
// Flag is not present
if ( !primitive.m_textures.hasTextures() ) continue;
if ( primitive.m_material == nullptr ) continue;
}
const auto key {
std::make_pair( matrix_info.albedo_id, primitive.m_index_buffer.getOffset() )
std::make_pair( matrix_info.material_id, primitive.m_index_buffer.getOffset() )
};
//debug::drawBoundingBox( matrix * primitive.m_bounding_box );

View File

@@ -3,13 +3,14 @@
//
#pragma once
#include <vulkan/vulkan.hpp>
#include "engine/gameobjects/GameObject.hpp"
#include "engine/primitives/Frustum.hpp"
#include "engine/texture/Texture.hpp"
#include "engine/utils.hpp"
namespace fgl::engine
{
struct Frustum;
class OctTreeNode;
struct ModelMatrixInfo;
// <TextureID, MemoryOffset>

View File

@@ -8,6 +8,7 @@
#include <vulkan/vulkan.hpp>
#include "DrawPair.hpp"
#include "engine/assets/material/Material.hpp"
#include "engine/camera/Camera.hpp"
#include "engine/debug/profiling/counters.hpp"
#include "engine/rendering/pipelines/v2/AttachmentBuilder.hpp"
@@ -27,7 +28,7 @@ namespace fgl::engine
PipelineBuilder builder { render_pass, 0 };
builder.addDescriptorSet( camera_descriptor_set );
builder.addDescriptorSet( Camera::getDescriptorLayout() );
builder.addColorAttachment().finish();
builder.addColorAttachment().finish();
@@ -54,8 +55,9 @@ namespace fgl::engine
builder.addColorAttachment().finish();
builder.addColorAttachment().finish();
builder.addDescriptorSet( camera_descriptor_set );
builder.addDescriptorSet( texture_descriptor_set );
builder.addDescriptorSet( Camera::getDescriptorLayout() );
builder.addDescriptorSet( Texture::getDescriptorLayout() );
builder.addDescriptorSet( Material::getDescriptorLayout() );
builder.setFragmentShader( Shader::loadFragment( "shaders/textured-gbuffer.frag" ) );
builder.setVertexShader( Shader::loadVertex( "shaders/textured-gbuffer.vert" ) );
@@ -98,6 +100,7 @@ namespace fgl::engine
void EntityRendererSystem::texturelessPass( const FrameInfo& info )
{
/*
ZoneScopedN( "Textureless pass" );
auto& command_buffer { info.command_buffer };
TracyVkZone( info.tracy_ctx, *command_buffer, "Render textureless entities" );
@@ -136,6 +139,7 @@ namespace fgl::engine
draw_parameter_buffer->getOffset(),
draw_parameter_buffer->size(),
draw_parameter_buffer->stride() );
*/
}
void EntityRendererSystem::texturedPass( const FrameInfo& info )
@@ -144,20 +148,17 @@ namespace fgl::engine
auto& command_buffer { info.command_buffer };
TracyVkZone( info.tracy_ctx, *command_buffer, "Render textured entities" );
m_textured_pipeline->bind( command_buffer );
// Since the camera was bound in the textureless pass we shouldn't need to bind it here too.
// m_textured_pipeline
// ->bindDescriptor( command_buffer, CameraDescriptorSet::m_set_idx, info.global_descriptor_set );
m_standard_pipeline->bindDescriptor( command_buffer, info.getCameraDescriptor() );
m_textured_pipeline->bindDescriptor( command_buffer, Texture::getTextureDescriptorSet() );
auto [ draw_commands, model_matricies ] =
getDrawCallsFromTree( info.game_objects, info.camera->getFrustumBounds(), IS_VISIBLE | IS_ENTITY );
if ( draw_commands.empty() ) return;
m_textured_pipeline->bind( command_buffer );
m_textured_pipeline->bindDescriptor( command_buffer, info.getCameraDescriptor() );
m_textured_pipeline->bindDescriptor( command_buffer, Texture::getDescriptorSet() );
m_textured_pipeline->bindDescriptor( command_buffer, Material::getDescriptorSet() );
profiling::addModelDrawn( model_matricies.size() );
auto& model_matrix_info_buffer { m_textured_model_matrix_info_buffers[ info.frame_idx ] };

View File

@@ -9,8 +9,6 @@
#include "engine/assets/model/Model.hpp"
#include "engine/memory/buffers/vector/HostVector.hpp"
#include "engine/rendering/SwapChain.hpp"
#include "engine/systems/modelRendering/StandardPipeline.hpp"
#include "engine/systems/modelRendering/TexturedPipeline.hpp"
namespace fgl::engine
{

View File

@@ -44,7 +44,7 @@ namespace fgl::engine
m_pipeline->bind( command_buffer );
m_pipeline->bindDescriptor( command_buffer, 0, info.gui_input_descriptor );
// m_pipeline->bindDescriptor( command_buffer, 0, info.gui_input_descriptor );
return command_buffer;
}

View File

@@ -5,9 +5,8 @@
#include "LineDrawer.hpp"
#include "engine/FrameInfo.hpp"
#include "engine/assets/model/ModelVertex.hpp"
#include "engine/assets/model/SimpleVertex.hpp"
#include "engine/camera/CameraDescriptor.hpp"
#include "engine/camera/Camera.hpp"
#include "engine/debug/drawers.hpp"
#include "engine/memory/buffers/vector/HostVector.hpp"
#include "engine/primitives/points/Coordinate.hpp"
@@ -29,7 +28,7 @@ namespace fgl::engine
{
PipelineBuilder builder { render_pass, 0 };
builder.addDescriptorSet( camera_descriptor_set );
builder.addDescriptorSet( Camera::getDescriptorLayout() );
builder.addColorAttachment().finish();
builder.addColorAttachment().finish();

View File

@@ -3,7 +3,6 @@
//
#pragma once
#include "engine/camera/CameraDescriptor.hpp"
#include "engine/descriptors/Descriptor.hpp"
#include "engine/memory/buffers/vector/HostVector.hpp"
#include "engine/rendering/SwapChain.hpp"
@@ -17,18 +16,6 @@ namespace fgl::engine
class LineDrawer
{
/*
using VertexShader = VertexShaderT< "shaders/line.vert" >;
using FragmentShader = FragmentShaderT< "shaders/line.frag" >;
using LinePipeline = PipelineT<
ShaderCollection< VertexShader, FragmentShader >,
descriptors::DescriptorSetCollection< descriptors::EmptyDescriptorSet< 0 >, CameraDescriptorSet > >;
*/
std::unique_ptr< Pipeline > m_pipeline {};
PerFrameArray< std::unique_ptr< HostVector< VertexLine > > > m_line_vertex_buffer {};

View File

@@ -1,26 +0,0 @@
//
// Created by kj16609 on 5/24/24.
//
#pragma once
#include "engine/FrameInfo.hpp"
#include "engine/camera/CameraDescriptor.hpp"
#include "engine/rendering/pipelines/Shader.hpp"
namespace fgl::engine
{
/*
using StandardPipelineVertexShader = VertexShaderT< "shaders/textureless-gbuffer.vert" >;
using StandardPipelineFragShader = FragmentShaderT< "shaders/textureless-gbuffer.frag" >;
using StandardPipelineShaders = ShaderCollection< StandardPipelineVertexShader, StandardPipelineFragShader >;
// using StandardPipelineDescriptorSets = descriptors::DescriptorSetCollection< GlobalDescriptorSet >;
using StandardPipelineDescriptorSets =
descriptors::DescriptorSetCollection< descriptors::EmptyDescriptorSet< 0 >, CameraDescriptorSet >;
//! The standard pipeline is used for models without any form of texturing. They instead rely on Vertex coloring. A UV map is **NOT** expected
using StandardPipeline = PipelineT< StandardPipelineShaders, StandardPipelineDescriptorSets >;
*/
} // namespace fgl::engine

View File

@@ -1,26 +0,0 @@
//
// Created by kj16609 on 5/24/24.
//
#pragma once
#include "engine/FrameInfo.hpp"
#include "engine/rendering/pipelines/Shader.hpp"
namespace fgl::engine
{
/*
using TexturedPipelineVertexShader = VertexShaderT< "shaders/textured-gbuffer.vert" >;
using TexturedPipelineFragShader = FragmentShaderT< "shaders/textured-gbuffer.frag" >;
using TexturedPipelineShaders = ShaderCollection< TexturedPipelineVertexShader, TexturedPipelineFragShader >;
//using TexturedPipelineDescriptorSets =
// descriptors::DescriptorSetCollection< GlobalDescriptorSet, TextureDescriptorSet >;
using TexturedPipelineDescriptorSets = descriptors::
DescriptorSetCollection< descriptors::EmptyDescriptorSet< 0 >, CameraDescriptorSet, TextureDescriptorSet >;
//! The standard pipeline is used for models without any form of texturing. They instead rely on Vertex coloring. A UV map is **NOT** expected
using TexturedPipeline = PipelineT< TexturedPipelineShaders, TexturedPipelineDescriptorSets >;
*/
} // namespace fgl::engine

View File

@@ -1,13 +0,0 @@
| Name | Textured | Normal Textured |
|------------------|----------|-----------------|
| StandardPipeline | [ ] | [ ] |
| TexturedPipeline | [x] | [ ] |

View File

@@ -0,0 +1,49 @@
//
// Created by kj16609 on 10/5/24.
//
#pragma once
#include <queue>
namespace fgl::engine
{
template < typename T >
class IDPool
{
std::queue< T > unused_queue {};
T current;
T getNextID() { return current++; }
public:
IDPool() = delete;
IDPool( const T start_value ) : current( start_value ) {}
void markUnused( const T value ) { unused_queue.push( value ); }
constexpr static bool ALWAYS_NEW_ID { true };
T getID()
{
if constexpr ( ALWAYS_NEW_ID )
{
return getNextID();
}
else
{
if ( unused_queue.empty() )
return getNextID();
else
{
const auto value { unused_queue.front() };
unused_queue.pop();
return value;
}
}
}
};
} // namespace fgl::engine

View File

@@ -1,13 +1,14 @@
#version 450
layout (input_attachment_index = 0, binding = 0) uniform subpassInput i_composite;
//layout (input_attachment_index = 0, binding = 0) uniform subpassInput i_composite;
layout (location = 0) in vec2 in_uv;
layout (location = 0) out vec4 out_color;
void main() {
vec4 composite = subpassLoad(i_composite).xyzw;
out_color = composite;
// vec4 composite = subpassLoad(i_composite).xyzw;
//
// out_color = composite;
out_color = vec4(0.0f, 0.0f, 0.0f, 0.0f);
}

View File

@@ -4,6 +4,4 @@ layout (location = 2) in vec3 normal;
layout (location = 3) in vec2 uv;
layout (location = 4) in mat4 instance_model_matrix;// 4, 5, 6, 7
layout (location = 8) in uint in_albedo_id;
layout (location = 9) in uint in_normal_id;
layout (location = 10) in uint in_metallic_roughness_id;
layout (location = 8) in uint in_material_id;

61
src/shaders/pbr/pbr.frag Normal file
View File

@@ -0,0 +1,61 @@
#version 450
layout (location = 0) in vec3 in_normal;
layout (location = 1) in vec2 in_tex_coord;
layout (location = 2) in flat uint material_id;
layout(set = 2, binding = 0) uniform sampler2D tex[];
//TODO: Sort this to be nice and not padded to shit
struct Material {
uint color_tex_id;
vec4 color_factors;
uint metallic_roughness_tex_id;
float metallic_factor;
float roughness_factor;
uint normal_tex_id;
float normal_scale;
uint occlusion_tex_id;
float occlusion_strength;
uint emissive_tex_id;
vec3 emissive_factors;
};
layout(set = 3, binding = 0) uniform Material[] materials;
void main() {
out_position = vec4(in_world_pos, 1.0f);
vec3 N = vec3(0.0f);
const uint in_normal_idx = materials[material_id].normal_tex_id;
const uint in_albedo_idx = materials[material_id].color_tex_id;
if (in_normal_idx == INVALID_TEXTURE_ID)
{
N = normalize(in_normal);
}
else
{
N = texture(tex[in_normal_idx], in_tex_coord).xyz;
}
out_normal = vec4(N, 1.0);
vec4 tex_value = texture(tex[in_albedo_idx], in_tex_coord);
if (tex_value.a < 1.0)
{
discard;
}
out_albedo = tex_value;
out_position.a = linearDepth(out_position.z);
}

31
src/shaders/pbr/pbr.vert Normal file
View File

@@ -0,0 +1,31 @@
#version 450
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
layout (location = 2) in vec3 normal;
layout (location = 3) in vec2 uv;
layout (location = 4) in mat4 instance_model_matrix;// 4, 5, 6, 7
layout (location = 8) in uint material_id;
layout (location = 0) out vec3 out_normal;
layout (location = 1) out vec2 out_tex_coord;
layout (location = 2) out flat uint out_material_id;
void main() {
vec4 pos_world = instance_model_matrix * vec4(position, 1.0);
gl_Position = ubo.projection * ubo.view * pos_world;
mat3 normal_matrix = transpose(inverse(mat3(instance_model_matrix)));
out_normal = normalize(normal_matrix * normal);
out_tex_coord = uv;
out_material_id = material_id;
}

View File

@@ -5,9 +5,7 @@
layout (location = 0) in vec3 in_normal;
layout (location = 1) in vec2 in_tex_coord;
layout (location = 2) in vec3 in_world_pos;
layout (location = 3) in flat uint in_albedo_idx;
layout (location = 4) in flat uint in_normal_idx;
layout (location = 5) in flat uint in_metallic_roughness_idx;
layout (location = 3) in flat uint in_material_id;
#include "include/gbuffer_out.glsl"
@@ -19,6 +17,24 @@ layout (set = 1, binding = 0) uniform CameraInfo {
layout (set = 2, binding = 0) uniform sampler2D tex[];
layout (set = 3, binding = 0) uniform Material {
uint color_texture_id;
vec4 color_factors;
uint metallic_texture_id;
float metallic_factor;
float roughness_factor;
uint normal_texture_id;
float normal_scale;
uint occlusion_texture_id;
float occlusion_strength;
uint emissive_texture_id;
vec3 emissive_factors;
} materials[];
float linearDepth(float depth)
{
float z = depth * 2.0f - 1.0f;
@@ -29,6 +45,13 @@ void main()
{
out_position = vec4(in_world_pos, 1.0f);
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;
}
uint in_normal_idx = materials[in_material_id].normal_texture_id;
vec3 N = vec3(0.0f);
if (in_normal_idx == INVALID_TEXTURE_ID)
@@ -42,6 +65,7 @@ void main()
out_normal = vec4(N, 1.0);
uint in_albedo_idx = materials[in_material_id].color_texture_id;
vec4 tex_value = texture(tex[in_albedo_idx], in_tex_coord);
if (tex_value.a < 1.0)

View File

@@ -7,14 +7,11 @@
layout (location = 0) out vec3 out_normal;
layout (location = 1) out vec2 out_tex_coord;
layout (location = 2) out vec3 out_world_pos;
layout (location = 3) out flat uint out_albedo_id;
layout (location = 4) out flat uint out_normal_id;
layout (location = 5) out flat uint out_metallic_roughness_id;
layout (location = 3) out flat uint out_material_id;
#include "include/camera.glsl"
void main() {
vec4 position_world = instance_model_matrix * vec4(position, 1.0);
gl_Position = ubo.projection * ubo.view * position_world;
@@ -26,6 +23,5 @@ void main() {
out_tex_coord = uv;
out_albedo_id = in_albedo_id;
out_metallic_roughness_id = in_metallic_roughness_id;
out_material_id = in_material_id;
}