Оптимизация для дорогого фрагментного шейдера

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

Насколько я понимаю, я не могу использовать раннее тестирование глубины, потому что там значения глубины интерполируются между вершинами, а не поступают из фрагментного шейдера. Есть ли способ «подражать» этому поведению?

Что вы подразумеваете под «трассировкой лучей» здесь? Потому что в трассировке лучей нет «слоев»; есть только геометрия. Для каждого образца окончательного изображения вы трассируете луч и попадаете в любую геометрию, ближайшую к началу луча. Это проблема, которая решается сама собой, ничего с этим не делая.

Nicol Bolas 18.03.2022 16:30

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

Haukinger 18.03.2022 17:13

Почему 3D текстура? Разве SSBO или, если это недоступно, буферная текстура не имеют больше смысла, поскольку они могут использовать произвольные объемы памяти? Кроме того, есть ли что-то неправильное в использовании здесь буфера глубины?

Nicol Bolas 18.03.2022 17:16

Буфер глубины тоже был моей первой мыслью, но разве тест глубины не оценивается после рендеринга фрагмента?

Haukinger 18.03.2022 17:23

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

BDL 18.03.2022 17:31

@BDL: Это не сработает, поскольку полноэкранный четырехугольник, используемый для трассировки лучей, будет решать, будет ли записан фрагмент или нет. А discard почти всегда отключает ранние тесты фрагментов.

Nicol Bolas 18.03.2022 17:34
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
6
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Лучший способ решить эту проблему — не использовать слои. Вы используете слои только из-за ограничений использования 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вообще отключает раннее тестирование глубины на большинстве аппаратных средств, поскольку логика тестирования глубины обычно привязана к логике письмо глубины (это атомарное чтение/условное изменение/условная запись).

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