ソースを参照

Add directional light support to the exporter

Panagiotis Christopoulos Charitos 7 年 前
コミット
8774aa134e

BIN
samples/sponza/assets/metal_rod.ankimesh


+ 3 - 6
samples/sponza/assets/scene.lua

@@ -2507,16 +2507,13 @@ trf:setRotation(rot)
 trf:setScale(0.0170465)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 
-node = scene:newSpotLightNode("Lamp")
+node = scene:newDirectionalLightNode("Lamp")
 lcomp = node:getSceneNodeBase():getLightComponent()
 lcomp:setDiffuseColor(Vec4.new(15, 15, 15, 1))
-lcomp:setInnerAngle(0.737402)
-lcomp:setOuterAngle(1.4748)
-lcomp:setDistance(89.9999)
 trf = Transform.new()
-trf:setOrigin(Vec4.new(9.66932, 40.2052, -9.96416, 0))
+trf:setOrigin(Vec4.new(9.66932, 40.2052, -6.74682, 0))
 rot = Mat3x4.new()
-rot:setAll(-0.175432, -0.931125, 0.319735, 0, -0.392148, 0.363986, 0.844828, 0, -0.903019, 0.0228264, -0.428994, 0)
+rot:setAll(-0.175432, -0.931125, 0.319735, 0, -0.293426, 0.359464, 0.885825, 0, -0.939747, 0.0615835, -0.336278, 0)
 trf:setRotation(rot)
 trf:setScale(1)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)

BIN
samples/sponza/assets/sponza_05.ankimesh


BIN
samples/sponza/assets/sponza_117.ankimesh


BIN
samples/sponza/assets/sponza_18.ankimesh


BIN
samples/sponza/assets/sponza_382.ankimesh


+ 1 - 1
shaders/LightFunctions.glsl

@@ -169,7 +169,7 @@ F32 computeShadowFactorDirLight(DirectionalLight light, U32 cascadeIdx, Vec3 wor
 	F32 cascadeLinearDepth = texCoords3.z;
 
 	F32 shadowFactor = textureLod(shadowMap, texCoords3.xy, 0.0).r;
-	shadowFactor = saturate(exp(ESM_CONSTANT * 50.0 * (shadowFactor - cascadeLinearDepth)));
+	shadowFactor = saturate(exp(ESM_CONSTANT * 100.0 * (shadowFactor - cascadeLinearDepth)));
 
 	return shadowFactor;
 }

+ 1 - 1
src/anki/collision/Plane.cpp

@@ -26,7 +26,7 @@ void Plane::setFrom3Points(const Vec4& p0, const Vec4& p1, const Vec4& p2)
 	m_normal = u.cross(v);
 
 	// length of normal had better not be zero
-	ANKI_ASSERT(!isZero(m_normal.getLengthSquared()));
+	ANKI_ASSERT(m_normal.getLengthSquared() != 0.0f);
 
 	m_normal.normalize();
 	m_offset = m_normal.dot(p0);

+ 5 - 9
src/anki/renderer/ShadowMapping.cpp

@@ -516,6 +516,7 @@ void ShadowMapping::processLights(RenderingContext& ctx, U32& threadCountForScra
 		Array<Viewport, MAX_SHADOW_CASCADES> scratchViewports;
 		Array<TileAllocatorResult, MAX_SHADOW_CASCADES> subResults;
 		Array<U32, MAX_SHADOW_CASCADES> lods;
+		Array<Bool, MAX_SHADOW_CASCADES> blurEsms;
 
 		for(U cascade = 0; cascade < light.m_shadowCascadeCount; ++cascade)
 		{
@@ -524,14 +525,9 @@ void ShadowMapping::processLights(RenderingContext& ctx, U32& threadCountForScra
 			cascadeIndices[cascade] = cascade;
 			drawcallCounts[cascade] = 1; // Doesn't matter
 
-			if(cascade <= 1)
-			{
-				lods[cascade] = m_lodCount - 1; // Always the best quality
-			}
-			else
-			{
-				lods[cascade] = lods[0] - 1;
-			}
+			// Change the quality per cascade
+			blurEsms[cascade] = (cascade <= 1);
+			lods[cascade] = (cascade <= 1) ? (m_lodCount - 1) : (lods[0] - 1);
 		}
 
 		const Bool allocationFailed = allocateTilesAndScratchTiles(light.m_uuid,
@@ -556,7 +552,7 @@ void ShadowMapping::processLights(RenderingContext& ctx, U32& threadCountForScra
 				// Push work
 				newScratchAndEsmResloveRenderWorkItems(esmViewports[cascade],
 					scratchViewports[cascade],
-					true,
+					blurEsms[cascade],
 					false,
 					light.m_shadowRenderQueues[cascade],
 					lightsToRender,

+ 8 - 0
src/anki/scene/components/LightComponent.cpp

@@ -163,6 +163,14 @@ void LightComponent::setupDirectionalLightQueueElement(
 			// Adjust the max to take into account the scene bounds
 			aabbMax.z() = max(aabbMax.z(), m_dir.m_sceneAabbMaxZLightSpace);
 
+			// Align it to avoid flickering
+			const PtrSize alignmentMeters = 2;
+			for(U j = 0; j < 3; ++j)
+			{
+				aabbMin[j] = getAlignedRoundDown(alignmentMeters, I32(aabbMin[j]));
+				aabbMax[j] = getAlignedRoundUp(alignmentMeters, I32(aabbMax[j]));
+			}
+
 			ANKI_ASSERT(aabbMax > aabbMin);
 			minMaxes[i][0] = aabbMin;
 			minMaxes[i][1] = aabbMax;

+ 25 - 8
tools/scene/Exporter.cpp

@@ -451,7 +451,8 @@ void Exporter::exportLight(const aiLight& light)
 
 	LOGI("Exporting light %s", light.mName.C_Str());
 
-	if(light.mType != aiLightSource_POINT && light.mType != aiLightSource_SPOT)
+	if(light.mType != aiLightSource_POINT && light.mType != aiLightSource_SPOT
+		&& light.mType != aiLightSource_DIRECTIONAL)
 	{
 		LOGW("Skipping light %s. Unsupported type (0x%x)", light.mName.C_Str(), light.mType);
 		return;
@@ -463,8 +464,24 @@ void Exporter::exportLight(const aiLight& light)
 		return;
 	}
 
-	file << "\nnode = scene:new" << ((light.mType == aiLightSource_POINT) ? "Point" : "Spot") << "LightNode(\""
-		 << light.mName.C_Str() << "\")\n";
+	const char* lightType;
+	switch(light.mType)
+	{
+	case aiLightSource_POINT:
+		lightType = "Point";
+		break;
+	case aiLightSource_SPOT:
+		lightType = "Spot";
+		break;
+	case aiLightSource_DIRECTIONAL:
+		lightType = "Directional";
+		break;
+	default:
+		lightType = nullptr;
+		assert(0);
+	}
+
+	file << "\nnode = scene:new" << lightType << "LightNode(\"" << light.mName.C_Str() << "\")\n";
 
 	file << "lcomp = node:getSceneNodeBase():getLightComponent()\n";
 
@@ -474,15 +491,12 @@ void Exporter::exportLight(const aiLight& light)
 	file << "lcomp:setDiffuseColor(Vec4.new(" << linear[0] << ", " << linear[1] << ", " << linear[2] << ", 1))\n";
 
 	// Geometry
-	aiVector3D direction(0.0, 0.0, 1.0);
-
 	switch(light.mType)
 	{
 	case aiLightSource_POINT:
 	{
 		// At this point I want the radius and have the attenuation factors
-		// att = Ac + Al*d + Aq*d^2. When d = r then att = 0.0. Also if we
-		// assume that Al is 0 then:
+		// att = Ac + Al*d + Aq*d^2. When d = r then att = 0.0. Also if we assume that Al is 0 then:
 		// 0 = Ac + Aq*r^2. Solving by r is easy
 		float r = sqrt(light.mAttenuationConstant / light.mAttenuationQuadratic);
 		file << "lcomp:setRadius(" << r << ")\n";
@@ -502,8 +516,11 @@ void Exporter::exportLight(const aiLight& light)
 		file << "lcomp:setInnerAngle(" << inner << ")\n"
 			 << "lcomp:setOuterAngle(" << outer << ")\n"
 			 << "lcomp:setDistance(" << dist << ")\n";
+		break;
+	}
+	case aiLightSource_DIRECTIONAL:
+	{
 
-		direction = light.mDirection;
 		break;
 	}
 	default: