Получение усеченной пирамиды камеры из комбинированной матрицы вида и проекции?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Получение усеченной пирамиды камеры из комбинированной матрицы вида и проекции?

Сообщение Anonymous »

Я пытаюсь получить усеченную пирамиду камеры для Frustum Culling из объединенной матрицы вида и проекции. Подход для этого уже был дан в ответах на этот вопрос, но мой код просто не будет правильно отбираться, когда я буду следовать данным ответам. Фактически, создается впечатление, что создается своего рода «обратная» усеченная пирамида — при перемещении камеры влево крайняя левая усеченная пирамида кажется перемещающейся вправо в сцене и т. д.
Однако кажется, что это работает идеально, если я только работаю с матрицей проекции (преобразуя каждую отдельную точку, которую я хочу проверить, с помощью модели просмотра * модели вместо просто модели). Я не хочу этого делать, так как дополнительное умножение матрицы для каждого объекта делает этот подход к пространству просмотра значительно медленнее - кажется, что это делает разницу между 60 и 120 кадрами в секунду в сцене с 15 000 объектами для отсеивания.
Это мой код проверки усеченной пирамиды и усеченной сферы:
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)) return false;
return true;
}

Я использую это следующим образом:
const auto frustum = frustumFromMatrix(projection_mat * view_mat);

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


Подробнее здесь: https://stackoverflow.com/questions/797 ... ion-matrix
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»