From 4b9001abf2f3fb15a3451da454f4747d77ee5e4b Mon Sep 17 00:00:00 2001 From: Wojciech Figat Date: Tue, 7 Dec 2021 18:22:06 +0100 Subject: [PATCH] Fix spot lights rendering on D3D12 --- .../DirectX/DX11/GPUTextureDX11.cpp | 1 - Source/Engine/Level/Actors/SpotLight.cpp | 2 +- Source/Shaders/Lighting.hlsl | 4 +-- Source/Shaders/LightingCommon.hlsl | 27 +++++-------------- 4 files changed, 9 insertions(+), 25 deletions(-) diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUTextureDX11.cpp b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUTextureDX11.cpp index cb88f4849..c3566023e 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUTextureDX11.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUTextureDX11.cpp @@ -288,7 +288,6 @@ void GPUTextureDX11::initHandles() // (ViewDimension must be D3D11_SRV_DIMENSION_TEXTURECUBE) [ STATE_CREATION ERROR #126: CREATESHADERRESOURCEVIEW_INVALIDDESC] if (isCubeMap && _device->GetRendererType() != RendererType::DirectX10) { - RendererType aa = _device->GetRendererType(); /*if (isCubeMap) { srDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY; diff --git a/Source/Engine/Level/Actors/SpotLight.cpp b/Source/Engine/Level/Actors/SpotLight.cpp index c4c5c8c86..ff4d5d4f5 100644 --- a/Source/Engine/Level/Actors/SpotLight.cpp +++ b/Source/Engine/Level/Actors/SpotLight.cpp @@ -104,7 +104,7 @@ void SpotLight::UpdateBounds() // Cache cone angles _cosOuterCone = Math::Cos(_outerConeAngle * DegreesToRadians); _cosInnerCone = Math::Cos(_innerConeAngle * DegreesToRadians); - _invCosConeDifference = 1.0f / (_cosInnerCone - _cosOuterCone); + _invCosConeDifference = 1.0f / Math::Max(_cosInnerCone - _cosOuterCone, 0.0001f); // Cache bounds // Note: we use the law of cosines to find the distance to the furthest edge of the spotlight cone from a position that is halfway down the spotlight direction diff --git a/Source/Shaders/Lighting.hlsl b/Source/Shaders/Lighting.hlsl index b5021b711..9a5a1d9cc 100644 --- a/Source/Shaders/Lighting.hlsl +++ b/Source/Shaders/Lighting.hlsl @@ -122,7 +122,7 @@ float4 GetLighting(float3 viewPos, LightData lightData, GBufferSample gBuffer, f // Calculate attenuation if (isRadial) { - GetRadialLightAttenuation(lightData, isSpotLight, gBuffer.WorldPos, N, 1, lightData.Direction, L, NoL, distanceAttenuation, lightRadiusMask, spotAttenuation); + GetRadialLightAttenuation(lightData, isSpotLight, gBuffer.WorldPos, N, 1, L, NoL, distanceAttenuation, lightRadiusMask, spotAttenuation); } float attenuation = distanceAttenuation * lightRadiusMask * spotAttenuation; @@ -141,7 +141,7 @@ float4 GetLighting(float3 viewPos, LightData lightData, GBufferSample gBuffer, f // Calculate direct lighting LightingData lighting = SurfaceShading(gBuffer, energy, L, V, N); #if NO_SPECULAR - lighting.Specular = 0; + lighting.Specular = float3(0, 0, 0); #endif // Calculate final light color diff --git a/Source/Shaders/LightingCommon.hlsl b/Source/Shaders/LightingCommon.hlsl index 7ebced959..be17fa23b 100644 --- a/Source/Shaders/LightingCommon.hlsl +++ b/Source/Shaders/LightingCommon.hlsl @@ -43,21 +43,6 @@ struct LightingData float3 Transmission; }; -// Gets a radial attenuation factor for a point light. -// WorldLightVector is the vector from the position being shaded to the light, divided by the radius of the light. -float RadialAttenuation(float3 worldLightVector, half falloffExponent) -{ - float t = dot(worldLightVector, worldLightVector); - return pow(1.0f - saturate(t), falloffExponent); -} - -// Calculates attenuation for a spot light. Where L normalize vector to light. -float GetSpotAttenuation(LightData lightData, float3 L) -{ - // SpotAngles.x is CosOuterCone, SpotAngles.y is InvCosConeDifference - return Square(saturate((dot(normalize(-L), lightData.Direction) - lightData.SpotAngles.x) * lightData.SpotAngles.y)); -} - // Calculates radial light (point or spot) attenuation factors (distance, spot and radius mask) void GetRadialLightAttenuation( LightData lightData, @@ -65,15 +50,13 @@ void GetRadialLightAttenuation( float3 worldPosition, float3 N, float distanceBiasSqr, - inout float3 toLight, inout float3 L, inout float NoL, inout float distanceAttenuation, inout float lightRadiusMask, inout float spotAttenuation) { - toLight = lightData.Position - worldPosition; - + float3 toLight = lightData.Position - worldPosition; float distanceSqr = dot(toLight, toLight); L = toLight * rsqrt(distanceSqr); @@ -102,13 +85,15 @@ void GetRadialLightAttenuation( { distanceAttenuation = 1; NoL = saturate(dot(N, L)); - - lightRadiusMask = RadialAttenuation(toLight * lightData.RadiusInv, lightData.FalloffExponent); + float3 worldLightVector = toLight * lightData.RadiusInv; + float t = dot(worldLightVector, worldLightVector); + lightRadiusMask = pow(1.0f - saturate(t), lightData.FalloffExponent); } if (isSpotLight) { - spotAttenuation = GetSpotAttenuation(lightData, L); + // SpotAngles.x is CosOuterCone, SpotAngles.y is InvCosConeDifference + spotAttenuation = Square(saturate((dot(normalize(-L), lightData.Direction) - lightData.SpotAngles.x) * lightData.SpotAngles.y)); } }