Panagiotis Christopoulos Charitos 7 years ago
parent
commit
bb1bd72a2d

+ 36 - 14
shaders/ExponentialShadowmappingResolve.glslp

@@ -16,7 +16,7 @@ struct Uniforms
 	Vec2 m_uvTranslation;
 	F32 m_near;
 	F32 m_far;
-	U32 m_blur;
+	U32 m_renderingTechnique; // If value is 0: perspective+blur, 1: perspective, 2: ortho+blur, 3: ortho
 	U32 m_padding;
 };
 
@@ -25,7 +25,7 @@ ANKI_PUSH_CONSTANTS(Uniforms, u_regs);
 #define u_uvTranslation u_regs.m_uvTranslation
 #define u_near u_regs.m_near
 #define u_far u_regs.m_far
-#define u_blur (u_regs.m_blur == 1u)
+#define u_renderingTechnique u_regs.m_renderingTechnique
 
 #pragma anki start vert
 #include <shaders/Common.glsl>
@@ -65,31 +65,53 @@ layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_inputTex;
 
 layout(location = 0) out F32 out_color;
 
-F32 sampleLinearDepth(Vec2 uv)
+F32 sampleLinearDepthPerspective(Vec2 uv)
 {
 	uv = clamp(uv, in_minUv, in_maxUv);
 	return linearizeDepth(textureLod(u_inputTex, uv, 0.0).r, u_near, u_far);
 }
 
+F32 sampleLinearDepthOrhographic(Vec2 uv)
+{
+	uv = clamp(uv, in_minUv, in_maxUv);
+	return textureLod(u_inputTex, uv, 0.0).r;
+}
+
 void main()
 {
 	const Vec2 UV_OFFSET = OFFSET * TEXEL_SIZE;
 
-	if(u_blur)
+	if(u_renderingTechnique == 0u)
+	{
+		out_color = sampleLinearDepthPerspective(in_uv) * BOX_WEIGHTS[0u];
+		out_color += sampleLinearDepthPerspective(in_uv + Vec2(UV_OFFSET.x, 0.0)) * BOX_WEIGHTS[1u];
+		out_color += sampleLinearDepthPerspective(in_uv + Vec2(-UV_OFFSET.x, 0.0)) * BOX_WEIGHTS[1u];
+		out_color += sampleLinearDepthPerspective(in_uv + Vec2(0.0, UV_OFFSET.y)) * BOX_WEIGHTS[1u];
+		out_color += sampleLinearDepthPerspective(in_uv + Vec2(0.0, -UV_OFFSET.y)) * BOX_WEIGHTS[1u];
+		out_color += sampleLinearDepthPerspective(in_uv + Vec2(UV_OFFSET.x, UV_OFFSET.y)) * BOX_WEIGHTS[2u];
+		out_color += sampleLinearDepthPerspective(in_uv + Vec2(-UV_OFFSET.x, UV_OFFSET.y)) * BOX_WEIGHTS[2u];
+		out_color += sampleLinearDepthPerspective(in_uv + Vec2(UV_OFFSET.x, -UV_OFFSET.y)) * BOX_WEIGHTS[2u];
+		out_color += sampleLinearDepthPerspective(in_uv + Vec2(-UV_OFFSET.x, -UV_OFFSET.y)) * BOX_WEIGHTS[2u];
+	}
+	else if(u_renderingTechnique == 1u)
+	{
+		out_color = sampleLinearDepthPerspective(in_uv);
+	}
+	else if(u_renderingTechnique == 2u)
 	{
-		out_color = sampleLinearDepth(in_uv) * BOX_WEIGHTS[0u];
-		out_color += sampleLinearDepth(in_uv + Vec2(UV_OFFSET.x, 0.0)) * BOX_WEIGHTS[1u];
-		out_color += sampleLinearDepth(in_uv + Vec2(-UV_OFFSET.x, 0.0)) * BOX_WEIGHTS[1u];
-		out_color += sampleLinearDepth(in_uv + Vec2(0.0, UV_OFFSET.y)) * BOX_WEIGHTS[1u];
-		out_color += sampleLinearDepth(in_uv + Vec2(0.0, -UV_OFFSET.y)) * BOX_WEIGHTS[1u];
-		out_color += sampleLinearDepth(in_uv + Vec2(UV_OFFSET.x, UV_OFFSET.y)) * BOX_WEIGHTS[2u];
-		out_color += sampleLinearDepth(in_uv + Vec2(-UV_OFFSET.x, UV_OFFSET.y)) * BOX_WEIGHTS[2u];
-		out_color += sampleLinearDepth(in_uv + Vec2(UV_OFFSET.x, -UV_OFFSET.y)) * BOX_WEIGHTS[2u];
-		out_color += sampleLinearDepth(in_uv + Vec2(-UV_OFFSET.x, -UV_OFFSET.y)) * BOX_WEIGHTS[2u];
+		out_color = sampleLinearDepthOrhographic(in_uv) * BOX_WEIGHTS[0u];
+		out_color += sampleLinearDepthOrhographic(in_uv + Vec2(UV_OFFSET.x, 0.0)) * BOX_WEIGHTS[1u];
+		out_color += sampleLinearDepthOrhographic(in_uv + Vec2(-UV_OFFSET.x, 0.0)) * BOX_WEIGHTS[1u];
+		out_color += sampleLinearDepthOrhographic(in_uv + Vec2(0.0, UV_OFFSET.y)) * BOX_WEIGHTS[1u];
+		out_color += sampleLinearDepthOrhographic(in_uv + Vec2(0.0, -UV_OFFSET.y)) * BOX_WEIGHTS[1u];
+		out_color += sampleLinearDepthOrhographic(in_uv + Vec2(UV_OFFSET.x, UV_OFFSET.y)) * BOX_WEIGHTS[2u];
+		out_color += sampleLinearDepthOrhographic(in_uv + Vec2(-UV_OFFSET.x, UV_OFFSET.y)) * BOX_WEIGHTS[2u];
+		out_color += sampleLinearDepthOrhographic(in_uv + Vec2(UV_OFFSET.x, -UV_OFFSET.y)) * BOX_WEIGHTS[2u];
+		out_color += sampleLinearDepthOrhographic(in_uv + Vec2(-UV_OFFSET.x, -UV_OFFSET.y)) * BOX_WEIGHTS[2u];
 	}
 	else
 	{
-		out_color = sampleLinearDepth(in_uv);
+		out_color = sampleLinearDepthOrhographic(in_uv);
 	}
 }
 #pragma anki end

+ 16 - 2
src/anki/renderer/ShadowMapping.cpp

@@ -40,6 +40,7 @@ public:
 	F32 m_cameraNear;
 	F32 m_cameraFar;
 	Bool8 m_blur;
+	Bool8 m_perspectiveProjection;
 };
 
 ShadowMapping::~ShadowMapping()
@@ -174,14 +175,22 @@ void ShadowMapping::runEsm(RenderPassWorkContext& rgraphCtx)
 			Vec2 m_uvTranslation;
 			F32 m_near;
 			F32 m_far;
-			U32 m_blur;
+			U32 m_renderingTechnique;
 			U32 m_padding;
 		} unis;
 		unis.m_uvScale = workItem.m_uvIn.zw();
 		unis.m_uvTranslation = workItem.m_uvIn.xy();
 		unis.m_near = workItem.m_cameraNear;
 		unis.m_far = workItem.m_cameraFar;
-		unis.m_blur = workItem.m_blur;
+
+		if(workItem.m_perspectiveProjection)
+		{
+			unis.m_renderingTechnique = (workItem.m_blur) ? 0 : 1;
+		}
+		else
+		{
+			unis.m_renderingTechnique = (workItem.m_blur) ? 2 : 3;
+		}
 
 		cmdb->setPushConstants(&unis, sizeof(unis));
 
@@ -538,6 +547,7 @@ void ShadowMapping::processLights(RenderingContext& ctx, U32& threadCountForScra
 				newScratchAndEsmResloveRenderWorkItems(esmViewports[cascade],
 					scratchViewports[cascade],
 					true,
+					false,
 					light.m_shadowRenderQueues[cascade],
 					lightsToRender,
 					esmWorkItems,
@@ -624,6 +634,7 @@ void ShadowMapping::processLights(RenderingContext& ctx, U32& threadCountForScra
 						newScratchAndEsmResloveRenderWorkItems(esmViewport,
 							scratchViewport,
 							blurEsm,
+							true,
 							light->m_shadowRenderQueues[face],
 							lightsToRender,
 							esmWorkItems,
@@ -690,6 +701,7 @@ void ShadowMapping::processLights(RenderingContext& ctx, U32& threadCountForScra
 				newScratchAndEsmResloveRenderWorkItems(esmViewport,
 					scratchViewport,
 					blurEsm,
+					true,
 					light->m_shadowRenderQueue,
 					lightsToRender,
 					esmWorkItems,
@@ -780,6 +792,7 @@ void ShadowMapping::processLights(RenderingContext& ctx, U32& threadCountForScra
 void ShadowMapping::newScratchAndEsmResloveRenderWorkItems(const Viewport& esmViewport,
 	const Viewport& scratchVewport,
 	Bool blurEsm,
+	Bool perspectiveProjection,
 	RenderQueue* lightRenderQueue,
 	DynamicArrayAuto<LightToRenderToScratchInfo>& scratchWorkItem,
 	DynamicArrayAuto<EsmResolveWorkItem>& esmResolveWorkItem,
@@ -810,6 +823,7 @@ void ShadowMapping::newScratchAndEsmResloveRenderWorkItems(const Viewport& esmVi
 		esmItem.m_cameraNear = lightRenderQueue->m_cameraNear;
 
 		esmItem.m_blur = blurEsm;
+		esmItem.m_perspectiveProjection = perspectiveProjection;
 
 		esmResolveWorkItem.emplaceBack(esmItem);
 	}

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

@@ -117,6 +117,7 @@ private:
 	void newScratchAndEsmResloveRenderWorkItems(const Viewport& esmViewport,
 		const Viewport& scratchVewport,
 		Bool blurEsm,
+		Bool perspectiveProjection,
 		RenderQueue* lightRenderQueue,
 		DynamicArrayAuto<LightToRenderToScratchInfo>& scratchWorkItem,
 		DynamicArrayAuto<EsmResolveWorkItem>& esmResolveWorkItem,

+ 16 - 12
src/anki/scene/components/LightComponent.cpp

@@ -89,7 +89,8 @@ void LightComponent::setupDirectionalLightQueueElement(
 		// Gather the edges
 		Array<Vec4, (MAX_SHADOW_CASCADES + 1) * 4> edgesLocalSpaceStorage;
 		WeakArray<Vec4> edgesLocalSpace(&edgesLocalSpaceStorage[0], (m_dir.m_cascadeCount + 1) * 4);
-		edgesLocalSpace[0] = edgesLocalSpace[1] = edgesLocalSpace[2] = edgesLocalSpace[3] = Vec4(0.0f); // Eye
+		edgesLocalSpace[0] = edgesLocalSpace[1] = edgesLocalSpace[2] = edgesLocalSpace[3] =
+			Vec4(0.0f, 0.0f, 0.0f, 1.0f); // Eye
 		for(U i = 0; i < m_dir.m_cascadeCount; ++i)
 		{
 			const F32 clusterFarNearDist = far / F32(m_dir.m_cascadeCount);
@@ -127,7 +128,6 @@ void LightComponent::setupDirectionalLightQueueElement(
 				aabbMax = aabbMax.max(edgesLightSpace[j].xyz());
 			}
 
-			aabbMax.z() = min(0.0f, aabbMax.z()); // Max can't go behind the light
 			ANKI_ASSERT(aabbMax > aabbMin);
 
 			minMaxes[i][0] = aabbMin;
@@ -137,19 +137,22 @@ void LightComponent::setupDirectionalLightQueueElement(
 		// Compute the view and projection matrices per cascade
 		for(U i = 0; i < m_dir.m_cascadeCount; ++i)
 		{
-			const Vec3 halfDistances = (minMaxes[i][1] - minMaxes[i][0]) / 2.0f;
-			ANKI_ASSERT(halfDistances > Vec3(0.0f));
+			const Vec3& min = minMaxes[i][0];
+			const Vec3& max = minMaxes[i][1];
+
+			const Vec2 halfDistances = (max.xy() - min.xy()) / 2.0f;
+			ANKI_ASSERT(halfDistances > Vec2(0.0f));
 
 			const Mat4 cascadeProjMat = Mat4::calculateOrthographicProjectionMatrix(halfDistances.x(),
-				halfDistances.x(),
+				-halfDistances.x(),
 				halfDistances.y(),
 				-halfDistances.y(),
-				halfDistances.z(),
-				-halfDistances.z());
+				LIGHT_FRUSTUM_NEAR_PLANE,
+				max.z() - min.z());
 
 			Vec4 eye;
-			eye.x() = (minMaxes[i][1].x() + minMaxes[i][0].x()) / 2.0f;
-			eye.y() = (minMaxes[i][1].y() + minMaxes[i][0].y()) / 2.0f;
+			eye.x() = (max.x() + min.x()) / 2.0f;
+			eye.y() = (max.y() + min.y()) / 2.0f;
 			eye.z() = 0.0f;
 			eye.w() = 1.0f;
 			eye = lightTrf * eye;
@@ -158,15 +161,16 @@ void LightComponent::setupDirectionalLightQueueElement(
 			cascadeTransform.setOrigin(eye.xyz0());
 			const Mat4 cascadeViewMat = Mat4(cascadeTransform.getInverse());
 
-			static const Mat4 biasMat4(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0);
+			static const Mat4 biasMat4(
+				0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 0.0f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
 			el.m_textureMatrices[i] = biasMat4 * cascadeProjMat * cascadeViewMat;
 
 			// Fill the frustum
 			OrthographicFrustum& cascadeFrustum = cascadeFrustums[i];
 			cascadeFrustum.setAll(-halfDistances.x(),
 				halfDistances.x(),
-				-halfDistances.z(),
-				halfDistances.z(),
+				LIGHT_FRUSTUM_NEAR_PLANE,
+				max.z() - min.z(),
 				halfDistances.y(),
 				-halfDistances.y());
 			cascadeFrustum.transform(cascadeTransform);