소스 검색

Replace plain ESM with EVSM shadows

Panagiotis Christopoulos Charitos 5 년 전
부모
커밋
2dafafc9c4

+ 43 - 50
shaders/ExponentialShadowmappingResolve.glslp

@@ -7,21 +7,26 @@
 
 
 #pragma anki start comp
 #pragma anki start comp
 #include <shaders/GaussianBlurCommon.glsl>
 #include <shaders/GaussianBlurCommon.glsl>
-#include <shaders/Functions.glsl>
+#include <shaders/LightFunctions.glsl>
 
 
 layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
 layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
 
 
 const F32 OFFSET = 1.25;
 const F32 OFFSET = 1.25;
 
 
+struct Uniforms
+{
+	UVec4 m_viewport;
+	Vec2 m_uvScale;
+	Vec2 m_uvTranslation;
+	U32 m_blur;
+	U32 m_padding0;
+	U32 m_padding1;
+	U32 m_padding2;
+};
+
 layout(push_constant, std430) uniform pc_
 layout(push_constant, std430) uniform pc_
 {
 {
-	Vec2 u_uvScale;
-	Vec2 u_uvTranslation;
-	F32 u_near;
-	F32 u_far;
-	U32 u_renderingTechnique; // If value is 0: perspective+blur, 1: perspective, 2: ortho+blur, 3: ortho
-	U32 u_padding;
-	UVec4 u_viewport;
+	Uniforms u_uniforms;
 };
 };
 
 
 layout(set = 0, binding = 0) uniform sampler u_linearAnyClampSampler;
 layout(set = 0, binding = 0) uniform sampler u_linearAnyClampSampler;
@@ -29,72 +34,60 @@ layout(set = 0, binding = 1) uniform texture2D u_inputTex;
 
 
 layout(set = 0, binding = 2) uniform writeonly image2D u_outImg;
 layout(set = 0, binding = 2) uniform writeonly image2D u_outImg;
 
 
-F32 sampleLinearDepthPerspective(Vec2 uv)
-{
-	return linearizeDepth(textureLod(u_inputTex, u_linearAnyClampSampler, uv, 0.0).r, u_near, u_far);
-}
-
-F32 sampleLinearDepthOrhographic(Vec2 uv)
+Vec4 computeMoments(Vec2 uv)
 {
 {
-	return textureLod(u_inputTex, u_linearAnyClampSampler, uv, 0.0).r;
+	const F32 d = textureLod(u_inputTex, u_linearAnyClampSampler, uv, 0.0).r;
+	const Vec2 posAndNeg = evsmProcessDepth(d);
+	return Vec4(posAndNeg.x, posAndNeg.x * posAndNeg.x, posAndNeg.y, posAndNeg.y * posAndNeg.y);
 }
 }
 
 
 void main()
 void main()
 {
 {
-	if(gl_GlobalInvocationID.x >= u_viewport.z || gl_GlobalInvocationID.y >= u_viewport.w)
+	if(gl_GlobalInvocationID.x >= u_uniforms.m_viewport.z || gl_GlobalInvocationID.y >= u_uniforms.m_viewport.w)
 	{
 	{
 		// Skip if it's out of bounds
 		// Skip if it's out of bounds
 		return;
 		return;
 	}
 	}
 
 
 	// Compute the read UV
 	// Compute the read UV
-	Vec2 uv = (Vec2(gl_GlobalInvocationID.xy) + 0.5) / Vec2(u_viewport.zw);
-	uv = uv * u_uvScale + u_uvTranslation;
+	Vec2 uv = (Vec2(gl_GlobalInvocationID.xy) + 0.5) / Vec2(u_uniforms.m_viewport.zw);
+	uv = uv * u_uniforms.m_uvScale + u_uniforms.m_uvTranslation;
 
 
 	// Compute the UV limits. We can't sample beyond those
 	// Compute the UV limits. We can't sample beyond those
 	const Vec2 TEXEL_SIZE = 1.0 / Vec2(INPUT_TEXTURE_SIZE);
 	const Vec2 TEXEL_SIZE = 1.0 / Vec2(INPUT_TEXTURE_SIZE);
 	const Vec2 HALF_TEXEL_SIZE = TEXEL_SIZE / 2.0;
 	const Vec2 HALF_TEXEL_SIZE = TEXEL_SIZE / 2.0;
-	const Vec2 maxUv = (Vec2(1.0) * u_uvScale + u_uvTranslation) - HALF_TEXEL_SIZE;
-	const Vec2 minUv = (Vec2(0.0) * u_uvScale + u_uvTranslation) + HALF_TEXEL_SIZE;
+	const Vec2 maxUv = (Vec2(1.0) * u_uniforms.m_uvScale + u_uniforms.m_uvTranslation) - HALF_TEXEL_SIZE;
+	const Vec2 minUv = (Vec2(0.0) * u_uniforms.m_uvScale + u_uniforms.m_uvTranslation) + HALF_TEXEL_SIZE;
 
 
 	// Sample
 	// Sample
 	const Vec2 UV_OFFSET = OFFSET * TEXEL_SIZE;
 	const Vec2 UV_OFFSET = OFFSET * TEXEL_SIZE;
 	const F32 w0 = BOX_WEIGHTS[0u];
 	const F32 w0 = BOX_WEIGHTS[0u];
 	const F32 w1 = BOX_WEIGHTS[1u];
 	const F32 w1 = BOX_WEIGHTS[1u];
 	const F32 w2 = BOX_WEIGHTS[2u];
 	const F32 w2 = BOX_WEIGHTS[2u];
-	F32 outDepth;
-	switch(u_renderingTechnique)
+	Vec4 moments;
+	if(u_uniforms.m_blur != 0)
+	{
+		moments = computeMoments(uv) * w0;
+		moments += computeMoments(clamp(uv + Vec2(UV_OFFSET.x, 0.0), minUv, maxUv)) * w1;
+		moments += computeMoments(clamp(uv + Vec2(-UV_OFFSET.x, 0.0), minUv, maxUv)) * w1;
+		moments += computeMoments(clamp(uv + Vec2(0.0, UV_OFFSET.y), minUv, maxUv)) * w1;
+		moments += computeMoments(clamp(uv + Vec2(0.0, -UV_OFFSET.y), minUv, maxUv)) * w1;
+		moments += computeMoments(clamp(uv + Vec2(UV_OFFSET.x, UV_OFFSET.y), minUv, maxUv)) * w2;
+		moments += computeMoments(clamp(uv + Vec2(-UV_OFFSET.x, UV_OFFSET.y), minUv, maxUv)) * w2;
+		moments += computeMoments(clamp(uv + Vec2(UV_OFFSET.x, -UV_OFFSET.y), minUv, maxUv)) * w2;
+		moments += computeMoments(clamp(uv + Vec2(-UV_OFFSET.x, -UV_OFFSET.y), minUv, maxUv)) * w2;
+	}
+	else
 	{
 	{
-	case 0u:
-		outDepth = sampleLinearDepthPerspective(uv) * w0;
-		outDepth += sampleLinearDepthPerspective(clamp(uv + Vec2(UV_OFFSET.x, 0.0), minUv, maxUv)) * w1;
-		outDepth += sampleLinearDepthPerspective(clamp(uv + Vec2(-UV_OFFSET.x, 0.0), minUv, maxUv)) * w1;
-		outDepth += sampleLinearDepthPerspective(clamp(uv + Vec2(0.0, UV_OFFSET.y), minUv, maxUv)) * w1;
-		outDepth += sampleLinearDepthPerspective(clamp(uv + Vec2(0.0, -UV_OFFSET.y), minUv, maxUv)) * w1;
-		outDepth += sampleLinearDepthPerspective(clamp(uv + Vec2(UV_OFFSET.x, UV_OFFSET.y), minUv, maxUv)) * w2;
-		outDepth += sampleLinearDepthPerspective(clamp(uv + Vec2(-UV_OFFSET.x, UV_OFFSET.y), minUv, maxUv)) * w2;
-		outDepth += sampleLinearDepthPerspective(clamp(uv + Vec2(UV_OFFSET.x, -UV_OFFSET.y), minUv, maxUv)) * w2;
-		outDepth += sampleLinearDepthPerspective(clamp(uv + Vec2(-UV_OFFSET.x, -UV_OFFSET.y), minUv, maxUv)) * w2;
-		break;
-	case 1u:
-		outDepth = sampleLinearDepthPerspective(uv);
-		break;
-	case 2u:
-		outDepth = sampleLinearDepthOrhographic(uv) * w0;
-		outDepth += sampleLinearDepthOrhographic(clamp(uv + Vec2(UV_OFFSET.x, 0.0), minUv, maxUv)) * w1;
-		outDepth += sampleLinearDepthOrhographic(clamp(uv + Vec2(-UV_OFFSET.x, 0.0), minUv, maxUv)) * w1;
-		outDepth += sampleLinearDepthOrhographic(clamp(uv + Vec2(0.0, UV_OFFSET.y), minUv, maxUv)) * w1;
-		outDepth += sampleLinearDepthOrhographic(clamp(uv + Vec2(0.0, -UV_OFFSET.y), minUv, maxUv)) * w1;
-		outDepth += sampleLinearDepthOrhographic(clamp(uv + Vec2(UV_OFFSET.x, UV_OFFSET.y), minUv, maxUv)) * w2;
-		outDepth += sampleLinearDepthOrhographic(clamp(uv + Vec2(-UV_OFFSET.x, UV_OFFSET.y), minUv, maxUv)) * w2;
-		outDepth += sampleLinearDepthOrhographic(clamp(uv + Vec2(UV_OFFSET.x, -UV_OFFSET.y), minUv, maxUv)) * w2;
-		outDepth += sampleLinearDepthOrhographic(clamp(uv + Vec2(-UV_OFFSET.x, -UV_OFFSET.y), minUv, maxUv)) * w2;
-		break;
-	default:
-		outDepth = sampleLinearDepthOrhographic(uv);
+		moments = computeMoments(uv);
 	}
 	}
 
 
 	// Write the results
 	// Write the results
-	imageStore(u_outImg, IVec2(gl_GlobalInvocationID.xy) + IVec2(u_viewport.xy), Vec4(outDepth));
+#if ANKI_EVSM4
+	const Vec4 outColor = moments;
+#else
+	const Vec4 outColor = Vec4(moments.xy, 0.0, 0.0);
+#endif
+	imageStore(u_outImg, IVec2(gl_GlobalInvocationID.xy) + IVec2(u_uniforms.m_viewport.xy), outColor);
 }
 }
 #pragma anki end
 #pragma anki end

+ 85 - 32
shaders/LightFunctions.glsl

@@ -10,11 +10,63 @@
 #include <shaders/Functions.glsl>
 #include <shaders/Functions.glsl>
 #include <shaders/Pack.glsl>
 #include <shaders/Pack.glsl>
 #include <shaders/glsl_cpp_common/ClusteredShading.h>
 #include <shaders/glsl_cpp_common/ClusteredShading.h>
+#include <shaders/glsl_cpp_common/Evsm.h>
 
 
-const U32 SHADOW_SAMPLE_COUNT = 16;
-#if !defined(ESM_CONSTANT)
-const F32 ESM_CONSTANT = 40.0;
+// Do some EVSM magic with depth
+Vec2 evsmProcessDepth(F32 depth)
+{
+	depth = 2.0 * depth - 1.0;
+	const F32 pos = exp(EVSM_POSITIVE_CONSTANT * depth);
+	const F32 neg = -exp(EVSM_NEGATIVE_CONSTANT * depth);
+	return Vec2(pos, neg);
+}
+
+F32 linstep(F32 a, F32 b, F32 v)
+{
+	return saturate((v - a) / (b - a));
+}
+
+// Reduces VSM light bleedning
+F32 reduceLightBleeding(F32 pMax, F32 amount)
+{
+	// Remove the [0, amount] tail and linearly rescale (amount, 1].
+	return linstep(amount, 1.0, pMax);
+}
+
+F32 chebyshevUpperBound(Vec2 moments, F32 mean, F32 minVariance, F32 lightBleedingReduction)
+{
+	// Compute variance
+	F32 variance = moments.y - (moments.x * moments.x);
+	variance = max(variance, minVariance);
+
+	// Compute probabilistic upper bound
+	const F32 d = mean - moments.x;
+	F32 pMax = variance / (variance + (d * d));
+
+	pMax = reduceLightBleeding(pMax, lightBleedingReduction);
+
+	// One-tailed Chebyshev
+	return (mean <= moments.x) ? 1.0 : pMax;
+}
+
+// Compute the shadow factor of EVSM given the 2 depths
+F32 evsmComputeShadowFactor(F32 occluderDepth, Vec4 shadowMapMoments)
+{
+	const Vec2 evsmOccluderDepths = evsmProcessDepth(occluderDepth);
+	const Vec2 depthScale =
+		EVSM_BIAS * 0.01 * Vec2(EVSM_POSITIVE_CONSTANT, EVSM_NEGATIVE_CONSTANT) * evsmOccluderDepths;
+	const Vec2 minVariance = depthScale * depthScale;
+
+#if !ANKI_EVSM4
+	return chebyshevUpperBound(shadowMapMoments.xy, evsmOccluderDepths.x, minVariance.x, EVSM_LIGHT_BLEEDING_REDUCTION);
+#else
+	const F32 pos =
+		chebyshevUpperBound(shadowMapMoments.xy, evsmOccluderDepths.x, minVariance.x, EVSM_LIGHT_BLEEDING_REDUCTION);
+	const F32 neg =
+		chebyshevUpperBound(shadowMapMoments.zw, evsmOccluderDepths.y, minVariance.y, EVSM_LIGHT_BLEEDING_REDUCTION);
+	return min(pos, neg);
 #endif
 #endif
+}
 
 
 // Fresnel term unreal
 // Fresnel term unreal
 // specular: The specular color aka F0
 // specular: The specular color aka F0
@@ -116,14 +168,9 @@ F32 computeShadowFactorSpotLight(SpotLight light, Vec3 worldPos, texture2D spotM
 	const Vec4 texCoords4 = light.m_texProjectionMat * Vec4(worldPos, 1.0);
 	const Vec4 texCoords4 = light.m_texProjectionMat * Vec4(worldPos, 1.0);
 	const Vec3 texCoords3 = texCoords4.xyz / texCoords4.w;
 	const Vec3 texCoords3 = texCoords4.xyz / texCoords4.w;
 
 
-	const F32 near = LIGHT_FRUSTUM_NEAR_PLANE;
-	const F32 far = light.m_radius;
-
-	const F32 linearDepth = linearizeDepth(texCoords3.z, near, far);
-
-	const F32 shadowFactor = textureLod(spotMap, spotMapSampler, texCoords3.xy, 0.0).r;
+	const Vec4 shadowMoments = textureLod(spotMap, spotMapSampler, texCoords3.xy, 0.0);
 
 
-	return saturate(exp(ESM_CONSTANT * (shadowFactor - linearDepth)));
+	return evsmComputeShadowFactor(texCoords3.z, shadowMoments);
 }
 }
 
 
 // Compute the shadow factor of point (omni) lights.
 // Compute the shadow factor of point (omni) lights.
@@ -133,31 +180,40 @@ F32 computeShadowFactorPointLight(PointLight light, Vec3 frag2Light, texture2D s
 	const Vec3 dirabs = abs(dir);
 	const Vec3 dirabs = abs(dir);
 	const F32 dist = max(dirabs.x, max(dirabs.y, dirabs.z));
 	const F32 dist = max(dirabs.x, max(dirabs.y, dirabs.z));
 
 
+	// 1) Project the dist to light's proj mat
+	//
 	const F32 near = LIGHT_FRUSTUM_NEAR_PLANE;
 	const F32 near = LIGHT_FRUSTUM_NEAR_PLANE;
 	const F32 far = light.m_radius;
 	const F32 far = light.m_radius;
+	const F32 g = near - far;
 
 
-	const F32 linearDepth = (dist - near) / (far - near);
+	const F32 zVSpace = -dist;
+	const F32 w = -zVSpace;
+	F32 z = (far * zVSpace + far * near) / g;
+	z /= w;
 
 
-	// Read tex
-	F32 shadowFactor;
-	{
-		// Convert cube coords
-		U32 faceIdxu;
-		Vec2 uv = convertCubeUvsu(dir, faceIdxu);
+	// 2) Read shadow tex
+	//
 
 
-		// Get the atlas offset
-		Vec2 atlasOffset;
-		atlasOffset.x = light.m_shadowAtlasTileOffsets[faceIdxu >> 1u][(faceIdxu & 1u) << 1u];
-		atlasOffset.y = light.m_shadowAtlasTileOffsets[faceIdxu >> 1u][((faceIdxu & 1u) << 1u) + 1u];
+	// Convert cube coords
+	U32 faceIdxu;
+	Vec2 uv = convertCubeUvsu(dir, faceIdxu);
 
 
-		// Compute UV
-		uv = fma(uv, Vec2(light.m_shadowAtlasTileScale), atlasOffset);
+	// Get the atlas offset
+	Vec2 atlasOffset;
+	atlasOffset.x = light.m_shadowAtlasTileOffsets[faceIdxu >> 1u][(faceIdxu & 1u) << 1u];
+	atlasOffset.y = light.m_shadowAtlasTileOffsets[faceIdxu >> 1u][((faceIdxu & 1u) << 1u) + 1u];
 
 
-		// Sample
-		shadowFactor = textureLod(shadowMap, shadowMapSampler, uv, 0.0).r;
-	}
+	// Compute UV
+	uv = fma(uv, Vec2(light.m_shadowAtlasTileScale), atlasOffset);
+
+	// Sample
+	const Vec4 shadowMoments = textureLod(shadowMap, shadowMapSampler, uv, 0.0);
+
+	// 3) Compare
+	//
+	const F32 shadowFactor = evsmComputeShadowFactor(z, shadowMoments);
 
 
-	return saturate(exp(ESM_CONSTANT * (shadowFactor - linearDepth)));
+	return shadowFactor;
 }
 }
 
 
 // Compute the shadow factor of a directional light
 // Compute the shadow factor of a directional light
@@ -188,12 +244,9 @@ F32 computeShadowFactorDirLight(
 	const Vec4 texCoords4 = lightProjectionMat * Vec4(worldPos, 1.0);
 	const Vec4 texCoords4 = lightProjectionMat * Vec4(worldPos, 1.0);
 	const Vec3 texCoords3 = texCoords4.xyz / texCoords4.w;
 	const Vec3 texCoords3 = texCoords4.xyz / texCoords4.w;
 
 
-	const F32 cascadeLinearDepth = texCoords3.z;
-
-	F32 shadowFactor = textureLod(shadowMap, shadowMapSampler, texCoords3.xy, 0.0).r;
-	shadowFactor = saturate(exp(ESM_CONSTANT * 3.0 * (shadowFactor - cascadeLinearDepth)));
+	const Vec4 shadowMoments = textureLod(shadowMap, shadowMapSampler, texCoords3.xy, 0.0);
 
 
-	return shadowFactor;
+	return evsmComputeShadowFactor(texCoords3.z, shadowMoments);
 }
 }
 
 
 // Compute the shadow factor of a directional light
 // Compute the shadow factor of a directional light

+ 0 - 3
shaders/VolumetricLightingAccumulation.glslp

@@ -16,9 +16,6 @@
 
 
 #pragma anki start comp
 #pragma anki start comp
 
 
-// Lower the ESM constant to smooth the shadows
-#define ESM_CONSTANT 30.0
-
 const F32 PHASE_FUNCTION_ANISOTROPY = 0.3;
 const F32 PHASE_FUNCTION_ANISOTROPY = 0.3;
 
 
 layout(local_size_x = WORKGROUP_SIZE.x, local_size_y = WORKGROUP_SIZE.y, local_size_z = WORKGROUP_SIZE.z) in;
 layout(local_size_x = WORKGROUP_SIZE.x, local_size_y = WORKGROUP_SIZE.y, local_size_z = WORKGROUP_SIZE.z) in;

+ 19 - 0
shaders/glsl_cpp_common/Evsm.h

@@ -0,0 +1,19 @@
+// Copyright (C) 2009-2020, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <shaders/glsl_cpp_common/Common.h>
+
+ANKI_BEGIN_NAMESPACE
+
+#define ANKI_EVSM4 0 // 2 component EVSM or 4 component EVSM
+
+const F32 EVSM_POSITIVE_CONSTANT = 40.0f; // EVSM positive constant
+const F32 EVSM_NEGATIVE_CONSTANT = 5.0f; // EVSM negative constant
+const F32 EVSM_BIAS = 0.01f;
+const F32 EVSM_LIGHT_BLEEDING_REDUCTION = 0.05f;
+
+ANKI_END_NAMESPACE

+ 6 - 1
src/anki/renderer/Common.h

@@ -8,6 +8,7 @@
 #include <anki/Gr.h>
 #include <anki/Gr.h>
 #include <anki/core/StagingGpuMemoryManager.h>
 #include <anki/core/StagingGpuMemoryManager.h>
 #include <anki/util/Ptr.h>
 #include <anki/util/Ptr.h>
+#include <shaders/glsl_cpp_common/Evsm.h>
 
 
 namespace anki
 namespace anki
 {
 {
@@ -108,7 +109,11 @@ constexpr Format FORWARD_SHADING_COLOR_ATTACHMENT_PIXEL_FORMAT = Format::R16G16B
 constexpr Format DBG_COLOR_ATTACHMENT_PIXEL_FORMAT = Format::R8G8B8A8_UNORM;
 constexpr Format DBG_COLOR_ATTACHMENT_PIXEL_FORMAT = Format::R8G8B8A8_UNORM;
 
 
 constexpr Format SHADOW_DEPTH_PIXEL_FORMAT = Format::D32_SFLOAT;
 constexpr Format SHADOW_DEPTH_PIXEL_FORMAT = Format::D32_SFLOAT;
-constexpr Format SHADOW_COLOR_PIXEL_FORMAT = Format::R16_UNORM;
+#if ANKI_EVSM4
+constexpr Format SHADOW_COLOR_PIXEL_FORMAT = Format::R32G32B32A32_SFLOAT;
+#else
+constexpr Format SHADOW_COLOR_PIXEL_FORMAT = Format::R32G32_SFLOAT;
+#endif
 
 
 /// A convenience function to find empty cache entries. Used for various probes.
 /// A convenience function to find empty cache entries. Used for various probes.
 template<typename THashMap, typename TCacheEntryArray, typename TAlloc>
 template<typename THashMap, typename TCacheEntryArray, typename TAlloc>

+ 6 - 28
src/anki/renderer/ShadowMapping.cpp

@@ -36,10 +36,7 @@ class ShadowMapping::Atlas::ResolveWorkItem
 public:
 public:
 	Vec4 m_uvIn; ///< UV + size that point to the scratch buffer.
 	Vec4 m_uvIn; ///< UV + size that point to the scratch buffer.
 	Array<U32, 4> m_viewportOut; ///< Viewport in the atlas RT.
 	Array<U32, 4> m_viewportOut; ///< Viewport in the atlas RT.
-	F32 m_cameraNear;
-	F32 m_cameraFar;
 	Bool m_blur;
 	Bool m_blur;
-	Bool m_perspectiveProjection;
 };
 };
 
 
 ShadowMapping::~ShadowMapping()
 ShadowMapping::~ShadowMapping()
@@ -164,29 +161,19 @@ void ShadowMapping::runAtlas(RenderPassWorkContext& rgraphCtx)
 
 
 		struct Uniforms
 		struct Uniforms
 		{
 		{
+			UVec4 m_viewport;
 			Vec2 m_uvScale;
 			Vec2 m_uvScale;
 			Vec2 m_uvTranslation;
 			Vec2 m_uvTranslation;
-			F32 m_near;
-			F32 m_far;
-			U32 m_renderingTechnique;
-			U32 m_padding;
-			UVec4 m_viewport;
+			U32 m_blur;
+			U32 m_padding0;
+			U32 m_padding1;
+			U32 m_padding2;
 		} unis;
 		} unis;
 		unis.m_uvScale = workItem.m_uvIn.zw();
 		unis.m_uvScale = workItem.m_uvIn.zw();
 		unis.m_uvTranslation = workItem.m_uvIn.xy();
 		unis.m_uvTranslation = workItem.m_uvIn.xy();
-		unis.m_near = workItem.m_cameraNear;
-		unis.m_far = workItem.m_cameraFar;
 		unis.m_viewport = UVec4(
 		unis.m_viewport = UVec4(
 			workItem.m_viewportOut[0], workItem.m_viewportOut[1], workItem.m_viewportOut[2], workItem.m_viewportOut[3]);
 			workItem.m_viewportOut[0], workItem.m_viewportOut[1], workItem.m_viewportOut[2], workItem.m_viewportOut[3]);
-
-		if(workItem.m_perspectiveProjection)
-		{
-			unis.m_renderingTechnique = (workItem.m_blur) ? 0 : 1;
-		}
-		else
-		{
-			unis.m_renderingTechnique = (workItem.m_blur) ? 2 : 3;
-		}
+		unis.m_blur = workItem.m_blur;
 
 
 		cmdb->setPushConstants(&unis, sizeof(unis));
 		cmdb->setPushConstants(&unis, sizeof(unis));
 
 
@@ -571,7 +558,6 @@ void ShadowMapping::processLights(RenderingContext& ctx, U32& threadCountForScra
 					newScratchAndAtlasResloveRenderWorkItems(atlasViewports[activeCascades],
 					newScratchAndAtlasResloveRenderWorkItems(atlasViewports[activeCascades],
 						scratchViewports[activeCascades],
 						scratchViewports[activeCascades],
 						blurAtlass[activeCascades],
 						blurAtlass[activeCascades],
-						false,
 						light.m_shadowRenderQueues[cascade],
 						light.m_shadowRenderQueues[cascade],
 						lightsToRender,
 						lightsToRender,
 						atlasWorkItems,
 						atlasWorkItems,
@@ -673,7 +659,6 @@ void ShadowMapping::processLights(RenderingContext& ctx, U32& threadCountForScra
 						newScratchAndAtlasResloveRenderWorkItems(atlasViewport,
 						newScratchAndAtlasResloveRenderWorkItems(atlasViewport,
 							scratchViewport,
 							scratchViewport,
 							blurAtlas,
 							blurAtlas,
-							true,
 							light->m_shadowRenderQueues[face],
 							light->m_shadowRenderQueues[face],
 							lightsToRender,
 							lightsToRender,
 							atlasWorkItems,
 							atlasWorkItems,
@@ -740,7 +725,6 @@ void ShadowMapping::processLights(RenderingContext& ctx, U32& threadCountForScra
 				newScratchAndAtlasResloveRenderWorkItems(atlasViewport,
 				newScratchAndAtlasResloveRenderWorkItems(atlasViewport,
 					scratchViewport,
 					scratchViewport,
 					blurAtlas,
 					blurAtlas,
-					true,
 					light->m_shadowRenderQueue,
 					light->m_shadowRenderQueue,
 					lightsToRender,
 					lightsToRender,
 					atlasWorkItems,
 					atlasWorkItems,
@@ -831,7 +815,6 @@ void ShadowMapping::processLights(RenderingContext& ctx, U32& threadCountForScra
 void ShadowMapping::newScratchAndAtlasResloveRenderWorkItems(const Viewport& atlasViewport,
 void ShadowMapping::newScratchAndAtlasResloveRenderWorkItems(const Viewport& atlasViewport,
 	const Viewport& scratchVewport,
 	const Viewport& scratchVewport,
 	Bool blurAtlas,
 	Bool blurAtlas,
-	Bool perspectiveProjection,
 	RenderQueue* lightRenderQueue,
 	RenderQueue* lightRenderQueue,
 	DynamicArrayAuto<Scratch::LightToRenderToScratchInfo>& scratchWorkItem,
 	DynamicArrayAuto<Scratch::LightToRenderToScratchInfo>& scratchWorkItem,
 	DynamicArrayAuto<Atlas::ResolveWorkItem>& atlasResolveWorkItem,
 	DynamicArrayAuto<Atlas::ResolveWorkItem>& atlasResolveWorkItem,
@@ -857,12 +840,7 @@ void ShadowMapping::newScratchAndAtlasResloveRenderWorkItems(const Viewport& atl
 		atlasItem.m_uvIn[3] = F32(scratchVewport[3]) / scratchAtlasHeight;
 		atlasItem.m_uvIn[3] = F32(scratchVewport[3]) / scratchAtlasHeight;
 
 
 		atlasItem.m_viewportOut = atlasViewport;
 		atlasItem.m_viewportOut = atlasViewport;
-
-		atlasItem.m_cameraFar = lightRenderQueue->m_cameraFar;
-		atlasItem.m_cameraNear = lightRenderQueue->m_cameraNear;
-
 		atlasItem.m_blur = blurAtlas;
 		atlasItem.m_blur = blurAtlas;
-		atlasItem.m_perspectiveProjection = perspectiveProjection;
 
 
 		atlasResolveWorkItem.emplaceBack(atlasItem);
 		atlasResolveWorkItem.emplaceBack(atlasItem);
 	}
 	}

+ 0 - 1
src/anki/renderer/ShadowMapping.h

@@ -126,7 +126,6 @@ private:
 	void newScratchAndAtlasResloveRenderWorkItems(const Viewport& atlasViewport,
 	void newScratchAndAtlasResloveRenderWorkItems(const Viewport& atlasViewport,
 		const Viewport& scratchVewport,
 		const Viewport& scratchVewport,
 		Bool blurAtlas,
 		Bool blurAtlas,
-		Bool perspectiveProjection,
 		RenderQueue* lightRenderQueue,
 		RenderQueue* lightRenderQueue,
 		DynamicArrayAuto<Scratch::LightToRenderToScratchInfo>& scratchWorkItem,
 		DynamicArrayAuto<Scratch::LightToRenderToScratchInfo>& scratchWorkItem,
 		DynamicArrayAuto<Atlas::ResolveWorkItem>& atlasResolveWorkItem,
 		DynamicArrayAuto<Atlas::ResolveWorkItem>& atlasResolveWorkItem,