Отрисовка сбоев с GL_DEPTH_TEST и прозрачными текстурами - PullRequest
3 голосов
/ 20 февраля 2012

С одного угла мои кусты выглядят так:

image

From the other, they look like this:

image

My theory is that when looking at the shrubs from the first angle, all the blocks behind the shrub have already been drawn, so when it comes to draw the shrub, it just draws them overtop.

From the other angle, however, it's basically trying to draw the shrub first, and then when it goes to draw the block behind the shrub, it checks the depth buffer and sees that there's something already blocking the view of the block, so it doesn't render it, causing the navy blue squares (my clear color).

I really have no idea how to fix this issue though. Disabling the depth test causes all kinds of other errors. Is there some way to flag the vertex or polygon as having transparency so that it knows it still needs to render what's behind?


Нашел это . Это единственное решение? Чтобы отделить мои прозрачные и непрозрачные блоки, а затем вручную отсортировать их на ЦП практически каждый кадр, потому что игрок может перемещаться? Должен быть способ передать это в GPU ...

Ответы [ 3 ]

9 голосов
/ 20 февраля 2012

Эта ссылка (и сортировка по процессору) предназначена для альфа-смешивания. Если вам нужно только альфа-тестирование (не смешивание), вам не нужно ничего сортировать. Просто включите альфа-тестирование, оставив тест на глубину включенным, и все будет в порядке.

Смотрите здесь: http://www.opengl.org/wiki/Transparency_Sorting Вам нужен «Альфа-тест», который требует альфа-тестирования, а не «Стандартный полупрозрачный», который требует сортировки.

3 голосов
/ 22 декабря 2013

Если вы используете WebGL или OpenGL ES 2.0 (iPhone / Android), альфа-тестирование не проводится. Вместо этого вам не нужно рисовать прозрачные пиксели. Таким образом, они не влияют на буфер глубины, так как ни один пиксель не был записан. Для этого вам нужно отбросить прозрачные пиксели в вашем фрагментном шейдере. Вы можете жестко закодировать это

...
void main() {
   vec4 color = texture2D(u_someSampler, v_someUVs);
   if (color.a == 0.0) {
     discard;
   }
   gl_FragColor = color;
}

или вы можете смоделировать альфа-тестирование старого стиля, где вы можете установить альфа-значение

...
uniform float u_alphaTest;
void main() {
   vec4 color = texture2D(u_someSampler, v_someUVs);
   if (color.a < u_alphaTest) {
     discard;
   }
   gl_FragColor = color;
}
3 голосов
/ 20 февраля 2012

Решение № 1:

  1. Отображать все непрозрачные объекты первыми в любом порядке, буфер глубины включен.Это включает в себя все объекты, которые используют альфа-тестирование без альфа-смешивания.
  2. Для glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) объектов (дым / стекло / трава): рендеринг прозрачной сцены из самого дальнего многоугольника в ближайший многоугольник с отключенной записью в буфер глубины (glDepthMask(GL_FALSE)).Если все прозрачные объекты являются выпуклыми и не пересекаются, вы можете сортировать объекты вместо полигонов.
  3. Для glBlendFunc(GL_SRC_ALPHA, GL_ONE) и glBlend(GL_ONE, GL_ONE) (огонь, «магические» системы частиц, свечение): визуализация прозрачной сцены в любомпорядок с записью в буфер глубины (glDepthMask(GL_FALSE)) отключен.
  4. Не визуализировать объекты с поддержкой буфера глубины после шага № 3.

Решение № 2:
Использовать пилинг по глубине (Google google it).Особенно, если прозрачные объекты пересекаются друг с другом.Не подходит для систем частиц и травы, для которых требуется решение № 1.


, а затем вручную сортировать их на ЦП практически каждый кадр

Вставка сортировкиотлично работает для уже отсортированных или частично отсортированных данных.

Должен быть способ делегировать это в графический процессор ...

Я думаю, вы можете генерировать полигоны травы(в правильном порядке) в геометрическом шейдере с использованием текстуры, имеющей канал (скажем, альфа), который маркирует области с травой и без нее.Требуется OpenGL 4, и вам, вероятно, придется выполнить какую-то высокоуровневую сортировку для полигонов, которые вы будете подавать в шейдер для создания участков травы.

Отдельные кусты можно вращать в вершинном шейдере (на + - 90/ 180/270 градусов) для поддержания правильного порядка многоугольников, если они абсолютно симметричны во всех направлениях.

И есть алгоритм сортировки слиянием, который хорошо распараллеливается и может быть выполнен на GPU, используя подход GDGPU или OpenCL / CUDA.

Однако использование чего-то подобного для рендеринга 5 кустов травы примерно эквивалентно попытке убить таракана с помощью гранатомета - забавная вещь, но не совсем эффективная.

Я предлагаю забыть о «разгрузке на GPU», пока вы действительно не столкнетесь с проблемой производительности.Используйте профилировщики и всегда измеряйте их перед оптимизацией, иначе вы потратите большое количество времени на разработку ненужных оптимизаций.

...