Skip to content

Commit

Permalink
Fix local lights on replacements
Browse files Browse the repository at this point in the history
  • Loading branch information
sultim-t committed Sep 30, 2023
1 parent 5d52c8e commit a825d8a
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 42 deletions.
4 changes: 2 additions & 2 deletions Source/GltfImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1075,11 +1075,11 @@ auto RTGL1::GltfImporter::ParseFile( VkCommandBuffer cmdForTextures,


// local lights
for( const cgltf_node* child : std::span{ mainNode->children, mainNode->children_count } )
for( const cgltf_node* child : std::span{ srcNode->children, srcNode->children_count } )
{
const auto childHash = hashCombine( srcNodeHash, nodeName( child ) );

if( auto l = ParseNodeAsLight( srcNode, childHash, oneGameUnitInMeters ) )
if( auto l = ParseNodeAsLight( child, childHash, oneGameUnitInMeters ) )
{
result_dstModel.localLights.push_back( *l );
}
Expand Down
107 changes: 79 additions & 28 deletions Source/LightManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,43 @@ RTGL1::LightManager::~LightManager()
namespace
{

RTGL1::ShLightEncoded EncodeAsDirectionalLight( const RgLightDirectionalEXT& info, float mult )
RgFloat3D ApplyTransformToPosition( const RgTransform* transform, const RgFloat3D& pos )
{
RgFloat3D direction = info.direction;
RTGL1::Utils::Normalize( direction.data );
if( transform )
{
const auto& m = transform->matrix;
const auto& p = pos.data;
return RgFloat3D{
m[ 0 ][ 0 ] * p[ 0 ] + m[ 0 ][ 1 ] * p[ 1 ] + m[ 0 ][ 2 ] * p[ 2 ] + m[ 0 ][ 3 ],
m[ 1 ][ 0 ] * p[ 0 ] + m[ 1 ][ 1 ] * p[ 1 ] + m[ 1 ][ 2 ] * p[ 2 ] + m[ 1 ][ 3 ],
m[ 2 ][ 0 ] * p[ 0 ] + m[ 2 ][ 1 ] * p[ 1 ] + m[ 2 ][ 2 ] * p[ 2 ] + m[ 2 ][ 3 ],
};
}
return pos;
}

RgFloat3D ApplyTransformToDirection( const RgTransform *transform, const RgFloat3D &dir )
{
if( transform )
{
const auto& m = transform->matrix;
const auto& d = dir.data;
return RgFloat3D{
m[ 0 ][ 0 ] * d[ 0 ] + m[ 0 ][ 1 ] * d[ 1 ] + m[ 0 ][ 2 ] * d[ 2 ],
m[ 1 ][ 0 ] * d[ 0 ] + m[ 1 ][ 1 ] * d[ 1 ] + m[ 1 ][ 2 ] * d[ 2 ],
m[ 2 ][ 0 ] * d[ 0 ] + m[ 2 ][ 1 ] * d[ 1 ] + m[ 2 ][ 2 ] * d[ 2 ],
};
}
return dir;
}

RTGL1::ShLightEncoded EncodeAsDirectionalLight( const RgLightDirectionalEXT& info,
float mult,
const RgTransform* transform )
{
assert( !transform ); // not expected

RgFloat3D direction = RTGL1::Utils::Normalize( info.direction );

float angularRadius = 0.5f * RTGL1::Utils::DegToRad( info.angularDiameterDegrees );
auto fcolor = RTGL1::Utils::UnpackColor4DPacked32< RgFloat3D >( info.color );
Expand All @@ -121,8 +154,12 @@ RTGL1::ShLightEncoded EncodeAsDirectionalLight( const RgLightDirectionalEXT& inf
return lt;
}

RTGL1::ShLightEncoded EncodeAsSphereLight( const RgLightSphericalEXT& info, float mult )
RTGL1::ShLightEncoded EncodeAsSphereLight( const RgLightSphericalEXT& info,
float mult,
const RgTransform* transform )
{
RgFloat3D pos = ApplyTransformToPosition( transform, info.position );

float radius = std::max( RTGL1::MIN_SPHERE_RADIUS, info.radius );
// disk is visible from the point
float area = float( RTGL1::RG_PI ) * radius * radius;
Expand All @@ -137,9 +174,9 @@ RTGL1::ShLightEncoded EncodeAsSphereLight( const RgLightSphericalEXT& info, floa
lt.color[ 1 ] = fcolor.data[ 1 ] * info.intensity / area * mult;
lt.color[ 2 ] = fcolor.data[ 2 ] * info.intensity / area * mult;

lt.data_0[ 0 ] = info.position.data[ 0 ];
lt.data_0[ 1 ] = info.position.data[ 1 ];
lt.data_0[ 2 ] = info.position.data[ 2 ];
lt.data_0[ 0 ] = pos.data[ 0 ];
lt.data_0[ 1 ] = pos.data[ 1 ];
lt.data_0[ 2 ] = pos.data[ 2 ];

lt.data_0[ 3 ] = radius;

Expand All @@ -148,8 +185,11 @@ RTGL1::ShLightEncoded EncodeAsSphereLight( const RgLightSphericalEXT& info, floa

RTGL1::ShLightEncoded EncodeAsTriangleLight( const RgLightPolygonalEXT& info,
const RgFloat3D& unnormalizedNormal,
float mult )
float mult,
const RgTransform* transform )
{
assert( !transform ); // not implemented

RgFloat3D n = unnormalizedNormal;
float len = RTGL1::Utils::Length( n.data );
n.data[ 0 ] /= len;
Expand Down Expand Up @@ -188,10 +228,15 @@ RTGL1::ShLightEncoded EncodeAsTriangleLight( const RgLightPolygonalEXT& info,
return lt;
}

RTGL1::ShLightEncoded EncodeAsSpotLight( const RgLightSpotEXT& info, float mult )
RTGL1::ShLightEncoded EncodeAsSpotLight( const RgLightSpotEXT& info,
float mult,
const RgTransform* transform )
{
RgFloat3D direction = info.direction;
RTGL1::Utils::Normalize( direction.data );
RgFloat3D pos = ApplyTransformToPosition( transform, info.position );

RgFloat3D direction =
ApplyTransformToDirection( transform, RTGL1::Utils::Normalize( info.direction ) );
assert( std::abs( RTGL1::Utils::Length( direction.data ) - 1.0f ) < 0.001f );

float radius = std::max( RTGL1::MIN_SPHERE_RADIUS, info.radius );
float area = float( RTGL1::RG_PI ) * radius * radius;
Expand All @@ -216,9 +261,9 @@ RTGL1::ShLightEncoded EncodeAsSpotLight( const RgLightSpotEXT& info, float mult
lt.color[ 1 ] = fcolor.data[ 1 ] * info.intensity / area * mult;
lt.color[ 2 ] = fcolor.data[ 2 ] * info.intensity / area * mult;

lt.data_0[ 0 ] = info.position.data[ 0 ];
lt.data_0[ 1 ] = info.position.data[ 1 ];
lt.data_0[ 2 ] = info.position.data[ 2 ];
lt.data_0[ 0 ] = pos.data[ 0 ];
lt.data_0[ 1 ] = pos.data[ 1 ];
lt.data_0[ 2 ] = pos.data[ 2 ];

lt.data_0[ 3 ] = radius;

Expand Down Expand Up @@ -381,7 +426,9 @@ float CalculateLightStyle( const std::optional< RgLightAdditionalEXT >& extra,

}

void RTGL1::LightManager::Add( uint32_t frameIndex, const LightCopy& light )
void RTGL1::LightManager::Add( uint32_t frameIndex,
const LightCopy& light,
const RgTransform* transform )
{
std::visit(
ext::overloaded{
Expand All @@ -397,32 +444,35 @@ void RTGL1::LightManager::Add( uint32_t frameIndex, const LightCopy& light )
return;
}

AddInternal( frameIndex,
light.base.uniqueID,
EncodeAsDirectionalLight(
lext, CalculateLightStyle( light.additional, lightstyles ) ) );
AddInternal(
frameIndex,
light.base.uniqueID,
EncodeAsDirectionalLight(
lext, CalculateLightStyle( light.additional, lightstyles ), transform ) );
},
[ & ]( const RgLightSphericalEXT& lext ) {
if( IsLightColorTooDim( lext ) )
{
return;
}

AddInternal( frameIndex,
light.base.uniqueID,
EncodeAsSphereLight(
lext, CalculateLightStyle( light.additional, lightstyles ) ) );
AddInternal(
frameIndex,
light.base.uniqueID,
EncodeAsSphereLight(
lext, CalculateLightStyle( light.additional, lightstyles ), transform ) );
},
[ & ]( const RgLightSpotEXT& lext ) {
if( IsLightColorTooDim( lext ) )
{
return;
}

AddInternal( frameIndex,
light.base.uniqueID,
EncodeAsSpotLight(
lext, CalculateLightStyle( light.additional, lightstyles ) ) );
AddInternal(
frameIndex,
light.base.uniqueID,
EncodeAsSpotLight(
lext, CalculateLightStyle( light.additional, lightstyles ), transform ) );
},
[ & ]( const RgLightPolygonalEXT& lext ) {
if( IsLightColorTooDim( lext ) )
Expand All @@ -441,7 +491,8 @@ void RTGL1::LightManager::Add( uint32_t frameIndex, const LightCopy& light )
light.base.uniqueID,
EncodeAsTriangleLight( lext,
unnormalizedNormal,
CalculateLightStyle( light.additional, lightstyles ) ) );
CalculateLightStyle( light.additional, lightstyles ),
transform ) );
},
},
light.extension );
Expand Down
2 changes: 1 addition & 1 deletion Source/LightManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class LightManager

uint32_t GetLightIndexForShaders( uint32_t frameIndex, uint64_t* pLightUniqueId ) const;

void Add( uint32_t frameIndex, const LightCopy& light );
void Add( uint32_t frameIndex, const LightCopy& light, const RgTransform* transform = nullptr );

void SubmitForFrame( VkCommandBuffer cmd, uint32_t frameIndex );
void BarrierLightGrid( VkCommandBuffer cmd, uint32_t frameIndex );
Expand Down
27 changes: 20 additions & 7 deletions Source/Scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,10 +297,20 @@ RTGL1::UploadResult RTGL1::Scene::UploadPrimitive( uint32_t fr
assert( r != UploadResult::Fail );
}

for( const auto& localLight : replacement->localLights )
for( auto localLight : replacement->localLights )
{
assert( localLight.base.uniqueID != 0 && localLight.base.isExportable );
UploadLight( frameIndex, localLight, lightManager, false );

auto hashCombine = []< typename T >( size_t seed, const T& v ) {
return seed ^
( std::hash< T >{}( v ) + 0x9e3779b9 + ( seed << 6 ) + ( seed >> 2 ) );
};

localLight.base.uniqueID =
hashCombine( localLight.base.uniqueID, mesh.uniqueObjectID );
localLight.base.isExportable = false;

UploadLight( frameIndex, localLight, lightManager, false, &mesh.transform );
}

alreadyReplacedUniqueObjectIDs.insert( mesh.uniqueObjectID );
Expand All @@ -315,11 +325,14 @@ RTGL1::UploadResult RTGL1::Scene::UploadPrimitive( uint32_t fr
: ( mesh.isExportable ? UploadResult::ExportableDynamic : UploadResult::Dynamic );
}

RTGL1::UploadResult RTGL1::Scene::UploadLight( uint32_t frameIndex,
const LightCopy& light,
LightManager& lightManager,
bool isStatic )
RTGL1::UploadResult RTGL1::Scene::UploadLight( uint32_t frameIndex,
const LightCopy& light,
LightManager& lightManager,
bool isStatic,
const RgTransform* transform )
{
assert( !isStatic || ( isStatic && !transform ) );

bool isExportable = light.base.isExportable;

if( !isStatic )
Expand All @@ -341,7 +354,7 @@ RTGL1::UploadResult RTGL1::Scene::UploadLight( uint32_t frameIndex,
// adding static to light manager is done separately in SubmitStaticLights
if( !isStatic )
{
lightManager.Add( frameIndex, light );
lightManager.Add( frameIndex, light, transform );
}

return isStatic ? ( isExportable ? UploadResult::ExportableStatic : UploadResult::Static )
Expand Down
9 changes: 5 additions & 4 deletions Source/Scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,11 @@ class Scene
LightManager& lightManager,
bool isStatic );

UploadResult UploadLight( uint32_t frameIndex,
const LightCopy& light,
LightManager& lightManager,
bool isStatic );
UploadResult UploadLight( uint32_t frameIndex,
const LightCopy& light,
LightManager& lightManager,
bool isStatic,
const RgTransform* transform = nullptr );

void SubmitStaticLights( uint32_t frameIndex,
LightManager& lightManager,
Expand Down

0 comments on commit a825d8a

Please sign in to comment.