Browse Source

Creating a new projection matrix. Never seen that around. It is very accurate

Panagiotis Christopoulos Charitos 13 years ago
parent
commit
49d2fe62ef
3 changed files with 21 additions and 239 deletions
  1. 2 128
      src/collision/Frustum.cpp
  2. 4 4
      src/renderer/Dbg.cpp
  3. 15 107
      src/renderer/Is.cpp

+ 2 - 128
src/collision/Frustum.cpp

@@ -166,18 +166,14 @@ Mat4 PerspectiveFrustum::calculateProjectionMatrix() const
 {
 	ANKI_ASSERT(fovX != 0.0 && fovY != 0.0);
 	Mat4 projectionMat;
-#define METHOD 0
-
-#if METHOD == 0
-	F32 f = 1.0 / tan(fovY * 0.5); // f = cot(fovY/2)
 	F32 g = near - far;
 
-	projectionMat(0, 0) = f * (fovY / fovX); // = f/aspectRatio;
+	projectionMat(0, 0) = 1.0 / tanf(fovX * 0.5);
 	projectionMat(0, 1) = 0.0;
 	projectionMat(0, 2) = 0.0;
 	projectionMat(0, 3) = 0.0;
 	projectionMat(1, 0) = 0.0;
-	projectionMat(1, 1) = f;
+	projectionMat(1, 1) = 1.0 / tanf(fovY * 0.5);
 	projectionMat(1, 2) = 0.0;
 	projectionMat(1, 3) = 0.0;
 	projectionMat(2, 0) = 0.0;
@@ -188,128 +184,6 @@ Mat4 PerspectiveFrustum::calculateProjectionMatrix() const
 	projectionMat(3, 1) = 0.0;
 	projectionMat(3, 2) = -1.0;
 	projectionMat(3, 3) = 0.0;
-#elif METHOD == 1
-	F32 size = near * tanf(fovX / 2.0);
-	F32 a = fovX / fovY;
-	F32 left = -size, right = size, bottom = -size / a, top = size / a;
-
-	projectionMat(0, 0) = 2 * near / (right - left);
-	projectionMat(0, 1) = 0.0;
-	projectionMat(0, 2) = 0.0;
-	projectionMat(0, 3) = 0.0;
-	projectionMat(1, 0) = 0.0;
-	projectionMat(1, 1) = 2 * near / (top - bottom);
-	projectionMat(1, 2) = 0.0;
-	projectionMat(1, 3) = 0.0;
-	projectionMat(2, 0) = (right + left) / (right - left);
-	projectionMat(2, 1) = (top + bottom) / (top - bottom);
-	projectionMat(2, 2) = -(far + near) / (far - near);
-	projectionMat(2, 3) = -1;
-	projectionMat(3, 0) = 0.0;
-	projectionMat(3, 1) = 0.0;
-	projectionMat(3, 2) = -(2 * far * near) / (far - near);
-	projectionMat(3, 3) = 0.0;
-#elif METHOD == 2
-	F32 e = 1.0 / tanf(fovX / 2.0);
-	F32 a = fovY / fovX;
-
-	projectionMat(0, 0) = e;
-	projectionMat(0, 1) = 0.0;
-	projectionMat(0, 2) = 0.0;
-	projectionMat(0, 3) = 0.0;
-	projectionMat(1, 0) = 0.0;
-	projectionMat(1, 1) = e / a;
-	projectionMat(1, 2) = 0.0;
-	projectionMat(1, 3) = 0.0;
-	projectionMat(2, 0) = 0.0;
-	projectionMat(2, 1) = 0.0;
-	projectionMat(2, 2) = -(far + near) / (far - near);
-	projectionMat(2, 3) = (2.0 * far * near) / (near - far);
-	projectionMat(3, 0) = 0.0;
-	projectionMat(3, 1) = 0.0;
-	projectionMat(3, 2) = -1.0;
-	projectionMat(3, 3) = 0.0;
-#elif METHOD == 3
-	F32 s = 1.0 / tan(fovY * 0.5); // f = cot(fovY/2)
-	F32 g = near - far;
-
-	projectionMat(0, 0) = f * (fovY / fovX); // = f/aspectRatio;
-	projectionMat(0, 1) = 0.0;
-	projectionMat(0, 2) = 0.0;
-	projectionMat(0, 3) = 0.0;
-	projectionMat(1, 0) = 0.0;
-	projectionMat(1, 1) = f;
-	projectionMat(1, 2) = 0.0;
-	projectionMat(1, 3) = 0.0;
-	projectionMat(2, 0) = 0.0;
-	projectionMat(2, 1) = 0.0;
-	projectionMat(2, 2) = (far + near) / g;
-	projectionMat(2, 3) = -(far * near) / g;
-	projectionMat(3, 0) = 0.0;
-	projectionMat(3, 1) = 0.0;
-	projectionMat(3, 2) = 1.0;
-	projectionMat(3, 3) = 0.0;
-#elif METHOD == 4
-	F32 s = 1.0 / tan(fovY * 0.5);
-
-	projectionMat(0, 0) = s;
-	projectionMat(0, 1) = 0.0;
-	projectionMat(0, 2) = 0.0;
-	projectionMat(0, 3) = 0.0;
-	projectionMat(1, 0) = 0.0;
-	projectionMat(1, 1) = s;
-	projectionMat(1, 2) = 0.0;
-	projectionMat(1, 3) = 0.0;
-	projectionMat(2, 0) = 0.0;
-	projectionMat(2, 1) = 0.0;
-	projectionMat(2, 2) = -far / (far - near);
-	projectionMat(2, 3) = -1;
-	projectionMat(3, 0) = 0.0;
-	projectionMat(3, 1) = 0.0;
-	projectionMat(3, 2) = - far * near / (far - near);
-	projectionMat(3, 3) = 0.0;
-#elif METHOD == 5
-	float xymax = near * tan(fovY);
-	float ymin = -xymax;
-	float xmin = -xymax;
-
-	float width = xymax - xmin;
-	float height = xymax - ymin;
-
-	float depth = far - near;
-	float q = -(far + near) / depth;
-	float qn = -2 * (far * near) / depth;
-
-	float w = 2 * near / width;
-	float aspect  = fovY / fovX;
-	w = w / aspect;
-	float h = 2 * znear / height;
-
-	Mat4 m;
-
-	m[0]  = w;
-	m[1]  = 0;
-	m[2]  = 0;
-	m[3]  = 0;
-
-	m[4]  = 0;
-	m[5]  = h;
-	m[6]  = 0;
-	m[7]  = 0;
-
-	m[8]  = 0;
-	m[9]  = 0;
-	m[10] = q;
-	m[11] = -1;
-
-	m[12] = 0;
-	m[13] = 0;
-	m[14] = qn;
-	m[15] = 0;
-
-	projectionMat = m;
-	// XXX Transpose???
-#endif
 
 	return projectionMat;
 }

+ 4 - 4
src/renderer/Dbg.cpp

@@ -123,17 +123,17 @@ void Dbg::run()
 	fr.accept(cdd);
 	}
 
-	for(U j = 0; j < 1; j++)
+	for(U j = 0; j < 16; j++)
 	{
-		for(U i = 0; i < 16; i++)
+		for(U i = 0; i < 1; i++)
 		{
 			Is::Tile& tile = r->getIs().tiles[j][i];
 
 			Mat4 vmat = scene.getActiveCamera().getViewMatrix();
 
 			CollisionDebugDrawer cdd(drawer.get());
-			tile.planes[Frustum::FP_LEFT].accept(cdd);
-			tile.planes[Frustum::FP_RIGHT].accept(cdd);
+			//tile.planes[Frustum::FP_LEFT].accept(cdd);
+			//tile.planes[Frustum::FP_RIGHT].accept(cdd);
 			//tile.planes[Frustum::FP_BOTTOM].accept(cdd);
 			//tile.planes[Frustum::FP_TOP].accept(cdd);
 		}

+ 15 - 107
src/renderer/Is.cpp

@@ -201,9 +201,9 @@ Bool Is::cullLight(const PointLight& plight, const Tile& tile)
 	Camera& cam = r->getScene().getActiveCamera();
 	Sphere sphere = plight.getSphere();
 
-	return cam.getFrustumable()->getFrustum().insideFrustum(sphere);
+	//return cam.getFrustumable()->getFrustum().insideFrustum(sphere);
 
-#if 0
+#if 1
 	sphere.transform(Transform(cam.getViewMatrix()));
 
 	for(const Plane& plane : tile.planes)
@@ -231,19 +231,10 @@ void Is::updateAllTilesPlanes(const PerspectiveCamera& cam)
 	F32 fy = cam.getFovY();
 	F32 n = cam.getNear();
 
-#if 0
-	// Opts
-	F32 piAddfovXDiv2 = Math::PI + fovX / 2.0;
-	F32 piAddFovYDiv2 = (Math::PI + fovY) * 0.5;
-
-	// This is X the angle of the tile frustums
-	F32 fovXFragment = fovX / TILES_X_COUNT;
-	// See above
-	F32 fovYFragment = fovY / TILES_Y_COUNT;
-#endif
-
 	F32 l = 2.0 * n * tan(fx / 2.0);
 	F32 l6 = l / TILES_X_COUNT;
+	F32 o = 2.0 * n * tan(fy / 2.0);
+	F32 o6 = o / TILES_Y_COUNT;
 
 	for(U j = 0; j < TILES_Y_COUNT; j++)
 	{
@@ -266,102 +257,19 @@ void Is::updateAllTilesPlanes(const PerspectiveCamera& cam)
 
 			planes[Frustum::FP_RIGHT] = Plane(b, 0.0);
 
-#if 0
-			F32 c, s; // cos & sin
-
-			// Calc planes for one of those tiles:
-			// +-+-+-+-+
-			// | | | | |
-			// +-+-+-+-+
-			// | | | | |
-			// +-+-+-+-+
-			// |x|x| | |
-			// +-+-+-+-+
-			// |x|x| | |
-			// +-+-+-+-+
-			Array<Plane, Frustum::FP_COUNT>& planes = tiles[j][i].planes;
-			
-			// right
-			Math::sinCos(piAddfovXDiv2 - (TILES_X_COUNT - i - 1) * fovXFragment, s, c);
-			planes[Frustum::FP_RIGHT] = Plane(Vec3(c, 0.0, s), 0.0);
-			// left
-			Math::sinCos(-fovX / 2.0 + i * fovXFragment, s, c);
-			planes[Frustum::FP_LEFT] = Plane(Vec3(c, 0.0, s), 0.0);
+			// bottom
+			a = Vec3(0.0, (I(j) - I(TILES_Y_COUNT) / 2) * o6, -n);
+			b = Vec3(1.0, 0.0, 0.0).cross(a);
+			b.normalize();
+
+			planes[Frustum::FP_BOTTOM] = Plane(b, 0.0);
 
 			// bottom
-			Math::sinCos(piAddFovYDiv2 - j * fovYFragment, s, c);
-			planes[Frustum::FP_BOTTOM] = Plane(Vec3(0.0, s, c), 0.0);
-			// top
-			Math::sinCos((3.0 * Math::PI - fovY) / 2 + (TILES_Y_COUNT - j - 1) * fovYFragment, s, c);
-			planes[Frustum::FP_TOP] = Plane(Vec3(0.0, s, c), 0.0);
-
-			continue;
-
-			// Mirror planes for those tiles:
-			// +-+-+-+-+
-			// | | | | |
-			// +-+-+-+-+
-			// | | | | |
-			// +-+-+-+-+
-			// | | |x|x|
-			// +-+-+-+-+
-			// | | |x|x|
-			// +-+-+-+-+
-			Array<Plane, 6>& planes2 = tiles[j][TILES_X_COUNT - i - 1].planes;
-
-			planes2[Frustum::FP_RIGHT] = planes[Frustum::FP_LEFT];
-			planes2[Frustum::FP_RIGHT].getNormal().x() = 
-				-planes2[Frustum::FP_RIGHT].getNormal().x();
-
-			planes2[Frustum::FP_LEFT] = planes[Frustum::FP_RIGHT];
-			planes2[Frustum::FP_LEFT].getNormal().x() = 
-				-planes2[Frustum::FP_LEFT].getNormal().x();
-
-			planes2[Frustum::FP_BOTTOM] = planes[Frustum::FP_BOTTOM];
-			planes2[Frustum::FP_TOP] = planes[Frustum::FP_TOP];
-
-			// Mirror planes for those tiles:
-			// +-+-+-+-+
-			// |x|x| | |
-			// +-+-+-+-+
-			// |x|x| | |
-			// +-+-+-+-+
-			// | | | | |
-			// +-+-+-+-+
-			// | | | | |
-			// +-+-+-+-+
-			Array<Plane, 6>& planes3 = tiles[TILES_Y_COUNT - j - 1][i].planes;
-
-			planes3[Frustum::FP_RIGHT] = planes[Frustum::FP_RIGHT];
-			planes3[Frustum::FP_LEFT] = planes[Frustum::FP_RIGHT];
-
-			planes3[Frustum::FP_BOTTOM] = planes[Frustum::FP_TOP];
-			planes3[Frustum::FP_BOTTOM].getNormal().y() = 
-				-planes3[Frustum::FP_BOTTOM].getNormal().y();
-
-			planes3[Frustum::FP_TOP] = planes[Frustum::FP_BOTTOM];
-			planes3[Frustum::FP_TOP].getNormal().y() = 
-				-planes3[Frustum::FP_TOP].getNormal().y();
-
-			// Mirror planes for those tiles:
-			// +-+-+-+-+
-			// | | |x|x|
-			// +-+-+-+-+
-			// | | |x|x|
-			// +-+-+-+-+
-			// | | | | |
-			// +-+-+-+-+
-			// | | | | |
-			// +-+-+-+-+
-			Array<Plane, 6>& planes4 = 
-				tiles[TILES_Y_COUNT - j - 1][TILES_X_COUNT - i - 1].planes;
-
-			planes4[Frustum::FP_RIGHT] = planes2[Frustum::FP_RIGHT];
-			planes4[Frustum::FP_LEFT] = planes2[Frustum::FP_RIGHT];
-
-			planes4[Frustum::FP_BOTTOM] = planes3[Frustum::FP_BOTTOM];
-			planes4[Frustum::FP_TOP] = planes3[Frustum::FP_TOP];
-#endif
+			a = Vec3(0.0, (I(j) - I(TILES_Y_COUNT) / 2 + 1) * o6, -n);
+			b = a.cross(Vec3(1.0, 0.0, 0.0));
+			b.normalize();
+
+			planes[Frustum::FP_TOP] = Plane(b, 0.0);
 		}
 	}
 }