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( 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( 1 << StorageType( value ) );
return *this;
}
Comment on lines +19 to +29

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

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
30 changes: 24 additions & 6 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 on lines 22 to +26
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 @@ -81,6 +93,7 @@ Tr2LightManager::PerLightData LightData::AsPerSpotLightData( CXMMATRIX transform

Tr2Light::Tr2Light( IRoot* lockobj ) :
m_isDynamic( false ),
m_scaleBrightness( g_scaleLightBrightnessByRadiusDefault ),
m_type( UNDEFINED_LIGHT ),
m_name( "" ),
m_brightnessMultiplier( 1.f ),
Expand Down Expand Up @@ -118,6 +131,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 +157,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
21 changes: 14 additions & 7 deletions trinity/Lights/Tr2Light.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "Tr2LightManager.h"
#include "Tr2DebugRenderer.h"
#include "Utilities/MatrixUtils.h"
#include "../EnumFilter.h"

BLUE_DECLARE( Tr2LightProfileRes );

Expand All @@ -17,11 +18,10 @@ struct LightFeatures
float parentBrightness;
};

enum class PerLightShadowSetting
enum class LightFalloffType : uint8_t
{
DISABLED,
ENABLED_ONLY_ON_HIGH_QUALITY,
ALWAYS_ENABLED
INVERSE,
INVERSE_SQUARE
};

struct LightData
Expand All @@ -45,16 +45,20 @@ struct LightData
float outerAngle;
float innerAngle;

// This should be LightFalloffType, but it can't be used because of a bug in MAP_ATTRIBUTE
uint8_t falloff;
EnumFilter<LightingQuality> lightingQuality;

// Textured light specifics
std::wstring texturePath;
int32_t boneIndex;

uint16_t flags;

Be::Time startTime;

PerLightShadowSetting castsShadows;
EnumFilter<ShadowQuality> castsShadows;
bool isVolumetric;

Be::Time startTime;
};


Expand Down Expand Up @@ -105,6 +109,7 @@ BLUE_CLASS( Tr2Light ) :
std::string m_name;
Be::Time m_startTime;
bool m_isDynamic;
bool m_scaleBrightness;
float m_brightnessMultiplier;
Matrix m_boneTransform; // used for lights that have boneIndices

Expand All @@ -116,3 +121,5 @@ TYPEDEF_BLUECLASS( Tr2Light );

extern const Be::VarChooser PerLightShadowSettingChooser[];
extern const Be::VarChooser Tr2LightFlagChooser[];
extern const Be::VarChooser LightFalloffTypeChooser[];
extern const Be::VarChooser LightingQualityFilterChooser[];
Loading
Loading