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..2ffc8ba3f7 100644 --- a/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp +++ b/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp @@ -2374,6 +2374,9 @@ void plMetalPipeline::IEnableLight(size_t i, plLightInfo* light) plDirectionalLightInfo* dirLight = nullptr; plOmniLightInfo* omniLight = nullptr; plSpotLightInfo* spotLight = nullptr; + + constexpr float kMaxRange = 32767.f; + fLights.lampSources[i].range = kMaxRange; if ((dirLight = plDirectionalLightInfo::ConvertNoRef(light)) != nullptr) { hsVector3 lightDir = dirLight->GetWorldDirection(); @@ -2383,16 +2386,19 @@ 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}; - // TODO: Maximum Range - 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(); + } + if (!omniLight->GetProjection() && (spotLight = plSpotLightInfo::ConvertNoRef(omniLight)) != nullptr) { hsVector3 lightDir = spotLight->GetWorldDirection(); fLights.lampSources[i].direction = {lightDir.fX, lightDir.fY, lightDir.fZ};