Panagiotis Christopoulos Charitos 10 ani în urmă
părinte
comite
8914ae09fd
5 a modificat fișierele cu 116 adăugiri și 166 ștergeri
  1. 14 12
      include/anki/scene/Clusterer.h
  2. 1 1
      shaders/IsLp.frag.glsl
  3. 1 1
      src/renderer/Lf.cpp
  4. 92 145
      src/scene/Clusterer.cpp
  5. 8 7
      testapp/Main.cpp

+ 14 - 12
include/anki/scene/Clusterer.h

@@ -52,7 +52,6 @@ class Clusterer
 {
 {
 public:
 public:
 	static constexpr U TILE_SIZE = 64;
 	static constexpr U TILE_SIZE = 64;
-	static constexpr F32 NEAR_BIAS = 2.0;
 
 
 	Clusterer(const GenericMemoryPoolAllocator<U8>& alloc)
 	Clusterer(const GenericMemoryPoolAllocator<U8>& alloc)
 		: m_alloc(alloc)
 		: m_alloc(alloc)
@@ -61,6 +60,7 @@ public:
 	~Clusterer()
 	~Clusterer()
 	{
 	{
 		m_clusters.destroy(m_alloc);
 		m_clusters.destroy(m_alloc);
+		m_splitInfo.destroy(m_alloc);
 	}
 	}
 
 
 	void init(U clusterCountX, U clusterCountY, U clusterCountZ)
 	void init(U clusterCountX, U clusterCountY, U clusterCountZ)
@@ -81,6 +81,10 @@ public:
 	void bin(const CollisionShape& cs, ClustererTestResult& rez) const;
 	void bin(const CollisionShape& cs, ClustererTestResult& rez) const;
 
 
 public:
 public:
+	GenericMemoryPoolAllocator<U8> m_alloc;
+
+	Array<U8, 3> m_counts;
+
 	class Cluster
 	class Cluster
 	{
 	{
 	public:
 	public:
@@ -89,13 +93,18 @@ public:
 		Vec3 m_max;
 		Vec3 m_max;
 	};
 	};
 
 
-	GenericMemoryPoolAllocator<U8> m_alloc;
-
-	Array<U8, 3> m_counts;
-
 	/// [z][y][x]
 	/// [z][y][x]
 	DArray<Cluster> m_clusters;
 	DArray<Cluster> m_clusters;
 
 
+	class SplitInfo
+	{
+	public:
+		Vec2 m_xy;
+		Vec2 m_sizes;
+	};
+
+	DArray<SplitInfo> m_splitInfo;
+
 	F32 m_near = 0.0;
 	F32 m_near = 0.0;
 	F32 m_far = 0.0;
 	F32 m_far = 0.0;
 	F32 m_fovY = 0.0;
 	F32 m_fovY = 0.0;
@@ -125,13 +134,6 @@ public:
 
 
 	void initClusters();
 	void initClusters();
 
 
-	void binSphere(const Sphere& s, ClustererTestResult& rez) const;
-
-	void binGeneric(const CollisionShape& cs, ClustererTestResult& rez) const;
-
-	void findTilesFromAabb(const Aabb& box, U& tileBeginX, U& tileBeginY,
-		U& tileEndX, U& tileEndY) const;
-
 	void findSplitsFromAabb(const Aabb& box, U& zFrom, U& zTo) const;
 	void findSplitsFromAabb(const Aabb& box, U& zFrom, U& zTo) const;
 };
 };
 /// @}
 /// @}

+ 1 - 1
shaders/IsLp.frag.glsl

@@ -10,7 +10,7 @@
 #define PI 3.1415926535
 #define PI 3.1415926535
 
 
 #define ATTENUATION_FINE 0
 #define ATTENUATION_FINE 0
-#define ATTENUATION_BOOST (0.1)
+#define ATTENUATION_BOOST (0.05)
 
 
 #ifndef BRDF
 #ifndef BRDF
 #	define BRDF 1
 #	define BRDF 1

+ 1 - 1
src/renderer/Lf.cpp

@@ -176,7 +176,7 @@ void Lf::runOcclusionTests(CommandBufferPtr& cmdb)
 
 
 		if(vi.getLensFlaresCount() > m_maxFlares)
 		if(vi.getLensFlaresCount() > m_maxFlares)
 		{
 		{
-			ANKI_LOGW("Visible flares exceed the limit");
+			ANKI_LOGW("Visible flares exceed the limit. Increase lf.maxFlares");
 		}
 		}
 
 
 		U frame = getGlobalTimestamp() % m_positionsVertBuff.getSize();
 		U frame = getGlobalTimestamp() % m_positionsVertBuff.getSize();

+ 92 - 145
src/scene/Clusterer.cpp

@@ -67,6 +67,11 @@ void Clusterer::prepare(const PerspectiveFrustum& fr,
 		m_clusters.resize(m_alloc, clusterCount);
 		m_clusters.resize(m_alloc, clusterCount);
 	}
 	}
 
 
+	if(m_counts[2] != m_splitInfo.getSize())
+	{
+		m_splitInfo.resize(m_alloc, m_counts[2]);
+	}
+
 	initClusters();
 	initClusters();
 }
 }
 
 
@@ -115,6 +120,16 @@ void Clusterer::initClusters()
 				ANKI_ASSERT(min.xyz() < max.xyz());
 				ANKI_ASSERT(min.xyz() < max.xyz());
 				cluster(x, y, z).m_min = min.xyz();
 				cluster(x, y, z).m_min = min.xyz();
 				cluster(x, y, z).m_max = max.xyz();
 				cluster(x, y, z).m_max = max.xyz();
+
+				// Set split info
+				if(x == 0 && y == 0)
+				{
+					Vec2 xy(min.x(), min.y());
+					Vec2 sizes(max.x() - min.x(), max.y() - min.y());
+
+					m_splitInfo[z].m_xy = xy;
+					m_splitInfo[z].m_sizes = sizes;
+				}
 			}
 			}
 		}
 		}
 	}
 	}
@@ -125,164 +140,88 @@ void Clusterer::bin(const CollisionShape& cs, ClustererTestResult& rez) const
 {
 {
 	rez.m_count = 0;
 	rez.m_count = 0;
 
 
-	if(isa<Sphere>(cs))
-	{
-		// Specialized
-		binSphere(dcast<const Sphere&>(cs), rez);
-	}
-	else
-	{
-		binGeneric(cs, rez);
-	}
-}
-
-//==============================================================================
-void Clusterer::findTilesFromAabb(const Aabb& box, U& tileBeginX, U& tileBeginY,
-	U& tileEndX, U& tileEndY) const
-{
-	// Project front face of the AABB
-	const Vec4& minv = box.getMin();
-	const Vec4& maxv = box.getMax();
-
-	Array<Vec4, 8> projPoints;
-	projPoints[0] = Vec4(minv.x(), minv.y(), maxv.z(), 1.0);
-	projPoints[1] = Vec4(maxv.x(), minv.y(), maxv.z(), 1.0);
-	projPoints[2] = Vec4(maxv.x(), maxv.y(), maxv.z(), 1.0);
-	projPoints[3] = Vec4(minv.x(), maxv.y(), maxv.z(), 1.0);
-	projPoints[4] = Vec4(minv.x(), minv.y(), minv.z(), 1.0);
-	projPoints[5] = Vec4(maxv.x(), minv.y(), minv.z(), 1.0);
-	projPoints[6] = Vec4(maxv.x(), maxv.y(), minv.z(), 1.0);
-	projPoints[7] = Vec4(minv.x(), maxv.y(), minv.z(), 1.0);
-
-	Vec2 min2(MAX_F32), max2(MIN_F32);
-	for(Vec4& p : projPoints)
-	{
-		p = m_projMat * p;
-		p /= abs(p.w());
-
-		for(U i = 0; i < 2; ++i)
-		{
-			min2[i] = min(min2[i], p[i]);
-			max2[i] = max(max2[i], p[i]);
-		}
-	}
-
-	min2 = min2 * 0.5 + 0.5;
-	max2 = max2 * 0.5 + 0.5;
-
-	// Find tiles affected
-	F32 tcountX = m_counts[0];
-	F32 tcountY = m_counts[1];
-
-	I xFrom = floor(tcountX * min2.x());
-	xFrom = clamp<I>(xFrom, 0, tcountX);
-
-	I xTo = ceil(tcountX * max2.x());
-	xTo = min<U>(xTo, tcountX);
+	Aabb box;
+	cs.computeAabb(box);
 
 
-	I yFrom = floor(tcountY * min2.y());
-	yFrom = clamp<I>(yFrom, 0, tcountY);
+	U beginZ, endZ;
 
 
-	I yTo = ceil(tcountY * max2.y());
-	yTo = min<I>(yTo, tcountY);
+	// Find splits that cover the box
+	findSplitsFromAabb(box, beginZ, endZ);
 
 
-	ANKI_ASSERT(xFrom >= 0 && xFrom <= tcountX
-		&& xTo >= 0 && xTo <= tcountX);
-	ANKI_ASSERT(yFrom >= 0 && yFrom <= tcountX
-		&& yTo >= 0 && yFrom <= tcountY);
-
-	tileBeginX = xFrom;
-	tileBeginY = yFrom;
-	tileEndX = xTo;
-	tileEndY = yTo;
-}
-
-//==============================================================================
-void Clusterer::findSplitsFromAabb(const Aabb& box, U& zFrom, U& zTo) const
-{
-	zFrom = calcK(box.getMax().z());
-	zTo = calcK(box.getMin().z()) + 1;
-	ANKI_ASSERT(zFrom <= zTo);
-}
-
-//==============================================================================
-void Clusterer::binSphere(const Sphere& s, ClustererTestResult& rez) const
-{
-	Aabb aabb;
-	s.computeAabb(aabb);
-
-	const Vec4& scent = s.getCenter();
-	const F32 srad = s.getRadius();
-
-	// Find the tiles that are covered
-	//
-
-	U tileBeginX, tileBeginY, tileEndX, tileEndY;
-
-	if(ANKI_UNLIKELY(scent.getLengthSquared() <= srad * srad))
+	// For each split find the x and y clusters
+	for(U z = beginZ; z < endZ; ++z)
 	{
 	{
-		// The eye is inside the sphere. All tiles are covered
-		tileBeginX = tileBeginY = 0;
-		tileEndX = m_counts[0];
-		tileEndY = m_counts[1];
-	}
-	else
-	{
-		findTilesFromAabb(aabb, tileBeginX, tileBeginY, tileEndX, tileEndY);
-	}
+		const SplitInfo& info = m_splitInfo[z];
 
 
-	U zFrom, zTo;
-	findSplitsFromAabb(aabb, zFrom, zTo);
+		I beginX = -1, endX = -1, beginY = -1, endY = -1;
 
 
-	// Detailed tests
-	for(U z = zFrom; z < zTo; ++z)
-	{
-		for(U y = tileBeginY; y < tileEndY; ++y)
+		// Find beginX
+		F32 x = box.getMin().x();
+		if(x <= info.m_xy.x())
 		{
 		{
-			for(U x = tileBeginX; x < tileEndX; ++x)
-			{
-				const Cluster& cl = cluster(x, y, z);
-				Aabb clusterAabb(cl.m_min.xyz0(), cl.m_max.xyz0());
-				if(testCollisionShapes(s, clusterAabb))
-				{
-					Array<U8, 3> ids = {static_cast<U8>(x),
-						static_cast<U8>(y), static_cast<U8>(z)};
-					rez.m_clusterIds[rez.m_count++] = ids;
-				}
-			}
+			beginX = 0;
 		}
 		}
-	}
-}
+		else if(x >= (info.m_xy.x() + info.m_sizes.x() * m_counts[0]))
+		{
+			beginX = m_counts[0];
+		}
+		else
+		{
+			beginX = (x - info.m_xy.x()) / info.m_sizes.x();
+		}
+		ANKI_ASSERT(beginX >= 0 && beginX <= m_counts[0]);
 
 
-//==============================================================================
-void Clusterer::binGeneric(const CollisionShape& cs,
-	ClustererTestResult& rez) const
-{
-	Aabb aabb;
-	cs.computeAabb(aabb);
+		// Find endX
+		x = box.getMax().x();
+		if(x <= info.m_xy.x())
+		{
+			endX = 0;
+		}
+		else if(x >= (info.m_xy.x() + info.m_sizes.x() * m_counts[0]))
+		{
+			endX = m_counts[0];
+		}
+		else
+		{
+			endX = ceil((x - info.m_xy.x()) / info.m_sizes.x());
+		}
+		ANKI_ASSERT(endX >= 0 && endX <= m_counts[0]);
 
 
-	U tileBeginX, tileBeginY, tileEndX, tileEndY;
-	if(ANKI_UNLIKELY(aabb.getMax().z() >= -m_near))
-	{
-		// The eye is inside the sphere. All tiles are covered
-		tileBeginX = tileBeginY = 0;
-		tileEndX = m_counts[0];
-		tileEndY = m_counts[1];
-	}
-	else
-	{
-		findTilesFromAabb(aabb, tileBeginX, tileBeginY, tileEndX, tileEndY);
-	}
+		// Find beginY
+		F32 y = box.getMin().y();
+		if(y <= info.m_xy.y())
+		{
+			beginY = 0;
+		}
+		else if(y >= (info.m_xy.y() + info.m_sizes.y() * m_counts[1]))
+		{
+			beginY = m_counts[1];
+		}
+		else
+		{
+			beginY = (y - info.m_xy.y()) / info.m_sizes.y();
+		}
+		ANKI_ASSERT(beginY >= 0 && beginY <= m_counts[1]);
 
 
-	U zFrom, zTo;
-	findSplitsFromAabb(aabb, zFrom, zTo);
+		// Find endY
+		y = box.getMax().y();
+		if(y <= info.m_xy.y())
+		{
+			endY = 0;
+		}
+		else if(y >= (info.m_xy.y() + info.m_sizes.y() * m_counts[1]))
+		{
+			endY = m_counts[1];
+		}
+		else
+		{
+			endY = ceil((y - info.m_xy.y()) / info.m_sizes.y());
+		}
+		ANKI_ASSERT(endY >= 0 && endY <= m_counts[1]);
 
 
-	// Detailed tests
-	for(U z = zFrom; z < zTo; ++z)
-	{
-		for(U y = tileBeginY; y < tileEndY; ++y)
+		for(I y = beginY; y < endY; ++y)
 		{
 		{
-			for(U x = tileBeginX; x < tileEndX; ++x)
+			for(I x = beginX; x < endX; ++x)
 			{
 			{
 				const Cluster& cl = cluster(x, y, z);
 				const Cluster& cl = cluster(x, y, z);
 				Aabb clusterAabb(cl.m_min.xyz0(), cl.m_max.xyz0());
 				Aabb clusterAabb(cl.m_min.xyz0(), cl.m_max.xyz0());
@@ -297,5 +236,13 @@ void Clusterer::binGeneric(const CollisionShape& cs,
 	}
 	}
 }
 }
 
 
+//==============================================================================
+void Clusterer::findSplitsFromAabb(const Aabb& box, U& zFrom, U& zTo) const
+{
+	zFrom = calcK(box.getMax().z());
+	zTo = calcK(box.getMin().z()) + 1;
+	ANKI_ASSERT(zFrom <= zTo);
+}
+
 } // end namespace anki
 } // end namespace anki
 
 

+ 8 - 7
testapp/Main.cpp

@@ -43,8 +43,8 @@ App* app;
 ModelNode* horse;
 ModelNode* horse;
 PerspectiveCamera* cam;
 PerspectiveCamera* cam;
 
 
-#define PLAYER 0
-#define MOUSE 0
+#define PLAYER 1
+#define MOUSE 1
 
 
 Bool profile = false;
 Bool profile = false;
 
 
@@ -80,21 +80,21 @@ Error init()
 		toRad(ang), 0.2, 200.0);
 		toRad(ang), 0.2, 200.0);
 	scene.setActiveCamera(cam);
 	scene.setActiveCamera(cam);
 
 
-	/*cam->getComponent<MoveComponent>().
+	cam->getComponent<MoveComponent>().
 		setLocalTransform(Transform(Vec4(0.0),
 		setLocalTransform(Transform(Vec4(0.0),
 		Mat3x4(Euler(toRad(0.0), toRad(180.0), toRad(0.0))),
 		Mat3x4(Euler(toRad(0.0), toRad(180.0), toRad(0.0))),
-		1.0));*/
+		1.0));
 
 
 #if !PLAYER
 #if !PLAYER
-	/*cam->getComponent<MoveComponent>().
+	cam->getComponent<MoveComponent>().
 		setLocalTransform(Transform(
 		setLocalTransform(Transform(
 		//Vec4(147.392776, -10.132728, 16.607138, 0.0),
 		//Vec4(147.392776, -10.132728, 16.607138, 0.0),
 		Vec4(0.0),
 		Vec4(0.0),
 		Mat3x4(Euler(toRad(0.0), toRad(90.0), toRad(0.0))),
 		Mat3x4(Euler(toRad(0.0), toRad(90.0), toRad(0.0))),
-		1.0));*/
+		1.0));
 #endif
 #endif
 
 
-#if 1
+#if 0
 	PointLight* plight;
 	PointLight* plight;
 	scene.newSceneNode<PointLight>("spot0", plight);
 	scene.newSceneNode<PointLight>("spot0", plight);
 
 
@@ -465,6 +465,7 @@ Error initSubsystems(int argc, char* argv[])
 	config.set("is.sm.maxLights", 16);
 	config.set("is.sm.maxLights", 16);
 	config.set("is.sm.poissonEnabled", true);
 	config.set("is.sm.poissonEnabled", true);
 	config.set("is.sm.resolution", 1024);
 	config.set("is.sm.resolution", 1024);
+	config.set("lf.maxFlares", 32);
 	config.set("pps.enabled", true);
 	config.set("pps.enabled", true);
 	config.set("pps.bloom.enabled", true);
 	config.set("pps.bloom.enabled", true);
 	config.set("pps.bloom.renderingQuality", 0.5);
 	config.set("pps.bloom.renderingQuality", 0.5);