From 37ad9e4a2a54bd498bc0d2b0044132d14805af7e Mon Sep 17 00:00:00 2001 From: kj16609 Date: Sat, 5 Jul 2025 13:19:15 -0400 Subject: [PATCH] Setup for computing and using tangents to determine TBN --- src/editor/src/components/ModelComponent.cpp | 3 +- .../src/components/TransformComponent.cpp | 64 +++++++++++++- src/engine/EngineContext.cpp | 2 +- src/engine/EngineContext.hpp | 2 +- src/engine/assets/model/Model.cpp | 2 +- src/engine/assets/model/Model.hpp | 19 ++-- src/engine/assets/model/ModelInstance.cpp | 30 +++++++ src/engine/assets/model/ModelInstance.hpp | 19 ++-- src/engine/assets/model/ModelInstanceInfo.hpp | 3 +- src/engine/assets/model/ModelVertex.cpp | 36 ++++---- src/engine/assets/model/ModelVertex.hpp | 1 + src/engine/assets/model/SimpleVertex.cpp | 12 +-- src/engine/assets/model/SimpleVertex.hpp | 1 + src/engine/assets/model/VertexAttribute.hpp | 88 +++++++++++++++++++ .../assets/model/builders/SceneBuilder.cpp | 21 +++-- .../gameobjects/components/ModelComponent.hpp | 17 ++-- .../components/TransformComponent.hpp | 28 +++++- src/engine/primitives/Transform.hpp | 5 +- src/shaders/composition.slang | 14 ++- src/shaders/culling.slang | 5 +- src/shaders/model/vertex.slang | 6 +- src/shaders/objects/frustum.slang | 2 +- src/shaders/objects/gamemodel.slang | 42 +++++---- src/shaders/textured.slang | 24 ++++- src/shaders/vk/drawindexedindirect.slang | 12 +-- 25 files changed, 344 insertions(+), 114 deletions(-) create mode 100644 src/engine/assets/model/VertexAttribute.hpp diff --git a/src/editor/src/components/ModelComponent.cpp b/src/editor/src/components/ModelComponent.cpp index 4835480..0372d87 100644 --- a/src/editor/src/components/ModelComponent.cpp +++ b/src/editor/src/components/ModelComponent.cpp @@ -11,8 +11,7 @@ namespace fgl::engine::components { ModelComponent::ModelComponent( const std::shared_ptr< Model >& model ) : - m_model_instance( model->createInstance() ), - m_transform() + m_model_instance( model->createInstance() ) {} void ModelComponent::drawImGui() diff --git a/src/editor/src/components/TransformComponent.cpp b/src/editor/src/components/TransformComponent.cpp index f1fea9e..e9ca237 100644 --- a/src/editor/src/components/TransformComponent.cpp +++ b/src/editor/src/components/TransformComponent.cpp @@ -8,11 +8,65 @@ namespace fgl::engine::components { + void TransformComponent::triggerUpdate() + { + auto visitorFunc = [ & ]< typename T0 >( T0& to_update ) + { + if constexpr ( std::same_as< T0, std::weak_ptr< ModelInstance > > ) + { + if ( const std::shared_ptr< ModelInstance > model_instance = to_update.lock() ) + { + model_instance->setTransform( m_transform ); + model_instance->flagUpdate(); + } + } + }; + + for ( auto& to_update : m_updatables ) + { + std::visit( visitorFunc, to_update ); + } + } + + TransformComponent::TransformComponent() + {} + TransformComponent::TransformComponent( const WorldTransform& transform ) : m_transform( transform ) {} void TransformComponent::drawImGui() - {} + { + glm::vec3& position = m_transform.translation.vec(); + + if ( ImGui::DragFloat3( "Position", &position.x, 0.1f ) ) + { + triggerUpdate(); + } + + if ( m_transform.rotation.isEuler() ) + { + glm::vec3& rotation = m_transform.rotation.euler().vec(); + if ( ImGui::DragFloat3( "Rotation", &rotation.x, 0.1f ) ) + { + // Clamp high + while ( rotation.x > 180.0f ) rotation.x -= 360.0f; + while ( rotation.y > 180.0f ) rotation.y -= 360.0f; + while ( rotation.z > 180.0f ) rotation.z -= 360.0f; + // Clamp low + while ( rotation.x < -180.0f ) rotation.x += 360.0f; + while ( rotation.y < -180.0f ) rotation.y += 360.0f; + while ( rotation.z < -180.0f ) rotation.z += 360.0f; + + triggerUpdate(); + } + } + + glm::vec3& scale = m_transform.scale; + if ( ImGui::DragFloat3( "Scale", &scale.x, 0.1f ) ) + { + triggerUpdate(); + } + } std::string_view TransformComponent::humanName() const { @@ -28,4 +82,12 @@ namespace fgl::engine::components { return m_transform; } + + void TransformComponent::setTransform( const WorldTransform& transform ) + { + m_transform = transform; + } + + TransformComponent::~TransformComponent() + {} } // namespace fgl::engine::components \ No newline at end of file diff --git a/src/engine/EngineContext.cpp b/src/engine/EngineContext.cpp index cbf6cff..e61b8cd 100644 --- a/src/engine/EngineContext.cpp +++ b/src/engine/EngineContext.cpp @@ -29,7 +29,7 @@ namespace fgl::engine PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > createDrawCommandsDescriptors( PerFrameArray< DeviceVector< vk::DrawIndexedIndirectCommand > >& gpu_draw_commands, - PerFrameArray< DeviceVector< PerVertexInstanceInfo > >& per_vertex_info ) + PerFrameArray< DeviceVector< InstanceRenderInfo > >& per_vertex_info ) { PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > descriptors {}; diff --git a/src/engine/EngineContext.hpp b/src/engine/EngineContext.hpp index 5119b7a..7a9d2e6 100644 --- a/src/engine/EngineContext.hpp +++ b/src/engine/EngineContext.hpp @@ -80,7 +80,7 @@ namespace fgl::engine PerFrameArray< DeviceVector< vk::DrawIndexedIndirectCommand > > m_gpu_draw_commands; //TODO: Outright remove this. Or the one in model buffers. - PerFrameArray< DeviceVector< PerVertexInstanceInfo > >& m_per_vertex_infos; + PerFrameArray< DeviceVector< InstanceRenderInfo > >& m_per_vertex_infos; PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > m_gpu_draw_cmds_desc; MaterialManager m_material_manager {}; diff --git a/src/engine/assets/model/Model.cpp b/src/engine/assets/model/Model.cpp index d542675..484b97d 100644 --- a/src/engine/assets/model/Model.cpp +++ b/src/engine/assets/model/Model.cpp @@ -38,7 +38,7 @@ namespace fgl::engine 1_GiB, vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eTransferDst, vk::MemoryPropertyFlagBits::eDeviceLocal ), - m_generated_instance_info( constructPerFrame< DeviceVector< PerVertexInstanceInfo > >( m_vertex_buffer ) ), + m_generated_instance_info( constructPerFrame< DeviceVector< InstanceRenderInfo > >( m_vertex_buffer ) ), m_primitive_info( m_long_buffer ), m_primitive_instances( m_short_buffer ), m_model_instances( m_short_buffer ) diff --git a/src/engine/assets/model/Model.hpp b/src/engine/assets/model/Model.hpp index 6375a09..c0c5a06 100644 --- a/src/engine/assets/model/Model.hpp +++ b/src/engine/assets/model/Model.hpp @@ -75,20 +75,27 @@ namespace fgl::engine inline static descriptors::DescriptorSetLayout COMMANDS_SET { 2, COMMANDS_DESCRIPTOR, VERTEX_INSTANCE_INFO }; - struct PerVertexInstanceInfo + struct InstanceRenderInfo { alignas( 4 * 4 ) glm::mat4x4 m_model_matrix; - MaterialID material_id; + alignas( 4 * 4 ) glm::mat4x4 m_normal_matrix; + MaterialID m_material_id; + + // This struct is purely for vulkan and type info. + FGL_DELETE_ALL_RO5( InstanceRenderInfo ); }; + static_assert( offsetof( InstanceRenderInfo, m_model_matrix ) == 0 ); static_assert( sizeof( glm::mat4x4 ) == 64 ); - static_assert( offsetof( PerVertexInstanceInfo, m_model_matrix ) == 0 ); - static_assert( offsetof( PerVertexInstanceInfo, material_id ) == 64 ); + static_assert( offsetof( InstanceRenderInfo, m_normal_matrix ) == 64 ); + static_assert( sizeof( glm::mat4x4 ) == 64 ); + + static_assert( offsetof( InstanceRenderInfo, m_material_id ) == 128 ); static_assert( sizeof( MaterialID ) == 4 ); // Padding check - static_assert( sizeof( PerVertexInstanceInfo ) == 64 + ( 4 * 4 ) ); + static_assert( sizeof( InstanceRenderInfo ) == ( 64 * 2 ) + ( 4 * 4 ) ); struct ModelGPUBuffers { @@ -101,7 +108,7 @@ namespace fgl::engine memory::Buffer m_index_buffer; //! Generated by the compute shader, This vector contains the instance info for each primitive. - PerFrameArray< DeviceVector< PerVertexInstanceInfo > > m_generated_instance_info; + PerFrameArray< DeviceVector< InstanceRenderInfo > > m_generated_instance_info; //! contains the core primitive info, like vertex and index offsets and counts IndexedVector< PrimitiveRenderInfo > m_primitive_info; diff --git a/src/engine/assets/model/ModelInstance.cpp b/src/engine/assets/model/ModelInstance.cpp index b5f8c46..ad005ce 100644 --- a/src/engine/assets/model/ModelInstance.cpp +++ b/src/engine/assets/model/ModelInstance.cpp @@ -5,4 +5,34 @@ namespace fgl::engine { + ModelInstance::ModelInstance( + std::vector< PrimitiveInstanceInfoIndex >&& primative_instances, + ModelInstanceInfoIndex&& model_instance, + const std::shared_ptr< Model >& model ) noexcept : + m_model( model ), + m_model_instance( std::move( model_instance ) ), + m_primitive_instances( std::move( primative_instances ) ) + {} + + bool ModelInstance::acquireNeedsUpdate() + { + if ( m_updated ) [[unlikely]] + { + m_updated = false; + return true; + } + + return false; + } + + void ModelInstance::setTransform( const WorldTransform& transform ) + { + ModelInstanceInfo info {}; + info.m_model_matrix = transform.mat4(); + info.m_normal_matrix = glm::transpose( glm::inverse( info.m_model_matrix ) ); + + m_model_instance.update( info ); + + m_updated = true; + } } // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/assets/model/ModelInstance.hpp b/src/engine/assets/model/ModelInstance.hpp index 1eb3e18..ab519c2 100644 --- a/src/engine/assets/model/ModelInstance.hpp +++ b/src/engine/assets/model/ModelInstance.hpp @@ -36,23 +36,14 @@ namespace fgl::engine ModelInstance( std::vector< PrimitiveInstanceInfoIndex >&& primative_instances, ModelInstanceInfoIndex&& model_instance, - const std::shared_ptr< Model >& model ) noexcept : - m_model( model ), - m_model_instance( std::move( model_instance ) ), - m_primitive_instances( std::move( primative_instances ) ) - {} + const std::shared_ptr< Model >& model ) noexcept; + + void flagUpdate() { m_updated = true; } //! Returns the current update state and sets it to false if it was true. - bool acquireNeedsUpdate() - { - if ( m_updated ) [[unlikely]] - { - m_updated = false; - return true; - } + bool acquireNeedsUpdate(); - return false; - } + void setTransform( const WorldTransform& transform ); }; } // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/assets/model/ModelInstanceInfo.hpp b/src/engine/assets/model/ModelInstanceInfo.hpp index 83d0e33..fb44935 100644 --- a/src/engine/assets/model/ModelInstanceInfo.hpp +++ b/src/engine/assets/model/ModelInstanceInfo.hpp @@ -9,7 +9,8 @@ namespace fgl::engine struct ModelInstanceInfo { - glm::mat4 m_matrix { glm::mat4( constants::DEFAULT_MODEL_SCALE ) }; + glm::mat4 m_model_matrix { glm::mat4( constants::DEFAULT_MODEL_SCALE ) }; + glm::mat4 m_normal_matrix { glm::transpose( glm::inverse( m_model_matrix ) ) }; }; using ModelInstanceInfoIndex = IndexedVector< ModelInstanceInfo >::Index; diff --git a/src/engine/assets/model/ModelVertex.cpp b/src/engine/assets/model/ModelVertex.cpp index 7c3344d..d905606 100644 --- a/src/engine/assets/model/ModelVertex.cpp +++ b/src/engine/assets/model/ModelVertex.cpp @@ -14,6 +14,7 @@ #include "Model.hpp" #include "ModelInstance.hpp" +#include "VertexAttribute.hpp" #include "engine/utils.hpp" namespace fgl::engine @@ -29,7 +30,7 @@ namespace fgl::engine { std::vector< vk::VertexInputBindingDescription > binding_descriptions { { 0, sizeof( ModelVertex ), vk::VertexInputRate::eVertex }, - { 1, sizeof( PerVertexInstanceInfo ), vk::VertexInputRate::eInstance } + { 1, sizeof( InstanceRenderInfo ), vk::VertexInputRate::eInstance } }; return binding_descriptions; @@ -37,29 +38,28 @@ namespace fgl::engine std::vector< vk::VertexInputAttributeDescription > ModelVertex::getAttributeDescriptions() { - std::vector< vk::VertexInputAttributeDescription > attribute_descriptions { - SimpleVertex::getAttributeDescriptions() - }; + AttributeBuilder builder { SimpleVertex::getAttributeDescriptions() }; - // {location, binding, format, offset} - // attribute_descriptions.emplace_back( 0, 0, vk::Format::eR32G32B32Sfloat, offsetof( ModelVertex, m_position ) ); - // attribute_descriptions.emplace_back( 1, 0, vk::Format::eR32G32B32Sfloat, offsetof( ModelVertex, m_color ) ); -#pragma GCC diagnostic push +#pragma GCC diagnostic push // TODO: Fix with reflection once we get it in 20 years #pragma GCC diagnostic ignored "-Winvalid-offsetof" - attribute_descriptions.emplace_back( 2, 0, vk::Format::eR32G32B32Sfloat, offsetof( ModelVertex, m_normal ) ); - attribute_descriptions.emplace_back( 3, 0, vk::Format::eR32G32Sfloat, offsetof( ModelVertex, m_uv ) ); + // builder.add< decltype( ModelVertex::m_position ), offsetof( ModelVertex, m_position ) >( 0 ); + // builder.add< decltype( ModelVertex::m_color ), offsetof( ModelVertex, m_color ) >( 0 ); + builder.add< decltype( ModelVertex::m_normal ), offsetof( ModelVertex, m_normal ) >( 0 ); + builder.add< decltype( ModelVertex::m_tangent ), offsetof( ModelVertex, m_tangent ) >( 0 ); + builder.add< decltype( ModelVertex::m_uv ), offsetof( ModelVertex, m_uv ) >( 0 ); #pragma GCC diagnostic pop - //Normal Matrix - attribute_descriptions.emplace_back( 4, 1, vk::Format::eR32G32B32A32Sfloat, 0 ); - attribute_descriptions.emplace_back( 5, 1, vk::Format::eR32G32B32A32Sfloat, 1 * sizeof( glm::vec4 ) ); - 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 ) ); + builder + .add< decltype( InstanceRenderInfo::m_model_matrix ), offsetof( InstanceRenderInfo, m_model_matrix ) >( 1 ); - attribute_descriptions - .emplace_back( 8, 1, vk::Format::eR32Uint, offsetof( PerVertexInstanceInfo, material_id ) ); + builder.add< + decltype( InstanceRenderInfo::m_normal_matrix ), + offsetof( InstanceRenderInfo, m_normal_matrix ) >( 1 ); - return attribute_descriptions; + builder + .add< decltype( InstanceRenderInfo::m_material_id ), offsetof( InstanceRenderInfo, m_material_id ) >( 1 ); + + return builder.get(); } } // namespace fgl::engine diff --git a/src/engine/assets/model/ModelVertex.hpp b/src/engine/assets/model/ModelVertex.hpp index d6cc54e..007c894 100644 --- a/src/engine/assets/model/ModelVertex.hpp +++ b/src/engine/assets/model/ModelVertex.hpp @@ -20,6 +20,7 @@ namespace fgl::engine struct ModelVertex : public SimpleVertex { glm::vec3 m_normal { 0.0f, 0.0f, 0.0f }; + glm::vec3 m_tangent { 0.0f, 0.0f, 0.0f }; glm::vec2 m_uv { 0.0f, 0.0f }; ModelVertex( const glm::vec3 pos, const glm::vec3 color, const glm::vec3 norm, const glm::vec2 uv ) noexcept : diff --git a/src/engine/assets/model/SimpleVertex.cpp b/src/engine/assets/model/SimpleVertex.cpp index bba8786..5a1b883 100644 --- a/src/engine/assets/model/SimpleVertex.cpp +++ b/src/engine/assets/model/SimpleVertex.cpp @@ -7,6 +7,7 @@ #include #include "ModelVertex.hpp" +#include "VertexAttribute.hpp" namespace fgl::engine { @@ -19,11 +20,12 @@ namespace fgl::engine std::vector< vk::VertexInputAttributeDescription > SimpleVertex::getAttributeDescriptions() { - // {location, binding, format, offset} - return { - { 0, 0, vk::Format::eR32G32B32Sfloat, offsetof( SimpleVertex, m_position ) }, - { 1, 0, vk::Format::eR32G32B32Sfloat, offsetof( SimpleVertex, m_color ) }, - }; + AttributeBuilder builder {}; + + builder.add< decltype( SimpleVertex::m_position ), offsetof( SimpleVertex, m_position ) >( 0 ); + builder.add< decltype( SimpleVertex::m_color ), offsetof( SimpleVertex, m_color ) >( 0 ); + + return builder.get(); } } // namespace fgl::engine diff --git a/src/engine/assets/model/SimpleVertex.hpp b/src/engine/assets/model/SimpleVertex.hpp index aa3407f..00ae720 100644 --- a/src/engine/assets/model/SimpleVertex.hpp +++ b/src/engine/assets/model/SimpleVertex.hpp @@ -6,6 +6,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" +#include #include #pragma GCC diagnostic pop diff --git a/src/engine/assets/model/VertexAttribute.hpp b/src/engine/assets/model/VertexAttribute.hpp new file mode 100644 index 0000000..3caa33e --- /dev/null +++ b/src/engine/assets/model/VertexAttribute.hpp @@ -0,0 +1,88 @@ +// +// Created by kj16609 on 7/5/25. +// +#pragma once +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Weffc++" +#pragma GCC diagnostic ignored "-Wduplicated-branches" +#include +#include +#pragma GCC diagnostic pop + +#include "rendering/RenderingFormats.hpp" + +namespace fgl::engine +{ + + template < typename T > + consteval vk::Format format() + { + if constexpr ( std::same_as< T, glm::vec2 > ) // || std::same_as< T, glm::mat2 > ) + { + return vk::Format::eR32G32Sfloat; + } + else if constexpr ( std::same_as< T, glm::vec3 > || std::same_as< T, glm::mat3 > ) + { + return vk::Format::eR32G32B32Sfloat; + } + else if constexpr ( std::same_as< T, glm::vec4 > || std ::same_as< T, glm::mat4 > ) + { + return vk::Format::eR32G32B32A32Sfloat; + } + else if constexpr ( std::same_as< T, std::uint32_t > ) + { + return vk::Format::eR32Uint; + } + else + { + static_assert( false, "Format for type T not given" ); + return vk::Format::eUndefined; + } + } + + class AttributeBuilder + { + std::vector< vk::VertexInputAttributeDescription > m_attributes {}; + + std::size_t m_location_counter { 0 }; + + public: + + AttributeBuilder() = default; + + AttributeBuilder( std::vector< vk::VertexInputAttributeDescription >&& attributes ) : m_attributes( attributes ) + { + m_location_counter = attributes.size(); + } + + template < typename T, std::size_t offset > + void add( std::size_t binding ) + { + if constexpr ( std::same_as< glm::mat4, T > ) + { + for ( std::size_t i = 0; i < 4; ++i ) + m_attributes.emplace_back( + m_location_counter++, + binding, + format< T >(), + offset + ( i * sizeof( glm::vec4 ) ) ); // size vec4, Since each attribute is one row + } + else if constexpr ( std::same_as< T, glm::mat3 > ) + { + for ( std::size_t i = 0; i < 3; ++i ) + m_attributes.emplace_back( + m_location_counter++, + binding, + format< T >(), + offset + ( i * sizeof( glm::vec3 ) ) ); // size vec3, since each attribtue is one row + } + else + { + m_attributes.emplace_back( m_location_counter++, binding, format< T >(), offset ); + } + } + + [[nodiscard]] auto get() const { return m_attributes; } + }; + +} // namespace fgl::engine diff --git a/src/engine/assets/model/builders/SceneBuilder.cpp b/src/engine/assets/model/builders/SceneBuilder.cpp index fbbc805..9840692 100644 --- a/src/engine/assets/model/builders/SceneBuilder.cpp +++ b/src/engine/assets/model/builders/SceneBuilder.cpp @@ -18,6 +18,7 @@ #include "engine/debug/logging/logging.hpp" #include "engine/descriptors/DescriptorSet.hpp" #include "engine/gameobjects/GameObject.hpp" +#include "gameobjects/components/TransformComponent.hpp" namespace fgl::engine { @@ -557,10 +558,10 @@ namespace fgl::engine const auto& pbr_tex_id { metallic_roughness.baseColorTexture.index }; material->properties.pbr.color_tex = loadTexture( pbr_tex_id, root ); - material->properties.pbr.color_factors = { metallic_roughness.baseColorFactor[ 0 ], - metallic_roughness.baseColorFactor[ 1 ], - metallic_roughness.baseColorFactor[ 2 ], - metallic_roughness.baseColorFactor[ 3 ] }; + material->properties.m_pbr.m_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 ); @@ -596,14 +597,16 @@ namespace fgl::engine assert( model ); - std::unique_ptr< components::ModelComponent > component { - std::make_unique< components::ModelComponent >( std::move( model ) ) - }; + auto model_component { std::make_unique< components::ModelComponent >( std::move( model ) ) }; const auto transform { loadTransform( node_idx, root ) }; - // component->updateTransform( transform ); + auto transform_component { std::make_unique< components::TransformComponent >( transform ) }; + transform_component->setTransform( transform ); - obj->addComponent( std::move( component ) ); + transform_component->addUpdateTarget( model_component->getModelInstance() ); + + obj->addComponent( std::move( transform_component ) ); + obj->addComponent( std::move( model_component ) ); obj->addFlag( IsVisible | IsEntity ); diff --git a/src/engine/gameobjects/components/ModelComponent.hpp b/src/engine/gameobjects/components/ModelComponent.hpp index 60e056f..456c4a5 100644 --- a/src/engine/gameobjects/components/ModelComponent.hpp +++ b/src/engine/gameobjects/components/ModelComponent.hpp @@ -6,7 +6,6 @@ #include #include "ComponentIDS.hpp" -#include "TransformComponent.hpp" #include "assets/model/ModelInstance.hpp" #include "interface/GameObjectComponent.hpp" @@ -24,8 +23,6 @@ namespace fgl::engine::components COMPONENT_CLASS( ModelComponent, ModelComponentID ) { std::shared_ptr< ModelInstance > m_model_instance; - TransformComponent m_transform {}; - // In the future this should also contain a handle to the pipeline that is going to be used for rendering this model. public: @@ -37,18 +34,14 @@ namespace fgl::engine::components std::string_view humanName() const override; std::string_view className() const override; + std::shared_ptr< ModelInstance >& getModelInstance() + { + return m_model_instance; + } + virtual ~ModelComponent() override {} - TransformComponent getTransform() const - { - return m_transform; - } - void updateTransform( const TransformComponent& transform ) - { - m_transform = transform; - } - // Model* operator->(); // const Model* operator->() const; diff --git a/src/engine/gameobjects/components/TransformComponent.hpp b/src/engine/gameobjects/components/TransformComponent.hpp index 2437dc2..e39c1af 100644 --- a/src/engine/gameobjects/components/TransformComponent.hpp +++ b/src/engine/gameobjects/components/TransformComponent.hpp @@ -6,17 +6,27 @@ #include "assets/model/ModelInstanceInfo.hpp" #include "interface/GameObjectComponent.hpp" +namespace fgl::engine +{ + class ModelInstance; +} + namespace fgl::engine::components { - COMPONENT_CLASS( TransformComponent, TransformComponentID ) { WorldTransform m_transform; std::shared_ptr< ModelInstanceInfoIndex > m_model_instance_info_index; + using Updatable = std::variant< std::weak_ptr< ModelInstance > >; + + std::vector< Updatable > m_updatables {}; + + void triggerUpdate(); + public: - TransformComponent() = default; + TransformComponent(); explicit TransformComponent( const WorldTransform& transform ); void drawImGui() override; @@ -26,8 +36,18 @@ namespace fgl::engine::components WorldTransform& operator*(); - virtual ~TransformComponent() override - {} + void setTransform( const WorldTransform& transform ); + + ~TransformComponent() override; + + template < typename T > + void addUpdateTarget( const T& unique ) + { + // static_assert( std::constructible_from< Updatable, T >, "T must be Updatable" ); + + m_updatables.emplace_back( unique ); + triggerUpdate(); + } }; } // namespace fgl::engine::components diff --git a/src/engine/primitives/Transform.hpp b/src/engine/primitives/Transform.hpp index 09ff007..5a5ccdf 100644 --- a/src/engine/primitives/Transform.hpp +++ b/src/engine/primitives/Transform.hpp @@ -4,13 +4,14 @@ #pragma once +#include + #include "Scale.hpp" #include "engine/FGL_DEFINES.hpp" #include "engine/debug/logging/logging.hpp" #include "engine/primitives/points/Coordinate.hpp" #include "rotation/QuatRotation.hpp" #include "rotation/UniversalRotation.hpp" -#include namespace fgl::engine { @@ -41,7 +42,7 @@ namespace fgl::engine struct Transform { Coordinate< CType > translation { constants::WORLD_CENTER }; - Scale scale { 1.0f, 1.0f, 1.0f }; + Scale scale { constants::DEFAULT_SCALE }; UniversalRotation rotation { constants::DEFAULT_ROTATION }; //TODO: Figure this out and replace Transform with a template of CType instead diff --git a/src/shaders/composition.slang b/src/shaders/composition.slang index 1afce60..5402e9d 100644 --- a/src/shaders/composition.slang +++ b/src/shaders/composition.slang @@ -96,6 +96,8 @@ CompositeFragment fragmentMain( Vertex vertex ) // r, g, b const vec3 metallic_comb = gbuffer.metallic.SubpassLoad().xyz; + // frag.color = vec4(albedo, 1.0f); + const float metallic = metallic_comb.r; const float roughness = metallic_comb.g; const float occlusion = metallic_comb.b; @@ -120,14 +122,19 @@ CompositeFragment fragmentMain( Vertex vertex ) vec3 Lh = normalize( Li + Lo ); + float t = dot(normal, sun_dir); + + // frag.color = vec4( vec3( t ), 1.0 ); + // frag.color = vec4(normal, 1.0); + float cosLi = max( dot( N, Li ), 0.0 ); float cosLh = max( dot( N, Lh ), 0.0 ); float cosTheta = dot( Li, N ); - vec3 F = schlick( F0, cosTheta ); - float D = ndfGGX( cosLh, roughness ); - float G = gaSchlickGGX( cosLi, cosLo, roughness ); + const vec3 F = schlick( F0, cosTheta ); + const float D = ndfGGX( cosLh, roughness ); + const float G = gaSchlickGGX( cosLi, cosLo, roughness ); vec3 kb = mix( vec3( 1.0 ) - F, vec3( 0.0 ), metallic ); vec3 diffuse_BRDF = kb * albedo; @@ -137,7 +144,6 @@ CompositeFragment fragmentMain( Vertex vertex ) vec3 ambient_lighting = albedo * 0.1; - CompositeFragment frag; frag.color = vec4( direct_lighting + ambient_lighting, 1.0 ); return frag; diff --git a/src/shaders/culling.slang b/src/shaders/culling.slang index ad8881d..6a71964 100644 --- a/src/shaders/culling.slang +++ b/src/shaders/culling.slang @@ -72,10 +72,11 @@ void computeMain( uint3 dispatch_id : SV_DispatchThreadID) commands[ instance_index ] = command; - out_instances[ instance_index ].mat_id = instance.material_id; + out_instances[ instance_index ].material_id = instance.material_id; const ModelInstanceInfo model_instance = model_instances[ instance.model_index ]; - out_instances[ instance_index ].matrix = model_instance.model_matrix; + out_instances[ instance_index ].model_matrix = model_instance.model_matrix; + out_instances[ instance_index ].normal_matrix = model_instance.normal_matrix; } else { diff --git a/src/shaders/model/vertex.slang b/src/shaders/model/vertex.slang index afe95e0..e9c08a7 100644 --- a/src/shaders/model/vertex.slang +++ b/src/shaders/model/vertex.slang @@ -6,14 +6,16 @@ public struct SimpleVertex { public vec3 position; public vec3 color; - public vec3 normal; - public vec2 uv; }; public struct ModelVertex { public SimpleVertex simple; + public vec3 normal; + public vec3 tangent; + public vec2 uv; public mat4x4 model_matrix; + public mat4x4 normal_matrix; public uint material_id; }; diff --git a/src/shaders/objects/frustum.slang b/src/shaders/objects/frustum.slang index 88e4ea2..9aa9b42 100644 --- a/src/shaders/objects/frustum.slang +++ b/src/shaders/objects/frustum.slang @@ -1,7 +1,7 @@ #version 450 -struct Frustum +public struct Frustum { }; diff --git a/src/shaders/objects/gamemodel.slang b/src/shaders/objects/gamemodel.slang index cca3d16..843718f 100644 --- a/src/shaders/objects/gamemodel.slang +++ b/src/shaders/objects/gamemodel.slang @@ -1,29 +1,35 @@ #version 450 -struct PrimitiveRenderInfo { +public struct PrimitiveRenderInfo { //! Where in the buffer the first vertex lies - uint32_t first_vertex; + public uint32_t first_vertex; //! Where in the buffer the first index would be - uint32_t first_index; + public uint32_t first_index; //! Number of indicies there are - uint32_t index_count; + public uint32_t index_count; }; -struct PrimitiveInstanceInfo +// Each primitive has one instance +public struct PrimitiveInstanceInfo { - uint32_t render_info_id; - uint32_t model_index; - uint32_t material_id; -} - -struct InstanceRenderInfo -{ - mat4x4 matrix; - uint32_t mat_id; -} - -struct ModelInstanceInfo { - mat4x4 model_matrix; + public uint32_t render_info_id; + public uint32_t model_index; + public uint32_t material_id; +}; + +// One object exists for each render instance +public struct InstanceRenderInfo +{ + public mat4x4 model_matrix; + public mat4x4 normal_matrix; + public uint32_t material_id; +}; + +// One exists for each model (primitive collection) +public struct ModelInstanceInfo +{ + public mat4x4 model_matrix; + public mat4x4 normal_matrix; }; diff --git a/src/shaders/textured.slang b/src/shaders/textured.slang index 69ca7e9..78392fb 100644 --- a/src/shaders/textured.slang +++ b/src/shaders/textured.slang @@ -29,8 +29,8 @@ CoarseVertex vertexMain( ModelVertex in_vertex ) mat3 normal_matrix = transpose( inverse( mat3( in_vertex.model_matrix ) ) ); - out_vertex.normal = normalize( mul(normal_matrix, in_vertex.simple.normal) ); - out_vertex.tex_coord = in_vertex.simple.uv; + out_vertex.normal = normalize( mul(normal_matrix, in_vertex.normal) ); + out_vertex.tex_coord = in_vertex.uv; out_vertex.material_id = in_vertex.material_id; return out_vertex; @@ -100,10 +100,26 @@ GBufferFragment fragmentMain( CoarseVertex vertex ) frag.metallic = vec3( metallic_scalar, roughness_scalar, occlusion_scalar ); var normal = material.normal; + // if ( normal.isTexture() && false ) if ( normal.isTexture() ) { - const vec3 sample = texture( tex[ normal.texture_id ], vertex.tex_coord ).rgb; - const vec3 scaled_sample = mul( sample, vec3(normal.scale) ); + // TANGENT SPACE WOOOOOOOOOOOOOOOOO + // Y = V + // X = U + // Z = 1 + const vec3 sample = normalize((2.0 * texture( tex[ normal.texture_id ], vertex.tex_coord ).rgb) - 1.0); + // const vec3 sample = texture( tex[ normal.texture_id ], vertex.tex_coord ).rgb; + + // frag.normal = vec4( .scale)), 1.0f ); + + // const vec3 transformed_sample = normalize(mul( vertex.matrix, vec4(sample, 0.0f) ).xyz); + + // const vec3 scaled_sample = sample.xyz * normal.scale; + const vec3 scaled_sample = normalize((vertex.normal_matrix * vec4(sample.xyz, 0.0f)).xyz); + // const vec3 vertex_normal = sample * vertex.normal; + + // Combine the normal into the + frag.normal = vec4( scaled_sample, 1.0 ); } else diff --git a/src/shaders/vk/drawindexedindirect.slang b/src/shaders/vk/drawindexedindirect.slang index 7e1f253..f4f3a02 100644 --- a/src/shaders/vk/drawindexedindirect.slang +++ b/src/shaders/vk/drawindexedindirect.slang @@ -3,13 +3,13 @@ namespace vk { -struct DrawIndexedIndirectCommand +public struct DrawIndexedIndirectCommand { - uint32_t index_count; - uint32_t instance_count; - uint32_t first_index; - int32_t vertex_offset; - uint32_t first_instance; + public uint32_t index_count; + public uint32_t instance_count; + public uint32_t first_index; + public int32_t vertex_offset; + public uint32_t first_instance; }; } \ No newline at end of file