Einen Kamerastumpf aus einer kombinierten Ansichts- und Projektionsmatrix ableiten? [geschlossen]C++

Programme in C++. Entwicklerforum
Anonymous
 Einen Kamerastumpf aus einer kombinierten Ansichts- und Projektionsmatrix ableiten? [geschlossen]

Post by Anonymous »

Ich versuche, aus der kombinierten Ansichts- und Projektionsmatrix einen Kamerakegel für Frustum Culling abzuleiten. Ein Ansatz hierfür wurde bereits in den Antworten auf diese Frage angegeben, aber mein Code wird einfach nicht richtig ausgewählt, wenn ich den gegebenen Antworten folge. Tatsächlich scheint es eine Art „Rückwärts“-Kegelstumpf zu erzeugen – wenn man die Kamera nach links bewegt, scheint sich der Kegelstumpf ganz links in der Szene nach rechts zu bewegen und so weiter.
Es scheint jedoch perfekt zu funktionieren, wenn ich nur mit der Projektionsmatrix arbeite (und dabei jeden einzelnen Punkt, den ich testen möchte, durch Ansicht * Modell statt nur durch Modell transformiere). Ich möchte dies nicht tun, da die Eine zusätzliche Matrixmultiplikation pro Objekt macht diesen View-Space-Ansatz deutlich langsamer – es scheint den Unterschied zwischen 60 und 120 FPS in einer Szene mit 15.000 Objekten auszumachen.
Dies ist mein Code zur Kegelstumpf- und Kegelstumpfkugelprüfung:

Code: Select all

using Plane = glm::vec4;
using Frustum = std::array;

/// Generate a camera frustum from a projection-view matrix.
inline Frustum frustumFromMatrix(const glm::mat4& matrix)
{
Frustum frustum{};
frustum[0].x = matrix[0][3] + matrix[0][0];
frustum[0].y = matrix[1][3] + matrix[1][0];
frustum[0].z = matrix[2][3] + matrix[2][0];
frustum[0].w = matrix[3][3] + matrix[3][0];

frustum[1].x = matrix[0][3] - matrix[0][0];
frustum[1].y = matrix[1][3] - matrix[1][0];
frustum[1].z = matrix[2][3] - matrix[2][0];
frustum[1].w = matrix[3][3] - matrix[3][0];

frustum[2].x = matrix[0][3] - matrix[0][1];
frustum[2].y = matrix[1][3] - matrix[1][1];
frustum[2].z = matrix[2][3] - matrix[2][1];
frustum[2].w = matrix[3][3] - matrix[3][1];

frustum[3].x = matrix[0][3] + matrix[0][1];
frustum[3].y = matrix[1][3] + matrix[1][1];
frustum[3].z = matrix[2][3] + matrix[2][1];
frustum[3].w = matrix[3][3] + matrix[3][1];

frustum[4].x = matrix[0][3] + matrix[0][2];
frustum[4].y = matrix[1][3] + matrix[1][2];
frustum[4].z = matrix[2][3] + matrix[2][2];
frustum[4].w = matrix[3][3] + matrix[3][2];

frustum[5].x = matrix[0][3] - matrix[0][2];
frustum[5].y = matrix[1][3] - matrix[1][2];
frustum[5].z = matrix[2][3] - matrix[2][2];
frustum[5].w = matrix[3][3] - matrix[3][2];

return frustum;
}

inline bool sphereInHalfSpace(const glm::vec3 point, const float radius, const Plane plane)
{
return glm::dot(glm::vec3(plane), point) - plane.w > -radius;
}

inline bool sphereInFrustum(const glm::vec3 point, const float radius, const Frustum& frustum)
{
for (int i = 0; i < 6; i++)
if (!sphereInHalfSpace(point, radius, frustum[i])) return false;
return true;
}
Ich verwende es so:

Code: Select all

const auto frustum = frustumFromMatrix(projection_mat * view_mat);

for (int i = 0; i < count; i++) {
const auto radius = models[i].radius;
const auto pos = model_transforms[i] * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
if (!sphereInFrustum(pos, radius, frustum)) {
excludeFromDrawing(i);
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post