Привет, ребята! Подскажите пожалуйста, какой метод лучше использовать для отсечения невидимой геометрии?
Для начала хочется какой-то простой и эффективный алгоритм чтобы уже от него отталкиваться.
P.S: Знаю что в интернете полно статей на эту тему, но я хочу услышать ваше мнение, какой алгоритм
лучше реализовывать (особенно новичку в этой теме).
Сперва сделай обычное отсечение по фрустуму (Frustum culling), потом уже будешь думать над более продвинутыми вариантами.
Если дорастёшь до коммерческих решений, то вот: http://umbra3d.com/
zombihello
> (особенно новичку в этой теме).
Хотя бы предикаты
innuendo
> Хотя бы предикаты
кнута
MrShoor
> > Хотя бы предикаты
> кнута
Ты не знаешь что такое предикаты в графике ?
innuendo
> Ты не знаешь что такое предикаты в графике ?
Да, знаю. Вот и расскажи (но не мне, а топик стартеру).
Ребят, спасибо что откликнулись.
Решил я последовать совету ArchiDevil и сделать для начала Frustum culling, но с толкнулся с проблемой такой проблемой:
Как я понимаю где-то накосячил в вычислении Frustum'a (использую GLM)
вот код вычисления/обновления Frustum'a:
glm::mat4 ClippingPlane = glm::transpose(Projection * View ); // думаю что корень проблем здесь, // но я уже испробовал все комбинации ( Projection * View, glm::transpose( View * Projection ), View * Projection ) // Знаю что матрицы OpenGL отличаются от матриц GLM'a и потому применяю transpose, так как в примерах // исп. матрицы которые получали от OpenGL (например, урок от NeHe) PyramidFrustum[ Right ][ A ] = ClippingPlane[ 0 ].w - ClippingPlane[ 0 ].x; PyramidFrustum[ Right ][ B ] = ClippingPlane[ 1 ].w - ClippingPlane[ 1 ].x; PyramidFrustum[ Right ][ C ] = ClippingPlane[ 2 ].w - ClippingPlane[ 2 ].x; PyramidFrustum[ Right ][ D ] = ClippingPlane[ 3 ].w - ClippingPlane[ 3 ].x; NormalizePlane( Right ); PyramidFrustum[ Left ][ A ] = ClippingPlane[ 0 ].w + ClippingPlane[ 0 ].x; PyramidFrustum[ Left ][ B ] = ClippingPlane[ 1 ].w + ClippingPlane[ 1 ].x; PyramidFrustum[ Left ][ C ] = ClippingPlane[ 2 ].w + ClippingPlane[ 2 ].x; PyramidFrustum[ Left ][ D ] = ClippingPlane[ 3 ].w + ClippingPlane[ 3 ].x; NormalizePlane( Left ); PyramidFrustum[ Bottom ][ A ] = ClippingPlane[ 0 ].w + ClippingPlane[ 0 ].y; PyramidFrustum[ Bottom ][ B ] = ClippingPlane[ 1 ].w + ClippingPlane[ 1 ].y; PyramidFrustum[ Bottom ][ C ] = ClippingPlane[ 2 ].w + ClippingPlane[ 2 ].y; PyramidFrustum[ Bottom ][ D ] = ClippingPlane[ 3 ].w + ClippingPlane[ 3 ].y; NormalizePlane( Bottom ); PyramidFrustum[ Top ][ A ] = ClippingPlane[ 0 ].w - ClippingPlane[ 0 ].y; PyramidFrustum[ Top ][ B ] = ClippingPlane[ 1 ].w - ClippingPlane[ 1 ].y; PyramidFrustum[ Top ][ C ] = ClippingPlane[ 2 ].w - ClippingPlane[ 2 ].y; PyramidFrustum[ Top ][ D ] = ClippingPlane[ 3 ].w - ClippingPlane[ 3 ].y; NormalizePlane( Top ); PyramidFrustum[ Back ][ A ] = ClippingPlane[ 0 ].w - ClippingPlane[ 0 ].z; PyramidFrustum[ Back ][ B ] = ClippingPlane[ 1 ].w - ClippingPlane[ 1 ].z; PyramidFrustum[ Back ][ C ] = ClippingPlane[ 2 ].w - ClippingPlane[ 2 ].z; PyramidFrustum[ Back ][ D ] = ClippingPlane[ 3 ].w - ClippingPlane[ 3 ].z; NormalizePlane( Back ); PyramidFrustum[ Front ][ A ] = ClippingPlane[ 0 ].w + ClippingPlane[ 0 ].z; PyramidFrustum[ Front ][ B ] = ClippingPlane[ 1 ].w + ClippingPlane[ 1 ].z; PyramidFrustum[ Front ][ C ] = ClippingPlane[ 2 ].w + ClippingPlane[ 2 ].z; PyramidFrustum[ Front ][ D ] = ClippingPlane[ 3 ].w + ClippingPlane[ 3 ].z; NormalizePlane( Front );
вот код проверки на видимость (проверяемые координаты вершин в глобальных координатах)
glm::vec3* Vertexs = BoundingBox.GetVertexs(); for ( int Side = 0; Side < 6; Side++ ) { int IdVertex; for ( IdVertex = 0; IdVertex < 8; IdVertex++ ) { if ( PyramidFrustum[ Side ][ A ] * Vertexs[ IdVertex ].x + PyramidFrustum[ Side ][ B ] * Vertexs[ IdVertex ].y + PyramidFrustum[ Side ][ C ] * Vertexs[ IdVertex ].z + PyramidFrustum[ Side ][ D ] > 0 ) break; } if ( IdVertex == 8 ) return false; } return true;
Можете подсказать, может кто-то сталкивался с подобной проблемой.
zombihello
> исп. матрицы которые получали от OpenGL (например, урок от NeHe)
Тогда должно работать, cделай перемножение как в NeHe, без glm.
Andrey
> Тогда должно работать, cделай перемножение как в NeHe, без glm.
Не, не помогло, проблема осталась
делал так
const float* proj = glm::value_ptr(glm::transpose( Projection ) ); const float* modl = glm::value_ptr( glm::transpose( View ) ); // так же пробовал glm::value_ptr( Projection ), ну и менять их местами float clip[ 16 ]; clip[ 0 ] = modl[ 0 ] * proj[ 0 ] + modl[ 1 ].... // ну и дальше пошло перемножение и вычисление плоскостей как в nehe
Может это из-за того что матрицу проекции и вида я получаю с помощью glm? (glm::lookAt() , glm::perspective() )
zombihello
> Может это из-за того что матрицу проекции и вида я получаю с помощью glm?
> (glm::lookAt() , glm::perspective() )
может быть. Найди формулы для построения матриц, сравни c glm, я думаю отладчик тебя спасет, Стоит для начала найти рабочую реализацию матриц + frustum(этот код довольно стандартный и шаблонный), разобраться и потом адаптировать использую glm.
1001 тема почему у меня не работает frustum culling
innuendo
надо все константы загрузить за один вызов, тогда невидимая геометрия испугается и сама перестанет отсвечивать
g-cont
> тогда невидимая геометрия испугается и сама перестанет отсвечивать
регистры начинают путаться, да :)
Тема в архиве.