From 6ae48c13389490dd5a8200cbcb7bf9aeaae38ef6 Mon Sep 17 00:00:00 2001 From: Colin Cornaby Date: Tue, 26 Nov 2024 22:44:45 -0800 Subject: [PATCH 1/3] Implementing light range support in Metal --- .../pfMetalPipeline/ShaderSrc/FixedPipelineShaders.metal | 5 +++++ .../FeatureLib/pfMetalPipeline/ShaderSrc/ShaderTypes.h | 1 + .../Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp | 7 +++++++ 3 files changed, 13 insertions(+) diff --git a/Sources/Plasma/FeatureLib/pfMetalPipeline/ShaderSrc/FixedPipelineShaders.metal b/Sources/Plasma/FeatureLib/pfMetalPipeline/ShaderSrc/FixedPipelineShaders.metal index 7623c5c186..bbd4ad2db1 100644 --- a/Sources/Plasma/FeatureLib/pfMetalPipeline/ShaderSrc/FixedPipelineShaders.metal +++ b/Sources/Plasma/FeatureLib/pfMetalPipeline/ShaderSrc/FixedPipelineShaders.metal @@ -212,6 +212,11 @@ vertex ColorInOut pipelineVertexShader(Vertex in [[stage_in]], // Omni Light in all directions const float3 v2l = lightSource->position.xyz - position.xyz; const float distance = length(v2l); + + if (distance > lightSource->range) { + continue; + } + direction.xyz = normalize(v2l); direction.w = 1.f / (lightSource->constAtten + lightSource->linAtten * distance + lightSource->quadAtten * pow(distance, 2.f)); diff --git a/Sources/Plasma/FeatureLib/pfMetalPipeline/ShaderSrc/ShaderTypes.h b/Sources/Plasma/FeatureLib/pfMetalPipeline/ShaderSrc/ShaderTypes.h index 2845921eb8..1c07832eae 100644 --- a/Sources/Plasma/FeatureLib/pfMetalPipeline/ShaderSrc/ShaderTypes.h +++ b/Sources/Plasma/FeatureLib/pfMetalPipeline/ShaderSrc/ShaderTypes.h @@ -150,6 +150,7 @@ struct plMetalShaderLightSource half4 specular; simd::float3 direction; simd::float4 spotProps; // (falloff, theta, phi) + __fp16 range; __fp16 constAtten; __fp16 linAtten; __fp16 quadAtten; diff --git a/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp b/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp index 951fd2590a..ba8989b160 100644 --- a/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp +++ b/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp @@ -2374,6 +2374,8 @@ void plMetalPipeline::IEnableLight(size_t i, plLightInfo* light) plDirectionalLightInfo* dirLight = nullptr; plOmniLightInfo* omniLight = nullptr; plSpotLightInfo* spotLight = nullptr; + + const float maxRange = 32767.f; if ((dirLight = plDirectionalLightInfo::ConvertNoRef(light)) != nullptr) { hsVector3 lightDir = dirLight->GetWorldDirection(); @@ -2383,6 +2385,9 @@ void plMetalPipeline::IEnableLight(size_t i, plLightInfo* light) fLights.lampSources[i].constAtten = 1.0f; fLights.lampSources[i].linAtten = 0.0f; fLights.lampSources[i].quadAtten = 0.0f; + + fLights.lampSources[i].range = maxRange; + } else if ((omniLight = plOmniLightInfo::ConvertNoRef(light)) != nullptr) { hsPoint3 pos = omniLight->GetWorldPosition(); fLights.lampSources[i].position = {pos.fX, pos.fY, pos.fZ, 1.0}; @@ -2392,6 +2397,8 @@ void plMetalPipeline::IEnableLight(size_t i, plLightInfo* light) fLights.lampSources[i].constAtten = omniLight->GetConstantAttenuation(); fLights.lampSources[i].linAtten = omniLight->GetLinearAttenuation(); fLights.lampSources[i].quadAtten = omniLight->GetQuadraticAttenuation(); + + fLights.lampSources[i].range = omniLight->GetRadius(); if (!omniLight->GetProjection() && (spotLight = plSpotLightInfo::ConvertNoRef(omniLight)) != nullptr) { hsVector3 lightDir = spotLight->GetWorldDirection(); From 7f6842588ce135ebc063a6983f0285dda3e8d53a Mon Sep 17 00:00:00 2001 From: Colin Cornaby Date: Sun, 1 Dec 2024 21:57:30 -0800 Subject: [PATCH 2/3] Ignore max light range if radius is 0 --- .../FeatureLib/pfMetalPipeline/plMetalPipeline.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp b/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp index ba8989b160..42196da563 100644 --- a/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp +++ b/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp @@ -2376,6 +2376,7 @@ void plMetalPipeline::IEnableLight(size_t i, plLightInfo* light) plSpotLightInfo* spotLight = nullptr; const float maxRange = 32767.f; + fLights.lampSources[i].range = maxRange; if ((dirLight = plDirectionalLightInfo::ConvertNoRef(light)) != nullptr) { hsVector3 lightDir = dirLight->GetWorldDirection(); @@ -2386,19 +2387,17 @@ void plMetalPipeline::IEnableLight(size_t i, plLightInfo* light) fLights.lampSources[i].linAtten = 0.0f; fLights.lampSources[i].quadAtten = 0.0f; - fLights.lampSources[i].range = maxRange; - } else if ((omniLight = plOmniLightInfo::ConvertNoRef(light)) != nullptr) { hsPoint3 pos = omniLight->GetWorldPosition(); fLights.lampSources[i].position = {pos.fX, pos.fY, pos.fZ, 1.0}; - // TODO: Maximum Range - fLights.lampSources[i].constAtten = omniLight->GetConstantAttenuation(); fLights.lampSources[i].linAtten = omniLight->GetLinearAttenuation(); fLights.lampSources[i].quadAtten = omniLight->GetQuadraticAttenuation(); - fLights.lampSources[i].range = omniLight->GetRadius(); + if (omniLight->GetRadius() != 0.f) { + fLights.lampSources[i].range = omniLight->GetRadius(); + } if (!omniLight->GetProjection() && (spotLight = plSpotLightInfo::ConvertNoRef(omniLight)) != nullptr) { hsVector3 lightDir = spotLight->GetWorldDirection(); From 94016a852a3c538774563f8b003cb2171886ebec Mon Sep 17 00:00:00 2001 From: Colin Cornaby Date: Mon, 2 Dec 2024 19:45:09 -0800 Subject: [PATCH 3/3] Metal max range code cleanup --- .../Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp b/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp index 42196da563..2ffc8ba3f7 100644 --- a/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp +++ b/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp @@ -2375,8 +2375,8 @@ void plMetalPipeline::IEnableLight(size_t i, plLightInfo* light) plOmniLightInfo* omniLight = nullptr; plSpotLightInfo* spotLight = nullptr; - const float maxRange = 32767.f; - fLights.lampSources[i].range = maxRange; + constexpr float kMaxRange = 32767.f; + fLights.lampSources[i].range = kMaxRange; if ((dirLight = plDirectionalLightInfo::ConvertNoRef(light)) != nullptr) { hsVector3 lightDir = dirLight->GetWorldDirection(); @@ -2386,7 +2386,7 @@ void plMetalPipeline::IEnableLight(size_t i, plLightInfo* light) fLights.lampSources[i].constAtten = 1.0f; fLights.lampSources[i].linAtten = 0.0f; fLights.lampSources[i].quadAtten = 0.0f; - + } else if ((omniLight = plOmniLightInfo::ConvertNoRef(light)) != nullptr) { hsPoint3 pos = omniLight->GetWorldPosition(); fLights.lampSources[i].position = {pos.fX, pos.fY, pos.fZ, 1.0}; @@ -2394,7 +2394,7 @@ void plMetalPipeline::IEnableLight(size_t i, plLightInfo* light) fLights.lampSources[i].constAtten = omniLight->GetConstantAttenuation(); fLights.lampSources[i].linAtten = omniLight->GetLinearAttenuation(); fLights.lampSources[i].quadAtten = omniLight->GetQuadraticAttenuation(); - + if (omniLight->GetRadius() != 0.f) { fLights.lampSources[i].range = omniLight->GetRadius(); }