Точечные спрайты OpenGL с глубинным тестированием - проблема смешивания?

Я рисую точечные спрайты (используя OpenGL ES 2.0 на iOS) как штрихи для рисования пользователя. Я храню эти точки в объектах буфера вершин, так что мне нужно выполнить проверку глубины, чтобы спрайты отображались в правильном порядке, когда они отправляются на рисование.

Я вижу странный эффект при рендеринге этих штрихов рисования, как показано на следующем снимке экрана:

Проблема смешивания Point Sprite

Обратите внимание на цветную "рамку" по краю синего обводки, где он нарисован над зеленым. Пользователь нарисовал синий штрих после зеленого, но когда VBO перерисовываются, синий штрих рисуется первым. Когда дело доходит до рисования зеленого штриха, начинается тестирование глубины, и он видит, что он должен быть позади синего штриха, и это происходит с некоторым успехом. Мне кажется, это какая-то проблема смешивания или неправильный расчет цвета во фрагментном шейдере? Края всех штрихов должны быть прозрачными, однако при обработке этих фрагментов кажется, что фрагментный шейдер сочетает его с текстурой фона.

В моем приложении я создал рендер-буфер глубины и назвал glEnable(GL_DEPTH_TEST) с помощью glDepthFunc(GL_LEQUAL), Я экспериментировал с glDepthMask() но безрезультатно. Смешивание установлено на glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)и цвет точечного спрайта использует предварительно умноженные альфа-значения. Процедура рисования очень проста:

  • Привязать рендер к текстуре FBO.
  • Нарисуйте текстуру фона.
  • Нарисуйте точечные спрайты (из ряда VBO).
  • Нарисуйте текстуру этого FBO в основной кадровый буфер.
  • Представьте основной кадровый буфер.


РЕДАКТИРОВАТЬ

Вот некоторый код из процедуры рисования.

Настройка состояния до рисования:

glDisable(GL_DITHER);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

Процедура рисования:

[drawingView setFramebuffer:drawingView.scratchFramebuffer andClear:YES];
glUseProgram(programs[PROGRAM_TEXTURE]);
[self drawTexture:[self textureForBackgroundType:self.backgroundType]];

glUseProgram(programs[PROGRAM_POINT_SPRITE]);

// ...
// Draw all VBOs containing point sprite data
// ...

[drawingView setFramebuffer:drawingView.defaultFramebuffer andClear:YES];
glUseProgram(programs[PROGRAM_TEXTURE]);
[self drawTexture:drawingView.scratchTexture];

[drawingView presentFramebuffer:drawingView.defaultFramebuffer];

Спасибо за любую помощь.

1 ответ

Решение

Если вы хотите нарисовать непрозрачные геометрии, вы должны отсортировать их z-вперед. Это был единственный способ получить правильное смешивание в течение многих лет. В наши дни существуют некоторые алгоритмы прозрачности, независимой от порядка, например, Dual Depth Peeling, но они не применимы к iOS.

Другие вопросы по тегам