Поведение прозрачных текстур в WebGL - PullRequest
16 голосов
/ 06 января 2012

Среда: WebGL, Chrome. У меня следующее поведение при использовании прозрачных PNG в качестве текстур для моделей:

  1. Изображение A - дерево скрывает здание за ним, и я вижу текстуру мира. Также прячется (задние ветви не видны)
  2. В то же время - изображение B - работает нормально, окно прозрачное, и я вижу, что стоит за

A: Tree over house B: Window transparency

Оба снимка экрана были сделаны на одной и той же сцене в одно и то же время с разных позиций камеры. Текстуры производятся по тому же алгоритму.

Я не могу понять, в чем разница между прозрачностью окон и ветвей. Мой главный вопрос - как починить ветки, чтобы не скрывать объекты за ними? Код шейдера:

gl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a);

Я играл с включением / отключением смешивания и глубины_тестов, иногда получая желаемые результаты, но не уверен, что это правильный способ сделать что-либо.

Ответы [ 2 ]

30 голосов
/ 07 января 2012

У вас проблемы с буфером глубины, это никак не связано с вашими шейдерами или режимами наложения.

То, что происходит, заключается в том, что порядок, в котором вы визуализируете свою прозрачную геометрию, влияет на вашу способность рендеринга за ней. Это связано с тем, что буфер глубины не имеет понятия прозрачного или непрозрачного. В результате, даже если они не вносят визуальный вклад в сцену, эти прозрачные пиксели все равно записываются в буфер глубины, и после этого любые пиксели, которые вы рисуете за ними, будут отбрасываться, потому что они «не видны». Если вы сначала нарисуете геометрию позади прозрачного объекта, он будет отображаться правильно, потому что он записывается в кадр до того, как будет установлена ​​прозрачная глубина для его удаления.

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

Нет «идеального решения» этой проблемы, но то, к чему она действительно сводится, - это попытаться структурировать вашу сцену так:

  1. Визуализация любой непрозрачной геометрии, отсортированной по состоянию (шейдер / текстура / и т. Д.)
  2. Следующее отображение любой прозрачной геометрии. Если возможно, отсортируйте их по глубине, чтобы сначала вы нарисовали самый дальний из камеры.

Просто отметив биты геометрии, которые являются прозрачными, и отобразив их после всего остального, вы решите 90% этой проблемы, но проблема все еще может остаться для перекрывающихся прозрачных объектов. Это может быть не проблема для вас, в зависимости от вашей сцены, но если это все еще вызывает артефакты, вам нужно отсортировать прозрачные объекты по глубине, прежде чем рисовать.

4 голосов
/ 18 декабря 2015

Сброс фрагментов с альфа ниже, чем, например, 0,5 может помочь (конечно, есть побочный эффект).

if (gl_FragColor.a <0.5) сбросить; </p>

Альфа-функции в WebGL?

...