Browse Source

Add some form of cascade blending

Panagiotis Christopoulos Charitos 3 years ago
parent
commit
f8162fdb44

+ 1 - 1
AnKi/Gr/Vulkan/GrManagerImpl.cpp

@@ -1583,7 +1583,7 @@ Error GrManagerImpl::printPipelineShaderInfoInternal(VkPipeline ppline, CString
 
 		StringAuto finalLog(m_alloc);
 		log.join("", finalLog);
-		ANKI_VK_LOGI("%s", finalLog.cstr());
+		ANKI_VK_LOGV("%s", finalLog.cstr());
 	}
 
 	return Error::NONE;

+ 1 - 1
AnKi/Importer/GltfImporter.cpp

@@ -532,7 +532,7 @@ Error GltfImporter::visitNode(const cgltf_node& node, const Transform& parentTrf
 			const Transform localTrf = Transform(tsl.xyz0(), Mat3x4(Vec3(0.0f), rot), 1.0f);
 			ANKI_CHECK(writeTransform(parentTrf.combineTransformations(localTrf)));
 		}
-		else if((it = extras.find("gi_probe")) != extras.getEnd() && *it == "true")
+		else if((it = extras.find("gi_probe")) != extras.getEnd() && (*it == "true" || *it == "1"))
 		{
 			Vec3 tsl;
 			Mat3 rot;

+ 16 - 0
AnKi/Shaders/LightFunctions.glsl

@@ -400,6 +400,22 @@ U32 computeShadowCascadeIndex(F32 distance, F32 p, F32 effectiveShadowDistance,
 	return U32(idx);
 }
 
+/// Bring the indices of the closest cascades and a factor to blend them. To visualize what's going on go to
+/// https://www.desmos.com/calculator/dwlbq2j55i
+UVec2 computeShadowCascadeIndex2(F32 distance, F32 p, F32 effectiveShadowDistance, U32 shadowCascadeCount,
+								 out F32 blendFactor)
+{
+	const F32 shadowCascadeCountf = F32(shadowCascadeCount);
+	const F32 idx = pow(distance / effectiveShadowDistance, 1.0f / p) * shadowCascadeCountf;
+
+	const U32 cascadeA = min(U32(idx), shadowCascadeCount - 1u);
+	const U32 cascadeB = min(cascadeA + 1u, shadowCascadeCount - 1u);
+
+	blendFactor = pow(fract(idx), 24.0);
+
+	return UVec2(cascadeA, cascadeB);
+}
+
 /// To play with it use https://www.shadertoy.com/view/sttSDf
 /// http://jcgt.org/published/0007/04/01/paper.pdf by Eric Heitz
 /// Input v: view direction

+ 21 - 6
AnKi/Shaders/ShadowmapsResolve.glsl

@@ -65,12 +65,27 @@ void main()
 		ANKI_RP F32 shadowFactor;
 		if(positiveZViewSpace < dirLight.m_effectiveShadowDistance)
 		{
-			const U32 cascadeIdx =
-				computeShadowCascadeIndex(positiveZViewSpace, dirLight.m_shadowCascadesDistancePower,
-										  dirLight.m_effectiveShadowDistance, dirLight.m_cascadeCount);
-
-			shadowFactor =
-				computeShadowFactorDirLight(dirLight, cascadeIdx, worldPos, u_shadowAtlasTex, u_linearAnyClampSampler);
+			F32 cascadeBlendFactor;
+			const UVec2 cascadeIndices = computeShadowCascadeIndex2(
+				positiveZViewSpace, dirLight.m_shadowCascadesDistancePower, dirLight.m_effectiveShadowDistance,
+				dirLight.m_cascadeCount, cascadeBlendFactor);
+
+			const F32 shadowFactorCascadeA = computeShadowFactorDirLight(dirLight, cascadeIndices.x, worldPos,
+																		 u_shadowAtlasTex, u_linearAnyClampSampler);
+
+			if(cascadeBlendFactor < 0.01 || cascadeIndices.x == cascadeIndices.y)
+			{
+				// Don't blend cascades
+				shadowFactor = shadowFactorCascadeA;
+			}
+			else
+			{
+				// Blend cascades
+				const F32 shadowFactorCascadeB = computeShadowFactorDirLight(dirLight, cascadeIndices.y, worldPos,
+																			 u_shadowAtlasTex, u_linearAnyClampSampler);
+
+				shadowFactor = mix(shadowFactorCascadeA, shadowFactorCascadeB, cascadeBlendFactor);
+			}
 
 			ANKI_RP F32 distanceFadeFactor = saturate(positiveZViewSpace / dirLight.m_effectiveShadowDistance);
 			distanceFadeFactor = pow(distanceFadeFactor, 8.0);