Я визуализирую несколько слоев плоских треугольников с помощью трассировщика лучей во фрагментном шейдере. Верхние слои имеют отверстия, и я ищу способ, как мне избежать запуска шейдера для пикселей, которые уже заполнены одним из верхних слоев, т.е. я хочу, чтобы отрисовывались только те части нижних слоев, которые лежат в отверстиях в верхних слоях. Конечно, есть дыра или нет, неизвестно, если только фрагментный шейдер не сделал свое дело для слоя.
Насколько я понимаю, я не могу использовать раннее тестирование глубины, потому что там значения глубины интерполируются между вершинами, а не поступают из фрагментного шейдера. Есть ли способ «подражать» этому поведению?
Я делаю трассировку лучей в изометрическом мире, разделенном на 3D-текстуры. Мне нужно больше высоты, чем может обеспечить одна текстура, поэтому я визуализирую несколько слоев, каждый со своим набором текстур. Если пиксель заполнен верхним слоем, я не хочу трассировать его в нижних слоях (снова и снова), просто чтобы узнать, что я могу отбросить результаты, потому что он все равно скрыт верхним слоем.
Почему 3D текстура? Разве SSBO или, если это недоступно, буферная текстура не имеют больше смысла, поскольку они могут использовать произвольные объемы памяти? Кроме того, есть ли что-то неправильное в использовании здесь буфера глубины?
Буфер глубины тоже был моей первой мыслью, но разве тест глубины не оценивается после рендеринга фрагмента?
Использовать трафаретный буфер и отмечать каждый фрагмент, в который вы уже вписали? Вам нужно настроить значения глубины во фрагментном шейдере?
@BDL: Это не сработает, поскольку полноэкранный четырехугольник, используемый для трассировки лучей, будет решать, будет ли записан фрагмент или нет. А discard
почти всегда отключает ранние тесты фрагментов.
Лучший способ решить эту проблему — не использовать слои. Вы используете слои только из-за ограничений использования 3D-текстуры для хранения данных вашей сцены. Так что... не делай этого.
SSBO и буферные текстуры (если ваше оборудование слишком старое для SSBO) могут получить доступ к большему объему памяти, чем 3D-текстура. И вы могли бы даже использовать ручную очистку данных улучшить локальность кеша, если это возможно.
As far as I understand, I cannot use early depth testing because there, the depth values are interpolated between the vertices and do not come from the fragment shader.
Это верно, поскольку вы не можете использовать ранние тесты глубины, но неверно в отношении Зачем.
«Глубина», предоставляемая VS, не обязательно должна быть глубиной фактического фрагмента. Вы визуализируете свою сцену слоями, предположительно, каждый слой представляет собой полноэкранный четырехугольник. По определению, все на одном уровне рендеринга ниже всего на более низком уровне. Таким образом, абсолютное значение глубины не имеет значения; важно, есть ли что-нибудь от более высокого уровня над этим фрагментом.
Таким образом, каждый слой может получить свое собственное значение глубины, а нижние слои получат более низкое значение глубины. Точное значение произвольно и не имеет значения; важно то, что более высокие уровни имеют более высокие значения.
Причина, по которой это не работает, заключается в следующем: если ваш алгоритм трассировки лучей обнаруживает промах внутри слоя («дыру»), вы должны discard
этот фрагмент. А использование discard
вообще отключает раннее тестирование глубины на большинстве аппаратных средств, поскольку логика тестирования глубины обычно привязана к логике письмо глубины (это атомарное чтение/условное изменение/условная запись).
Что вы подразумеваете под «трассировкой лучей» здесь? Потому что в трассировке лучей нет «слоев»; есть только геометрия. Для каждого образца окончательного изображения вы трассируете луч и попадаете в любую геометрию, ближайшую к началу луча. Это проблема, которая решается сама собой, ничего с этим не делая.