Как правильно реализовать альфа-смешивание в сложной 3D-сцене?

11

Я знаю, что на этот вопрос может показаться немного легко ответить, но это сводит меня с ума. Существует слишком много возможных ситуаций, с которыми должен справиться хороший механизм альфа-смешивания, и для каждого Алгоритма, который я могу придумать, чего-то не хватает.

Вот методы, о которых я пока говорю:

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

  • Затем я подумал о сортировке треугольников, но этот тоже может потерпеть неудачу, подумав, что я не уверен, как это реализовать. Существует редкий случай, который может снова вызвать проблему, при которой два треугольника проходят друг через друга. Опять же никто не может сказать, кто из них ближе.

  • Следующим шагом было использование буфера глубины, по крайней мере, главная причина, по которой у нас есть буфер глубины, из-за проблем с сортировкой, о которых я упоминал, но теперь у нас возникает другая проблема. Так как объекты могут быть прозрачными, в один пиксель там может быть больше , чем один объект видимым. Так для какого объекта я должен хранить глубину пикселя?

  • Затем я подумал, что, возможно, я смогу сохранить только наибольшую глубину переднего объекта, и с помощью этого определить, как я должен смешивать следующие вызовы отрисовки в этом пикселе. Но опять возникла проблема, подумайте о двух полупрозрачных плоскостях с твердой плоскостью в середине. Я собирался визуализировать сплошную плоскость в конце, можно увидеть самую дальнюю плоскость. Обратите внимание, что я собирался объединять каждые две плоскости, пока для этого пикселя не останется только один цвет. Очевидно, я тоже могу использовать методы сортировки по тем же причинам, которые я объяснил выше.

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

Ali1S232
источник

Ответы:

11

Короткий ответ

Посмотри в глубину пилинга . Из моих исследований это, кажется, лучшая альтернатива, хотя вычислительно дорогая, потому что она требует многократных проходов рендеринга. Вот еще одна более свежая и более быстрая реализация , в том числе NVIDIA.

Длинный ответ

Это сложный вопрос. Большинство книг, которые я прочитал, пролистывают тему и оставляют ее по адресу:

Начните с рендеринга всех непрозрачных объектов, а затем смешайте прозрачные объекты поверх них в обратном порядке.

Проще сказать, чем сделать, потому что очевидный подход сортировки объектов по центроидам не гарантирует правильного порядка сортировки.

Это та же самая проблема, почему алгоритм художника не работает в общем случае, и необходим буфер глубины .

С учетом сказанного, в одной из моих книг упоминается несколько решений:

  • Depth Peeling - многопроходное решение, которое преодолевает ограничение буфера глубины, давая нам n-й ближайший фрагмент, а не только самый близкий. Самым большим преимуществом является то, что вы можете визуализировать прозрачные объекты в любом порядке, и нет необходимости сортировать. Это может быть дорого из-за нескольких проходов, но ссылка, которую я дал наверху, кажется, улучшает производительность.

  • K-Buffer с трафаретной передачей - используйте трафаретную маршрутизацию для захвата нескольких слоев фрагментов на пиксель за проход геометрии. Основным недостатком является то, что фрагменты должны быть отсортированы на этапе последующей обработки.

В нем также упоминается аппаратное решение проблемы, но я не думаю, что оно действительно доступно:

  • F-Buffer - FIFO-буфер Rasterization-Order для многопроходного рендеринга. Тем не менее, хорошее чтение и введение также немного говорят о проблеме порядка сортировки прозрачности и текущих решениях.

Другие обходные пути, которые не дают отличных результатов, но лучше, чем ничего:

  • После рендеринга всех непрозрачных объектов продолжайте использовать тестирование Z-буфера для прозрачных объектов, но отключите запись в Z-буфер . Вы можете получить некоторые артефакты от неправильной сортировки, но по крайней мере все прозрачные объекты будут видны.

И процитировав технический документ по F-буферу выше:

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

Дэвид Гувея
источник
11

Правильный ответ # 1: сортируйте все ваши вещи по глубине и визуализируйте их (очевидно, отключите глубину записи, но не тестирование). Что такое "вещь"?

Каждая «вещь» должна быть выпуклым объектом; оно не может перекрывать друг друга. Если у вас есть вогнутый объект, он должен быть разбит на выпуклые части.

Это стандартный способ визуализации прозрачной сцены. Есть ли решить это взаимопроникающие случаи? Нет . Имеет ли это решить случаи , когда у вас есть 3 объекта , где нет порядка глубины не может быть определена? Нет. Решает ли это случаи, когда у вас есть длинный объект, который перекрывается с маленьким, который ближе по глубине к центру? Нет .

Но это работает достаточно хорошо . Игры не используют глубины пилинга. Они не используют трафарет маршрутизации K-буфера. Они не используют F-буфера. Почему? Потому что эти вещи невероятно медленно.

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

Если вы хотите ограничиться DX11 или более качественным оборудованием, есть способы реализовать смешивание с правильной сортировкой. Они медленнее, но не так медленно, как и предыдущие методы. И в отличие от глубины пилинга, который может ввести артефакты, это один образец с точностью. Кроме того, производительность алгоритма, как правило, зависит от фрагмента (и до некоторой степени за перекрытие внутри каждого фрагмента). Так что, если вы не сделать много прозрачного материала, производительность минимальна.

Я не знаю , если техника имеет элегантное имя, но одна реализации для предварительного GL4.2 можно найти здесь. Версия D3D11 можно найти здесь (Powerpoint, PPSX, Libre-совместимый).

Николь Болас
источник
Хорошие моменты в этом ответе. Я лично также рассчитаться с достаточно хорошим (который я описать на мой ответ, как обходной путь) , как большинство методов , которые я перечислил, вероятно , больше проблем , чем они стоят. Кроме того , интересная техника в конце концов, я не думаю , что он был включен в рендеринг в реальном времени , на который я исследовал мой ответ. Я полный нуб , когда дело доходит до черты уровня DX11.
Дэвид Гувейя
«одну реализацию для pre-GL4.2 можно найти здесь» 404
Йероен ван Ланген