Skip to content

Commit

Permalink
Merge pull request #1638 from colincornaby/Implement-Light-Range-For-…
Browse files Browse the repository at this point in the history
…Metal

Implementing light range support in Metal
  • Loading branch information
Hoikas authored Dec 3, 2024
2 parents ee3faf5 + 94016a8 commit 1707710
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
10 changes: 8 additions & 2 deletions Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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};
Expand Down

0 comments on commit 1707710

Please sign in to comment.