2012-03-10 4 views
2

Итак, я пытаюсь найти лучший способ визуализации 3D-модели в OpenGL, когда некоторые текстуры, применяемые к ней, имеют альфа-каналы.Рендеринг 3D-моделей с текстурами, которые имеют альфа в OpenGL

Когда у меня включен буфер глубины и начните рисовать все треугольники в 3D-модели, если он рисует треугольник, который находится перед другим треугольником в модели, он просто не будет отображать задний треугольник, когда он будет к нему. Проблема заключается в том, что передний треугольник имеет альфа-прозрачность и должен быть доступен для наблюдения за треугольником позади него, но треугольник позади все еще не отображается.

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

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

Depth Buffer Enabled

Вы можете увидеть, как вы можете видеть схему прозрачных треугольников.

На следующем рисунке показано, как выглядит буфер буферизации.

Depth Buffer Disabled

Здесь вы можете увидеть, как некоторые из треугольников на обратной стороне дерева, оказываемые в передней части остальной части дерева.

Любые идеи, как решить эту проблему, и правильно отремонтировать сосну?

P.S. Я использую шейдеры для визуализации всего.

ответ

5

Если вы не используете частичную прозрачность (все либо 0 или 255), вы можете glEnable (GL_ALPHA_TEST) , и это должно вам помочь. Проблема состоит в том, что если вы сначала визуализируете верхний конус, он откладывает весь квад в z-буфер (даже прозрачные части), поэтому нижние ветви снизу получают z-отклонение, когда их время нарисовано. Включение альфа-тестирования не записывает пиксели в буфер z, если они не выдают альфа-тест (установлен с glAlphaFunc) .

Если вы хотите использовать частичную прозрачность, вам нужно будет отсортировать порядок объектов рендеринга от начала до конца или снизу вверх в вашем случае.

Вам также нужно оставить включенным z-буфер.

[edit] Огонь Я понял, что те функции, которые я не верю, работают, когда вы используете шейдеры. В случае шейдера вы хотите использовать функцию отбрасывания в шейдере фрагмента, если альфа-значение близко к нулю.

if(color.a < 0.01) { 
    discard; 
} else { 
    outcolor = color; 
} 
+3

... или используйте «discard» в вашем шейдере фрагмента, если альфа находится ниже вашего порогового значения в любой среде без поддержки альфа-теста (например, ES 2.0 или WebGL). – Tommy

+1

Они работают, когда у вас есть шейдеры (в настольном OpenGL). Что не работает, это альфа-тест, когда вы используете [core OpenGL 3.1 или выше] (http://www.opengl.org/wiki/Core_And_Compatibility_in_Contexts). –

+0

@Tim Итак, я пробовал использовать discard, и он, кажется, удаляет любое изменение цвета, выполняемое шейдером фрагмента. Однако, похоже, он вообще не влияет на буфер глубины. При использовании сброса я получаю те же результаты, что и на картинке, где включен буфер глубины. – Jeremy

-2

Я могу ошибаться, но это не потому, что когда вы предоставляете в 3D вы не делаете тыльные треугольники, используя настройку DiRectX по умолчанию, когда Z удаляются - он рисует их в порядке, с Z на он больше не рисует заднюю сторону треугольников. Можно показать обе стороны треугольника, даже с включенным Z, однако я думаю, что может быть причина, по которой его обычно разрешено .. например, скорость ..

Device->SetRenderState(D3DRS_CULLMODE, Value); 

значение может равняться

D3DCULL_NONE - Shows both sides of triangle 
D3DCULL_CW - Culls Front side of triangle 
D3DCULL_CCW - Default state 
0

Вы необходимо реализовать алгоритм два прохода.

Первый проход отображает только задние лица, а второй проход - только передние.

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