Setup for computing and using tangents to determine TBN

This commit is contained in:
2025-07-05 13:19:15 -04:00
parent d8b03bfba9
commit 37ad9e4a2a
25 changed files with 344 additions and 114 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -7,6 +7,7 @@
#include <vector>
#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

View File

@@ -6,6 +6,7 @@
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#pragma GCC diagnostic pop

View File

@@ -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 <glm/mat3x3.hpp>
#include <glm/mat4x4.hpp>
#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

View File

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

View File

@@ -6,7 +6,6 @@
#include <memory>
#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;

View File

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

View File

@@ -4,13 +4,14 @@
#pragma once
#include <variant>
#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 <variant>
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

View File

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

View File

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

View File

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

View File

@@ -1,7 +1,7 @@
#version 450
struct Frustum
public struct Frustum
{
};

View File

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

View File

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

View File

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