Что такое производные пространства экрана и когда я буду их использовать?

12

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

Итак вопросы:

  1. Каковы функции производных экранного пространства?
  2. Что делают эти функции? Входные значения и выходные значения
  3. Для каких эффектов они чаще всего используются?
  4. Какие эффекты требуют, чтобы вы смотрели на эти функции?
NeomerArcana
источник
В прошлом я использовал их для деформации текстуры, где деформация может привести к тому, что для некоторых фрагментов будет выбран неправильный уровень; как правило, ниже среднего уровня, так что вы можете увидеть текстуру очень заметно смещается в деталях, когда она деформируется. Возьмем производные от деформированных текстовых кордов, затем вычислим деформацию, затем используем tex2Dgrad / SampleGrad / textureGrad с деформированными текстовыми связями и производными, чтобы предотвратить это.
Максимус Минимус
@ LeComteduMerde-fou, что такое перекосы текстуры? Быстрый Google предлагает вам иметь в виду обертку?
NeomerArcana
Нет, я имею в виду деформации , то есть искажение текстуры путем изменения координат текстуры с течением времени.
Максимус Минимус
Смотрите этот связанный вопрос . Я не думаю, что это довольно дубликат, так как связанный вопрос спрашивает больше о том, как эти функции работают / как они рассчитываются, вместо более высокого уровня «что это такое и для чего это хорошо?»
DMGregory
Здравствуйте, я очень заинтересован в этом, я в настоящее время использую их, чтобы сделать рельефное отображение без касательной или битангентной, но я в основном скопировал код. ... Я думал об использовании этого для этого ... но я не знаю, как преобразовать эти производные экранного пространства в нормали мирового пространства, используя некоторую дешевую линейную алгебру. Возможно, мне нужна обратная матрица проецирования камеры.
Прокоп Хапала

Ответы:

12

Во-первых, полезно знать, что графические процессоры всегда оценивают фрагментные / пиксельные шейдеры по 2x2 блокам пикселей одновременно. (Даже если в конечном итоге необходимо нарисовать только некоторые из этих пикселей, в то время как другие находятся за пределами многоугольника или перекрыты - ненужные фрагменты маскируются вместо того, чтобы записываться в конце).

Диаграмма, иллюстрирующая производные в растеризованном треугольнике

Производная пространства экрана от переменной (или выражения) vв вашем шейдере - это разница в значении v(в этой точке кода) от одной стороны этого квадрата 2x2 пикселей к другой. то есть. ddxзначение vв правом пикселе минус значение vв левом, и аналогично для ddyпо вертикали.

Это отвечает «насколько быстро vувеличивается или уменьшается, когда мы движемся горизонтально (ddx) или вертикально (ddy) по экрану?» - т.е. в терминах исчисления, он аппроксимирует частные производные вашей переменной (приблизительный, потому что он использует дискретные выборки в каждом фрагменте, а не математически оценивает бесконечно малое поведение функции)

Для скалярных величин мы также можем рассматривать это как вектор градиента, ∇v = float2(ddx(v), ddy(v)) который указывает вдоль направления пространства экрана, в котором vнаиболее быстро увеличивается.

Этот тип информации часто используется для выбора подходящего mipmap или ядра анизотропной фильтрации для поиска текстур. Например, если моя камера выглядит почти параллельно вертикальному uvнаправлению текстурированной плоскости пола, ddy(uv.y)она будет очень большой по сравнению с ddx(uv.x)(так как вертикальная ось укорочена на экране - один шаг пикселя по вертикали покрывает более длинный участок текстурного пространства), что сообщает аппаратуре выборки текстуры, что мне нужна анизотропная фильтрация, чтобы размыть вертикальное направление текстуры больше, чем горизонтальное, чтобы избежать наложения артефактов.

Для большинства простых эффектов вам не нужно использовать эти производные, так как базовые методы выборки двухмерных текстур обрабатывают это для вас. Но, как отмечает Le Comte du Merde-fou в комментарии выше, при искажении поиска текстур вам может потребоваться вручную извлечь и / или обработать используемые производные пространства экрана, чтобы помочь аппаратному обеспечению выбрать соответствующую фильтрацию (например, через tex2Dlodв HLSL)

Декали пространства экрана являются одним из таких случаев, когда один блок 2x2 может покрыть большой скачок скачка в вычисленной координате текстуры, приводя к размытому или псевдонимному краю, если вы позволите системе наивно рассчитать уровень фильтрации. В этой статье подробно рассказывается об этом артефакте и подходах к его смягчению .

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

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

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

Последнее замечание: производные пространства экрана могут быть вычислены с «грубой» / низкой точностью (это означает, что одна пара производных является общей для четырехугольника) или «с высокой» / высокой точностью (то есть каждый пиксель сравнивается только с его непосредственным соседи в кваде, которые могли бы дать четыре четкие пары производных по квадру). Обычно это достаточно, но если вы заметили, что в вашем эффекте видны блоки 2х2, это хорошая подсказка, которую вы хотите переключить на высокую / высокую точность. ;)

(На диаграмме вверху я использовал вычисления для мелких производных, но остерегайтесь того, что только ddx / ddy сам по себе может по умолчанию давать грубые производные)

ДМГригорий
источник
Когда вы говорите, что это разница между пикселями от одной стороны блока 2x2 к другой, это разница в значении пикселя или различие в положении текселя? Если это разница в значении, то суммирует тексели между ними или что-то в этом роде?
НеомерАркана
Это разница в значении аргумента ( vздесь), и так как это квадрат 4x2, между ними нет пикселей. Итак, если мы закрашиваем верхний левый фрагмент четырехугольника, и там v = 1, а в верхнем правом фрагменте v = 4, то ddx (v) = 3 (говоря, что «v увеличивается на 3 при движении слева направо ")
DMGregory
Я до сих пор не совсем понимаю. Если я смотрю под углом, блок 2x2 может не состоять из пикселей рядом в текстуре. Таким образом, разница в значениях - это разница между двумя выбранными текселями или разница между двумя выбранными текселями с учетом пропущенных?
NeomerArcana
Забудьте тексели - это не выборка текстуры. Он принимает буквальное значение аргумента, который вы передали ddx или ddy, и сравнивает его со значением, переданным ddx или ddy, при оценке соседнего фрагмента. Если это значение произошло из образца текстуры, пусть будет так, но производные функции не имеют никакого знания о текстурах. Они просто вычитают числа. Я попытаюсь добавить диаграмму к этому ответу, как только вернусь к своему ПК.
DMGregory
О, я думаю, теперь я понимаю. Было бы здорово получить диаграмму, но я думаю, что понимаю. Это похоже на очень полезные функции.
NeomerArcana