Browse Source

Fixing a bug in spatial logic. Add poisson shadowmapping

Panagiotis Christopoulos Charitos 12 years ago
parent
commit
0ba4872ca0

+ 4 - 4
include/anki/renderer/Sm.h

@@ -29,9 +29,9 @@ public:
 		return enabled;
 	}
 
-	Bool getPcfEnabled() const
+	Bool getPoissonEnabled() const
 	{
-		return pcfEnabled;
+		return poissonEnabled;
 	}
 	/// @}
 
@@ -55,8 +55,8 @@ private:
 	/// If false then disable SM at all
 	Bool enabled; 
 
-	/// Enable Percentage Closer Filtering for all the levels
-	Bool pcfEnabled;
+	/// Enable Poisson for all the levels
+	Bool poissonEnabled;
 
 	/// Shadowmap bilinear filtering for the first level. Better quality
 	Bool bilinearEnabled;

+ 11 - 2
include/anki/scene/SpatialComponent.h

@@ -34,7 +34,9 @@ public:
 		/// with any surface then it shouldn't be visible and be processed 
 		/// further. This flag is being used to check if we should test agains
 		/// near plane when using the tiler for visibility tests.
-		SF_FULLY_TRANSPARENT = 1 << 3
+		SF_FULLY_TRANSPARENT = 1 << 3,
+
+		SF_MARKED_FOR_UPDATE = 1 << 4
 	};
 
 	/// Pass the collision shape here so we can avoid the virtuals
@@ -108,8 +110,15 @@ public:
 
 	/// The derived class has to manually call this method when the collision 
 	/// shape got updated
-	void markForUpdate();
+	void markForUpdate()
+	{
+		enableBits(SF_MARKED_FOR_UPDATE);
+	}
+
+	/// Update
+	void update();
 
+	/// Disable some flags
 	void resetFrame();
 
 protected:

+ 21 - 22
shaders/IsLp.glsl

@@ -187,25 +187,6 @@ float calcSpotFactor(in SpotLight light, in vec3 frag2LightVec)
 	return spotFactor;
 }
 
-//==============================================================================
-#if PCF == 1
-float pcfLow(in sampler2DArrayShadow shadowMap, in vec3 shadowUv)
-{
-	float shadowCol = textureOffset(shadowMap, shadowUv, ivec2(-1, -1));
-	shadowCol += textureOffset(shadowMap, shadowUv, ivec2(0, -1));
-	shadowCol += textureOffset(shadowMap, shadowUv, ivec2(1, -1));
-	shadowCol += textureOffset(shadowMap, shadowUv, ivec2(-1, 0));
-	shadowCol += textureOffset(shadowMap, shadowUv, ivec2(0, 0));
-	shadowCol += textureOffset(shadowMap, shadowUv, ivec2(1, 0));
-	shadowCol += textureOffset(shadowMap, shadowUv, ivec2(-1, 1));
-	shadowCol += textureOffset(shadowMap, shadowUv, ivec2(0, 1));
-	shadowCol += textureOffset(shadowMap, shadowUv, ivec2(1, 1));
-
-	shadowCol *= (1.0 / 9.0);
-	return shadowCol;
-}
-#endif
-
 //==============================================================================
 float calcShadowFactor(in SpotTexLight light, in vec3 fragPosVspace, 
 	in mediump sampler2DArrayShadow shadowMapArr, in float layer)
@@ -213,14 +194,32 @@ float calcShadowFactor(in SpotTexLight light, in vec3 fragPosVspace,
 	vec4 texCoords4 = light.texProjectionMat * vec4(fragPosVspace, 1.0);
 	vec3 texCoords3 = texCoords4.xyz / texCoords4.w;
 
-#if PCF == 1
-	float shadowFactor = pcfLow(shadowMapArr, texCoords3);
+#if POISSON == 1
+	const vec2 poissonDisk[4] = vec2[](
+		vec2(-0.94201624, -0.39906216),
+		vec2(0.94558609, -0.76890725),
+		vec2(-0.094184101, -0.92938870),
+		vec2(0.34495938, 0.29387760));
+
+	float shadowFactor = 0.0;
+
+	vec2 cordpart0 = vec2(layer, texCoords3.z);
+
+	for(int i = 0; i < 4; i++)
+	{
+		vec2 cordpart1 = texCoords3.xy + poissonDisk[i] / (300.0);
+		vec4 tcoord = vec4(cordpart1, cordpart0);
+		
+		shadowFactor += texture(shadowMapArr, tcoord);
+	}
+
+	return shadowFactor / 4.0;
 #else
 	vec4 tcoord = vec4(texCoords3.x, texCoords3.y, layer, texCoords3.z);
 	float shadowFactor = texture(shadowMapArr, tcoord);
-#endif
 
 	return shadowFactor;
+#endif
 }
 
 //==============================================================================

+ 3 - 3
src/renderer/Is.cpp

@@ -464,13 +464,13 @@ void Is::initInternal(const RendererInitializer& initializer)
 		<< "\n#define TILES_BLOCK_BINDING " << TILES_BLOCK_BINDING
 		<< "\n";
 
-	if(sm.getPcfEnabled())
+	if(sm.getPoissonEnabled())
 	{
-		pps << "#define PCF 1\n";
+		pps << "#define POISSON 1\n";
 	}
 	else
 	{
-		pps << "#define PCF 0\n";
+		pps << "#define POISSON 0\n";
 	}
 
 	// point light

+ 1 - 1
src/renderer/Renderer.cpp

@@ -20,7 +20,7 @@ RendererInitializer::RendererInitializer()
 
 	// Is
 	newOption("is.sm.enabled", true);
-	newOption("is.sm.pcfEnabled", true);
+	newOption("is.sm.poissonEnabled", true);
 	newOption("is.sm.bilinearEnabled", true);
 	newOption("is.sm.resolution", 512);
 	newOption("is.sm.maxLights", 4);

+ 1 - 1
src/renderer/Sm.cpp

@@ -18,7 +18,7 @@ void Sm::init(const RendererInitializer& initializer)
 		return;
 	}
 
-	pcfEnabled = initializer.get("is.sm.pcfEnabled");
+	poissonEnabled = initializer.get("is.sm.poissonEnabled");
 	bilinearEnabled = initializer.get("is.sm.bilinearEnabled");
 	resolution = initializer.get("is.sm.resolution");
 

+ 1 - 0
src/scene/SceneGraph.cpp

@@ -46,6 +46,7 @@ static void updateSceneNode(SceneNode& sn, F32 prevUpdateTime,
 	SpatialComponent* sp = sn.getSpatialComponent();
 	if(sp)
 	{
+		sp->update();
 		sp->resetFrame();
 	}
 

+ 15 - 7
src/scene/SpatialComponent.cpp

@@ -19,20 +19,28 @@ SpatialComponent::~SpatialComponent()
 {}
 
 //==============================================================================
-void SpatialComponent::markForUpdate()
+void SpatialComponent::update()
 {
-	visitThisAndChildren([](SpatialComponent& sp)
+	if(getParent() == nullptr)
 	{
-		sp.updateInternal();
-	});
+		visitThisAndChildren([](SpatialComponent& sp)
+		{
+			sp.updateInternal();
+		});	
+	}
 }
 
 //==============================================================================
 void SpatialComponent::updateInternal()
 {
-	spatialCs->toAabb(aabb);
-	origin = (aabb.getMax() + aabb.getMin()) * 0.5;
-	timestamp = getGlobTimestamp();
+	if(bitsEnabled(SF_MARKED_FOR_UPDATE))
+	{
+		spatialCs->toAabb(aabb);
+		origin = (aabb.getMax() + aabb.getMin()) * 0.5;
+		timestamp = getGlobTimestamp();
+
+		disableBits(SF_MARKED_FOR_UPDATE);
+	}
 }
 
 //==============================================================================

+ 2 - 2
testapp/Main.cpp

@@ -477,7 +477,7 @@ void mainLoop()
 
 		// Sleep
 		//
-#if 0
+#if 1
 		timer.stop();
 		if(timer.getElapsedTime() < AppSingleton::get().getTimerTick())
 		{
@@ -548,7 +548,7 @@ void initSubsystems(int argc, char* argv[])
 	initializer.get("is.sm.bilinearEnabled") = true;
 	initializer.get("is.groundLightEnabled") = true;
 	initializer.get("is.sm.enabled") = true;
-	initializer.get("is.sm.pcfEnabled") = false;
+	initializer.get("is.sm.poissonEnabled") = true;
 	initializer.get("is.sm.resolution") = 512;
 	initializer.get("pps.enabled") = true;
 	initializer.get("pps.hdr.enabled") = true;