Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions trinity/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1411,6 +1411,7 @@ set(_SOURCES
autoversion.h
ContinueOnMainThread.cpp
ContinueOnMainThread.h
EnumFilter.h
EveSprite2dBracket.cpp
EveSprite2dBracket.h
EveSprite2dBracket_Blue.cpp
Expand Down
59 changes: 59 additions & 0 deletions trinity/EnumFilter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright © 2026 CCP ehf.

#pragma once

#include <cstdint>


/**
* @brief A filter for enum values stored as bits.
* @tparam Enum The enum type to filter.
* @tparam StorageType The underlying storage type for the filter bits. Needs to be large enough to hold all enum values. Defaults to uint8_t (up to 8 enum values).
*/
template <typename Enum, typename StorageType = uint8_t>
class EnumFilter
{
public:
EnumFilter() = default;
EnumFilter( const EnumFilter& other ) = default;
EnumFilter( Enum value ) : m_filter( StorageType( StorageType( 1 ) << StorageType( value ) ) )
{
CCP_ASSERT_M( uint64_t( value ) < 8 * sizeof( StorageType ), "Enum value out of range for the chosen storage type" );
}

EnumFilter& operator|=( Enum value )
{
CCP_ASSERT_M( uint64_t( value ) < 8 * sizeof( StorageType ), "Enum value out of range for the chosen storage type" );
m_filter |= StorageType( StorageType( 1 ) << StorageType( value ) );
return *this;
}

EnumFilter operator|( const EnumFilter& other ) const
{
return EnumFilter( m_filter | other.m_filter );
}

EnumFilter operator|( Enum value ) const
{
EnumFilter result( *this );
result |= value;
return result;
}

bool HasBit( Enum value ) const
{
CCP_ASSERT_M( uint64_t( value ) < 8 * sizeof( StorageType ), "Enum value out of range for the chosen storage type" );
return ( m_filter & StorageType( StorageType( 1 ) << StorageType( value ) ) ) != 0;
}

/// @brief Creates an EnumFilter with all bits set.
static EnumFilter AllBits()
{
EnumFilter filter;
filter.m_filter = ~StorageType( 0 );
return filter;
}

// This variable should be private, but we need to access it for MAP_ATTRIBUTE macros
StorageType m_filter = 0;
};
12 changes: 0 additions & 12 deletions trinity/Eve/EveSpaceScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1372,18 +1372,6 @@ void EveSpaceScene::BeginRender( bool enableDistortion, Tr2RenderContext& render
renderContext.m_esm.BeginManagedRendering();
renderContext.m_esm.ApplyStandardStates( Tr2EffectStateManager::RM_OPAQUE );

if( g_eveSpaceSceneDynamicLighting )
{
if( auto lightManager = Tr2LightManager::GetOrCreateInstance( "res:/graphics/effect/managed/space/system/computelightlists.fx" ) )
{
lightManager->SetVariableStore();
}
}
else
{
Tr2LightManager::DeleteInstance();
}

GatherBatches( enableDistortion, renderContext );

if( m_shadowQuality == ShadowQuality::SHADOW_RAYTRACED && m_enableShadows )
Expand Down
16 changes: 16 additions & 0 deletions trinity/Eve/EveSpaceSceneRenderDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

CCP_STATS_DECLARE( updateDynamicLightLists, "Trinity/EveSpaceScene/updateDynamicLights", true, CST_TIME, "Time took to gather dynamic lights for EveSpaceScene" );

extern bool g_eveSpaceSceneDynamicLighting;

namespace
{

Expand Down Expand Up @@ -486,6 +488,20 @@ void EveSpaceSceneRenderDriver::Execute( const Span<const Tr2TextureAL>& destina

{
TimeSection beginRenderSection( m_timers.beginRender, "BeginRender", rootTimer, renderContext );

if( g_eveSpaceSceneDynamicLighting )
{
if( auto lightManager = Tr2LightManager::GetOrCreateInstance( "res:/graphics/effect/managed/space/system/computelightlists.fx" ) )
{
lightManager->SetVariableStore();
lightManager->SetLightingQuality( m_settings.lightingQuality );
}
}
else
{
Tr2LightManager::DeleteInstance();
}

m_scene->BeginRender( m_settings.enableDistortion, renderContext );
}
{
Expand Down
1 change: 1 addition & 0 deletions trinity/Eve/EveSpaceSceneRenderDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ BLUE_CLASS( EveSpaceSceneRenderDriver ) :
AmbientOcclusionQuality aoQuality = AmbientOcclusionQuality::High;
PostProcess::Quality postProcessingQuality = PostProcess::Quality::HIGH;
Tr2VolumerticQuality volumetricQuality = Tr2VolumerticQuality::High;
LightingQuality lightingQuality = LightingQuality::HIGH;

Color clearColor = Color( 0.0f, 0.0f, 0.0f, 1.0f );

Expand Down
14 changes: 14 additions & 0 deletions trinity/Eve/EveSpaceSceneRenderDriver_Blue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ Be::VarChooser ShadowQualityChooser[] = {
{ "Raytraced", BeCast( ShadowQuality::SHADOW_RAYTRACED ), "" },
{ 0 }
};
const Be::VarChooser LightingQualityChooser[] = {
{ "Low", BeCast( LightingQuality::LOW ), "" },
{ "Medium", BeCast( LightingQuality::MEDIUM ), "" },
{ "High", BeCast( LightingQuality::HIGH ), "" },
{ 0 }
};

const Be::VarChooser TriRMChooser[] = {
// Name Value Docstring
Expand All @@ -52,6 +58,7 @@ extern Be::VarChooser PostProcessQualityChooser[];
BLUE_REGISTER_ENUM_EX( "EveSpaceSceneRenderDriverAntiAliasingQuality", EveSpaceSceneRenderDriver::AntiAliasingQuality, AntiAliasingQualityChooser, ENUM_REG_ENUM_OBJECT_ON_MODULE );
BLUE_REGISTER_ENUM_EX( "EveSpaceSceneRenderDriverAmbientOcclusionQuality", EveSpaceSceneRenderDriver::AmbientOcclusionQuality, AmbientOcclusionQualityChooser, ENUM_REG_ENUM_OBJECT_ON_MODULE );
BLUE_REGISTER_ENUM_EX( "ShadowQuality", ShadowQuality, ShadowQualityChooser, ENUM_REG_ENUM_OBJECT_ON_MODULE );
BLUE_REGISTER_ENUM_EX( "LightingQuality", LightingQuality, LightingQualityChooser, ENUM_REG_ENUM_OBJECT_ON_MODULE );



Expand Down Expand Up @@ -152,6 +159,13 @@ const Be::ClassInfo* EveSpaceSceneRenderDriver::ExposeToBlue()
Be::READWRITE | Be::ENUM,
ShadowQualityChooser )

MAP_ATTRIBUTE_WITH_CHOOSER(
"lightingQuality",
m_settings.lightingQuality,
"Lighting quality setting. One of trinity.LightingQuality enum",
Be::READWRITE | Be::ENUM,
LightingQualityChooser )

MAP_ATTRIBUTE_WITH_CHOOSER(
"antiAliasingQuality",
m_settings.antiAliasingQuality,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
#include "Resources/Tr2LightProfileRes.h"
#include "TriMath.h"

extern bool g_scaleLightBrightnessByRadiusDefault;

EveSmartLightPointLight::EveSmartLightPointLight( IRoot* lockobj ) :
m_staticOffsetTranslation( 0.f, 0.f, 0.f ),
m_staticOffsetRotation( 0.f, 0.f, 0.f, 1.f ),
m_activationStrength( 1.f ),
m_display( true )
m_display( true ),
m_scaleBrightness( g_scaleLightBrightnessByRadiusDefault )
{
m_lightGroupData = LightData();
m_lightType = Tr2Light::POINT_LIGHT;
Expand Down Expand Up @@ -92,7 +95,7 @@ void EveSmartLightPointLight::GetLights( Tr2LightManager& lightManager ) const
pointLightData.radius = m_lightGroupData.radius * scaling * perLightScaling;
pointLightData.innerRadius = Float_16( m_lightGroupData.innerRadius * scaling * perLightScaling );

pointLightData.flags = m_lightGroupData.flags | ( profileIndex << 4 );
pointLightData.flags = Tr2LightManager::PackFlags( m_lightGroupData.flags, profileIndex );

Quaternion rotation = placements[index].initialRotation * placements[index].additionalRotation;
if( m_staticOffsetTranslation != Vector3( 0.f, 0.f, 0.f ) )
Expand Down Expand Up @@ -126,7 +129,7 @@ void EveSmartLightPointLight::GetLights( Tr2LightManager& lightManager ) const
pointLightData.innerAngle = Float_16( cos( TRI_2PI * m_lightGroupData.innerAngle / 360.0f ) );
}

lightManager.AddLight( pointLightData );
lightManager.AddLight( pointLightData, m_scaleBrightness );
Comment thread
filipppavlov marked this conversation as resolved.
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ BLUE_CLASS( EveSmartLightPointLight ) :

protected:
bool m_display;
bool m_scaleBrightness;
LightData m_lightGroupData;
Tr2Light::LIGHT_TYPE m_lightType;
Vector3 m_staticOffsetTranslation;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,7 @@ const Be::ClassInfo* EveSmartLightPointLight::ExposeToBlue()
MAP_ATTRIBUTE( "staticOffsetTranslation", m_staticOffsetTranslation, "static per instance offset in local space before placement \n:jessica-group: StaticOffsetFromDistribution", Be::READWRITE | Be::PERSIST )
MAP_ATTRIBUTE( "staticOffsetRotation", m_staticOffsetRotation, "static per instance rotation in local space before placement \n:jessica-group: StaticOffsetFromDistribution", Be::READWRITE | Be::PERSIST )

MAP_ATTRIBUTE( "scaleBrightness", m_scaleBrightness, "Scale light brightness by its radius", Be::READWRITE | Be::PERSIST )

EXPOSURE_CHAINTO( EveSmartLightBaseGroup )
}
12 changes: 8 additions & 4 deletions trinity/Lights/Tr2FactionLight.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,10 @@ void Tr2FactionLight::RenderDebugInfo( ITr2DebugRenderer2& renderer, const Matri
float outerAngle = TRI_2PI * m_lightData.outerAngle / 360.f;
float innerAngle = TRI_2PI * m_lightData.innerAngle / 360.f;

renderer.DrawCone( this, lightMatrix, m_lightData.radius, outerAngle, 15, 15, Tr2DebugRenderer::Solid, Tr2DebugColor( baseColor + colorMod * 2.0f, baseColor ) );
renderer.DrawCone( this, lightMatrix, m_lightData.innerRadius, innerAngle, 15, 15, Tr2DebugRenderer::Solid, Tr2DebugColor( baseColor + colorMod * 3.0f, baseColor + colorMod ) );
renderer.DrawCone( this, lightMatrix, m_lightData.radius, outerAngle, 15, 15, Tr2DebugRenderer::Wireframe, Tr2DebugColor( baseColor + colorMod * 2.0f, baseColor ) );
renderer.DrawCone( this, lightMatrix, m_lightData.radius, outerAngle, 15, 15, Tr2DebugRenderer::Solid, Color( 0, 0, 0, 0 ) );
renderer.DrawCone( this, lightMatrix, m_lightData.innerRadius, innerAngle, 15, 15, Tr2DebugRenderer::Wireframe, Tr2DebugColor( baseColor + colorMod * 3.0f, baseColor + colorMod ) );
renderer.DrawText( TRI_DBG_FONT_SMALL, lightMatrix.GetTranslation(), baseColor, "%s", m_name.empty() ? "Tr2FactionLight" : m_name.c_str() );
}
else
{
Expand All @@ -96,7 +98,9 @@ void Tr2FactionLight::RenderDebugInfo( ITr2DebugRenderer2& renderer, const Matri
}
lightMatrix *= worldMatrix;

renderer.DrawSphere( this, lightMatrix, m_lightData.position, m_lightData.radius, 10, Tr2DebugRenderer::Solid, Tr2DebugColor( selectedColor, baseColor ) );
renderer.DrawSphere( this, lightMatrix, m_lightData.position, m_lightData.innerRadius, 10, Tr2DebugRenderer::Solid, Tr2DebugColor( selectedColor, baseColor ) );
renderer.DrawSphere( this, lightMatrix, m_lightData.position, m_lightData.radius, 10, Tr2DebugRenderer::Wireframe, Tr2DebugColor( selectedColor, baseColor ) );
renderer.DrawSphere( this, lightMatrix, m_lightData.position, m_lightData.radius, 10, Tr2DebugRenderer::Solid, Color( 0, 0, 0, 0 ) );
renderer.DrawSphere( this, lightMatrix, m_lightData.position, m_lightData.innerRadius, 10, Tr2DebugRenderer::Wireframe, Tr2DebugColor( selectedColor, baseColor ) );
renderer.DrawText( TRI_DBG_FONT_SMALL, TransformCoord( m_lightData.position, lightMatrix ), baseColor, "%s", m_name.empty() ? "Tr2FactionLight" : m_name.c_str() );
}
}
5 changes: 4 additions & 1 deletion trinity/Lights/Tr2FactionLight_Blue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,12 @@ const Be::ClassInfo* Tr2FactionLight::ExposeToBlue()
MAP_ATTRIBUTE( "noiseFrequency", m_lightData.noiseFrequency, "Brightness noise frequency\n:jessica-group: Noise", Be::READWRITE | Be::PERSIST )
MAP_ATTRIBUTE( "noiseOctaves", m_lightData.noiseOctaves, "Brightness turbulence octaves\n:jessica-group: Noise", Be::READWRITE | Be::PERSIST )

MAP_ATTRIBUTE_WITH_CHOOSER( "castsShadows", m_lightData.castsShadows, "Casts shadows. If the light is also volumetric, it will create godrays around the affected objects.", Be::READWRITE | Be::PERSIST | Be::NOTIFY | Be::ENUM, PerLightShadowSettingChooser );
MAP_ATTRIBUTE_WITH_CHOOSER( "lightingQuality", m_lightData.lightingQuality.m_filter, "Filter for lighting quality settings. Controls whether light is active with a certain lighting quality setting.", Be::READWRITE | Be::PERSIST | Be::NOTIFY, LightingQualityFilterChooser );
MAP_ATTRIBUTE_WITH_CHOOSER( "castsShadows", m_lightData.castsShadows.m_filter, "Casts shadows. If the light is also volumetric, it will create godrays around the affected objects.", Be::READWRITE | Be::PERSIST | Be::NOTIFY, PerLightShadowSettingChooser );
MAP_ATTRIBUTE( "isVolumetric", m_lightData.isVolumetric, "Volumetric lights affect participating media such as fog.", Be::READWRITE | Be::NOTIFY | Be::PERSIST )

MAP_ATTRIBUTE( "scaleBrightness", m_scaleBrightness, "Scale light brightness by its radius", Be::READWRITE | Be::PERSIST )

MAP_ATTRIBUTE(
"lightProfilePath",
m_lightProfilePath,
Expand Down
33 changes: 25 additions & 8 deletions trinity/Lights/Tr2Light.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
#include "Tr2Light.h"
#include "Include/TriMath.h"
#include "Resources/Tr2LightProfileRes.h"
#include "../TriSettingsRegistrar.h"

bool g_scaleLightBrightnessByRadiusDefault = true;
TRI_REGISTER_SETTING( "scaleLightBrightnessByRadiusDefault", g_scaleLightBrightnessByRadiusDefault );


LightData::LightData() :
Expand All @@ -18,11 +22,12 @@ LightData::LightData() :
rotation( 0.0f, 0.0f, 0.0f, 1.0f ),
innerAngle( 0.0f ),
outerAngle( 0.0f ),
falloff( uint8_t( LightFalloffType::INVERSE ) ),
lightingQuality( EnumFilter<LightingQuality>::AllBits() ),
Comment thread
filipppavlov marked this conversation as resolved.
texturePath( L"" ),
boneIndex( -1 ),
flags( Tr2LightManager::FLAG_DEFAULT ),
startTime( BeOS->GetCurrentFrameTime() ),
castsShadows( PerLightShadowSetting::DISABLED ),
isVolumetric( false )
{
}
Expand All @@ -48,8 +53,7 @@ Tr2LightManager::PerLightData LightData::AsPerPointLightData( CXMMATRIX transfor
data.color = ( Vector4( color ) * composedBrightness ).GetXYZ();
data.radius = radius * features.parentScale;
data.innerRadius = Float_16( innerRadius * features.parentScale );
int16_t profile = features.profileIndex;
data.flags = flags | ( profile << 4 );
data.flags = Tr2LightManager::PackFlags( flags, features.profileIndex );
data.position = Vector3( XMVector3TransformCoord( position, transform ) );

Matrix lightRotation = RotationMatrix( rotation ) * transform;
Expand All @@ -59,11 +63,19 @@ Tr2LightManager::PerLightData LightData::AsPerPointLightData( CXMMATRIX transfor
data.innerAngle = Float_16( 0.0f );
data.projectionPlaneDistance = Float_16( 1.f / tan( TRI_2PI * 45.f / 360.0f ) );

if( castsShadows == PerLightShadowSetting::ALWAYS_ENABLED || ( castsShadows == PerLightShadowSetting::ENABLED_ONLY_ON_HIGH_QUALITY && shadowQuality == ShadowQuality::SHADOW_HIGH ) || ( castsShadows == PerLightShadowSetting::ENABLED_ONLY_ON_HIGH_QUALITY && shadowQuality == ShadowQuality::SHADOW_RAYTRACED ) )
if( castsShadows.HasBit( shadowQuality ) )
{
data.flags |= Tr2LightManager::FLAG_CASTS_SHADOWS;
}
data.flags |= isVolumetric ? Tr2LightManager::FLAG_IS_VOLUMETRIC : 0;
if( falloff == uint8_t( LightFalloffType::INVERSE_SQUARE ) )
{
data.flags |= Tr2LightManager::FLAG_FALLOFF_INV_SQUARE;
}
else
{
data.flags &= ~Tr2LightManager::FLAG_FALLOFF_INV_SQUARE;
}

return data;
}
Expand All @@ -80,9 +92,9 @@ Tr2LightManager::PerLightData LightData::AsPerSpotLightData( CXMMATRIX transform
}

Tr2Light::Tr2Light( IRoot* lockobj ) :
m_isDynamic( false ),
m_type( UNDEFINED_LIGHT ),
m_name( "" ),
m_isDynamic( false ),
m_scaleBrightness( g_scaleLightBrightnessByRadiusDefault ),
m_brightnessMultiplier( 1.f ),
m_boneTransform( IdentityMatrix() )
{
Expand Down Expand Up @@ -118,6 +130,11 @@ void Tr2Light::ChangeLightColor( Color c )

void Tr2Light::AddLight( Tr2LightManager& lightManager, CXMMATRIX transform, float scale, const Float4x3* bones, size_t boneCount )
{
if( !m_lightData.lightingQuality.HasBit( lightManager.GetLightingQuality() ) )
{
return;
}

if( m_isDynamic )
{
this->Update();
Expand All @@ -139,12 +156,12 @@ void Tr2Light::AddLight( Tr2LightManager& lightManager, CXMMATRIX transform, flo
if( m_type == Tr2Light::POINT_LIGHT )
{
auto data = m_lightData.AsPerPointLightData( lightTransform, features, lightManager.GetCurrentSpaceSceneShadowQuality() );
lightManager.AddLight( data );
lightManager.AddLight( data, m_scaleBrightness );
}
else if( m_type == Tr2Light::SPOT_LIGHT )
{
auto data = m_lightData.AsPerSpotLightData( lightTransform, features, lightManager.GetCurrentSpaceSceneShadowQuality() );
lightManager.AddLight( data );
lightManager.AddLight( data, m_scaleBrightness );
}
}

Expand Down
Loading
Loading