diff --git a/Flax.flaxproj b/Flax.flaxproj index c9c27281b..78c03fce6 100644 --- a/Flax.flaxproj +++ b/Flax.flaxproj @@ -4,7 +4,7 @@ "Major": 1, "Minor": 11, "Revision": 0, - "Build": 6807 + "Build": 6808 }, "Company": "Flax", "Copyright": "Copyright (c) 2012-2026 Wojciech Figat. All rights reserved.", diff --git a/Source/Engine/Level/Actors/PointLight.cpp b/Source/Engine/Level/Actors/PointLight.cpp index 607bf1bc4..b5801166e 100644 --- a/Source/Engine/Level/Actors/PointLight.cpp +++ b/Source/Engine/Level/Actors/PointLight.cpp @@ -1,6 +1,7 @@ // Copyright (c) Wojciech Figat. All rights reserved. #include "PointLight.h" +#include "Engine/Content/Deprecated.h" #include "Engine/Graphics/RenderTask.h" #include "Engine/Graphics/RenderTools.h" #include "Engine/Graphics/RenderView.h" @@ -196,6 +197,14 @@ void PointLight::Deserialize(DeserializeStream& stream, ISerializeModifier* modi DESERIALIZE(UseInverseSquaredFalloff); DESERIALIZE(UseIESBrightness); DESERIALIZE(IESBrightnessScale); + + // [Deprecated on 12.03.2026, expires on 12.03.2028] + if (modifier->EngineBuild <= 6807 && SERIALIZE_FIND_MEMBER(stream, "UseInverseSquaredFalloff") != stream.MemberEnd() && UseInverseSquaredFalloff) + { + // Convert old non-physical brightness value that was used for Inverse Squared Falloff which wasn't based on proper cm/m units calculations + MARK_CONTENT_DEPRECATED(); + Brightness = Math::Sqrt(Brightness * 0.01f); + } } bool PointLight::IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) diff --git a/Source/Engine/Level/Actors/SpotLight.cpp b/Source/Engine/Level/Actors/SpotLight.cpp index 85b77647a..38502cf1b 100644 --- a/Source/Engine/Level/Actors/SpotLight.cpp +++ b/Source/Engine/Level/Actors/SpotLight.cpp @@ -1,6 +1,8 @@ // Copyright (c) Wojciech Figat. All rights reserved. #include "SpotLight.h" + +#include "Engine/Content/Deprecated.h" #include "Engine/Graphics/RenderView.h" #include "Engine/Renderer/RenderList.h" #include "Engine/Content/Assets/IESProfile.h" @@ -282,6 +284,14 @@ void SpotLight::Deserialize(DeserializeStream& stream, ISerializeModifier* modif DESERIALIZE(UseInverseSquaredFalloff); DESERIALIZE(UseIESBrightness); DESERIALIZE(IESBrightnessScale); + + // [Deprecated on 12.03.2026, expires on 12.03.2028] + if (modifier->EngineBuild <= 6807 && SERIALIZE_FIND_MEMBER(stream, "UseInverseSquaredFalloff") != stream.MemberEnd() && UseInverseSquaredFalloff) + { + // Convert old non-physical brightness value that was used for Inverse Squared Falloff which wasn't based on proper cm/m units calculations + MARK_CONTENT_DEPRECATED(); + Brightness = Math::Sqrt(Brightness * 0.01f); + } } bool SpotLight::IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) diff --git a/Source/Shaders/Common.hlsl b/Source/Shaders/Common.hlsl index 66303546a..2052214b2 100644 --- a/Source/Shaders/Common.hlsl +++ b/Source/Shaders/Common.hlsl @@ -131,6 +131,7 @@ SamplerComparisonState ShadowSamplerLinear : register(s5); #define SAMPLE_RT_LINEAR(rt, texCoord) rt.SampleLevel(SamplerLinearClamp, texCoord, 0) #define HDR_CLAMP_MAX 65472.0 #define PI 3.1415926535897932 +#define UNITS_TO_METERS_SCALE 0.01f // Structure that contains information about GBuffer struct GBufferData diff --git a/Source/Shaders/LightingCommon.hlsl b/Source/Shaders/LightingCommon.hlsl index f09572310..734b9b709 100644 --- a/Source/Shaders/LightingCommon.hlsl +++ b/Source/Shaders/LightingCommon.hlsl @@ -68,20 +68,25 @@ void GetRadialLightAttenuation( // Distance attenuation if (lightData.InverseSquared) { + // Convert scene units to meters for inverse-squared falloff + const float distanceScale = UNITS_TO_METERS_SCALE; + const float distanceScaleSqr = distanceScale * distanceScale; + float distanceSqrScaled = distanceSqr * distanceScaleSqr; + float distanceBiasSqrScaled = distanceBiasSqr * distanceScaleSqr; BRANCH if (lightData.SourceLength > 0) { - float3 l01 = lightData.Direction * lightData.SourceLength; - float3 l0 = toLight - 0.5 * l01; - float3 l1 = toLight + 0.5 * l01; + float3 l01 = lightData.Direction * (lightData.SourceLength * distanceScale); + float3 l0 = (toLight * distanceScale) - 0.5 * l01; + float3 l1 = (toLight * distanceScale) + 0.5 * l01; float lengthL0 = length(l0); float lengthL1 = length(l1); - attenuation = rcp((lengthL0 * lengthL1 + dot(l0, l1)) * 0.5 + distanceBiasSqr); + attenuation = rcp((lengthL0 * lengthL1 + dot(l0, l1)) * 0.5 + distanceBiasSqrScaled); NoL = saturate(0.5 * (dot(N, l0) / lengthL0 + dot(N, l1) / lengthL1)); } else { - attenuation = rcp(distanceSqr + distanceBiasSqr); + attenuation = rcp(distanceSqrScaled + distanceBiasSqrScaled); NoL = saturate(dot(N, L)); } attenuation *= Square(saturate(1 - Square(distanceSqr * Square(lightData.RadiusInv))));