3d окклюзия выбраковка - PullRequest
       114

3d окклюзия выбраковка

6 голосов
/ 14 февраля 2011

Я пишу для Minecraft как статический трехмерный мир блоков на C ++ / openGL. Я работаю над улучшением частоты кадров, и до сих пор я реализовал выборку усеченного конуса с использованием октодерева. Это помогает, но я все еще вижу частоту кадров от умеренной до плохой. Следующим шагом будет отбраковка кубов, которые скрыты от точки обзора более близкими кубами. Однако я не смог найти много ресурсов о том, как этого добиться.

Ответы [ 5 ]

8 голосов
/ 14 февраля 2011

Создание цели рендеринга с включенным Z-буфером (или «буфером глубины»).Затем убедитесь, что все непрозрачные объекты отсортированы так, что они отображаются спереди назад, то есть те, которые ближе всего расположены к камере.Все, что использует альфа-смешение, все еще нужно рендерить обратно на фронт, ПОСЛЕ того, как вы рендерили все ваши непрозрачные объекты.

Другой метод - это выборка окклюзии: вы можете дешево «высушить» вашу геометрию, а затем узнать, сколько пикселейпровалил тест глубины.Существует поддержка запросов окклюзии в DirectX и OpenGL, хотя не каждый GPU может это сделать.

Недостатком является то, что вам нужна задержка между рендерингом и извлечением результата - в зависимости от настройки (например, при использовании предикатного тайлинга).), это может быть полный кадр.Это означает, что вам нужно проявить творческий подход, например визуализировать ограничивающий прямоугольник, который больше самого объекта, и отклонить результаты после снятия камеры.

И еще одна вещь: более традиционное решение (то, что выможет использоваться одновременно с отбраковкой окклюзии) - это система комнат / порталов, где вы определяете регионы как "комнаты", связанные через "порталы".Если портал не виден из вашей текущей комнаты, вы не сможете увидеть подключенную к нему комнату.И даже в этом случае вы можете щелкнуть окно просмотра, чтобы увидеть то, что видно через портал.

5 голосов
/ 15 февраля 2011

Подход, который я использовал в , этот рендерер уровня Minecraft , по сути, заполнен наводнением с ограниченным усечением. Части 16x16x128 разделены на части 16x16x16, каждый с VBO с соответствующей геометрией. Я начинаю заливку в сетке чанклетов на месте игрока, чтобы найти чанкеты для рендеринга. Заполнение ограничено:

  1. Вид усеченного
  2. Сплошные чанклеты - если вся сторона чанклета является непрозрачными блоками, то заливка не попадет в чанлет в этом направлении
  3. Направление - поток не изменит направление, например: если текущий чанклет находится к северу от исходного чаклета, не заливайте его в юг

Кажется, все в порядке. Я нахожусь на андроиде, поэтому, хотя более сложный анализ (антипорталы, как отметил Майк Дэниелс) отбросил бы больше геометрии, я уже ограничен в ЦП, так что нет особого смысла.

Я только что видел ваш ответ Алану: отбраковка - это не ваша проблема, а то, что и как вы отправляете в OpenGL, это медленно.

Что рисовать: не визуализируйте куб для каждого блока, визуализируйте грани прозрачных блоков, которые граничат с непрозрачным блоком. Рассмотрим куб 3x3x3, скажем, из каменных блоков: нет смысла рисовать центральный блок, потому что игрок не может его увидеть. Кроме того, игрок никогда не увидит грани между двумя соседними каменными блоками, поэтому не рисуйте их.

Как рисовать: Как заметил Алан, используйте VBO для пакетной геометрии. Вы не поверите, насколько быстрее они делают вещи.

Более простой подход с минимальными изменениями в существующем коде заключается в использовании списков отображения . Это то, что использует Minecraft.

4 голосов
/ 15 февраля 2011

Сколько блоков вы рендеринга и на каком оборудовании?Современное аппаратное обеспечение очень быстрое и его очень сложно переполнить геометрией (если мы не говорим о портативной платформе).На любом умеренно новом настольном оборудовании вы должны иметь возможность рендерить сотни тысяч кубов в кадре со скоростью 60 кадров в секунду без каких-либо хитростей./ Arrays, glBegin / glEnd и т. Д.) (Бонусные баллы: не используйте glBegin / glEnd), тогда это будет вашим узким местом.Это распространенная ошибка для начинающих.Если вы делаете это, то вам нужно объединить все треугольники, которые совместно используют параметры текстуры и затенения, в один вызов для каждой настройки.Если геометрия статична и не меняет кадр за кадром, вы хотите использовать один объект буфера вершин для каждой партии треугольников.

Это все еще можно комбинировать с отбраковкой усеченного конуса с помощьюoctree, если у вас обычно только небольшая часть вашего игрового мира в окне просмотра одновременно.Буферы вершин по-прежнему загружаются статически и не изменяются.Frustum отбирает октре, чтобы генерировать только индексные буферы для треугольников в усеченной области, и загружать их динамически в каждом кадре.

3 голосов
/ 14 февраля 2011

Если у вас есть поверхности, близкие к камере, вы можете создать усеченную область, представляющую невидимую область, и отбросить объекты, которые полностью содержатся в этой усеченной области. На приведенной ниже схеме C - это камера, | - плоская поверхность около камеры, а область в форме усеченного конуса, состоящая из ., представляет собой окклюзированную область. Поверхность называется антипортал .

        .
       ..
      ...
     ....
    |....
    |....
    |....
    |....
C   |....
    |....
    |....
    |....
     ....
      ...
       ..
        .

(Конечно, вы также должны включить глубинное тестирование и глубинную запись, как упоминалось в других ответах и ​​комментариях - это очень просто сделать в OpenGL.)

0 голосов
/ 16 февраля 2011

Использование Z-буфера обеспечивает правильное перекрытие полигонов.

Включение проверки глубины заставляет каждую операцию рисования проверять Z-буфер перед размещением пикселей на экране.

Если у вас выпуклые объекты, вы должны (для производительности) включить отбраковку задней поверхности!

Пример кода:

glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE);

Вы можете изменить поведение glCullFace (), передавая GL_FRONT или GL_BACK ...

glCullFace(...);

// Рисуем "игровой мир" ...

...