Что на самом деле делает ddx (hlsl)?

17

Я немного смущен. Официальная документация ( http://msdn.microsoft.com/en-us/library/windows/desktop/bb509588(v=vs.85).aspx ) гласит, что ddx (input) является частной производной ввода по отношению к "координате экрана-пространства."

Мое исчисление в порядке, но как оно может определить, откуда поступает информация? Если бы я передал ему функцию, хорошо, я могу представить, что она будет делать, но производная числа всегда равна нулю ...?

Это просто масштабирование? Мол, это будет масштабироваться до одной десятой его размера на этом расстоянии, поэтому он возвращает одну десятую? Но тогда это не требует ввода ...

Может кто-нибудь дать быстрое объяснение того, что на самом деле происходит?

Ричард Раст
источник
2
ddxи ddyтвори магию, которую ты не можешь сделать сам. У них есть доступ к дополнительной информации из конвейера растеризации, которую вы не можете получить из пиксельного шейдера. Я не уверен, какую именно формулу они используют; Я был убежден, что они используют технику оценки, но я точно не знаю.
Шон Мидлдич
Это очень странно, но все же. Что на самом деле представляет ddx (5)? Если там написано .1, как мне это интерпретировать? Или -6?
Ричард Раст
1
ddx(5)вроде бессмысленно. Используйте его с входным значением, и это даст вам производную этого значения по отношению к соседним пикселям в блоке. Опять же, я не знаю, насколько точно он вычисляет значения, но запрос производной от не входных данных может быть просто неопределенным поведением и создавать мусор. Смотрите fgiesen.wordpress.com/2011/07/10/… для получения дополнительной информации, чем я могу предоставить.
Шон Миддледич
Я не уверен, но вполне возможно, что HLSL-компилятор фактически выполняет полную символьную дифференциацию выражения, которое вы передаете в ddx / ddy. blogs.msdn.com/b/chuckw/archive/2011/03/08/… research.microsoft.com/pubs/146019/…
Ziriax
Что оно делает? Только немного разумное , что, очевидно.
MickLH

Ответы:

32

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

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

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

Таким образом, получение производной от постоянного значения даст ноль (как и следовало ожидать из исчисления, верно?), Потому что это одно и то же постоянное значение во всех четырех пикселях.

Также обратите внимание, что существуют «грубые» и «мелкие» производные ddx_coarse/ ddy_coarseи ddx_fine/ ddy_fine. Объяснение различия дается здесь . Просто ddx/ ddyпсевдонимы для грубых версий.

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

Натан Рид
источник
+1; Я нашел это полезным, когда применяю эффект возмущения к текстуре; возмущенные текстовые координаты дали некоторое искажение цвета, но использование tex2Dgrad с производными от оригинальных (невозмущенных) текстовых координат дало неискаженный результат.
Максимус Минимус
Хорошо, после некоторой мысли, я думаю, что понял мою путаницу. На мой взгляд, ddxработает как любая другая функция в традиционном языке программирования; Вы оцениваете ввод, превращаете его в число с плавающей точкой или что-то еще, а затем выполняете функцию external ( ddx) для него. Но это не так - он берет входную строку , оценивает ее в нескольких местах, вычисляет производную и сообщает результат. Это примерно так?
Ричард Раст
1
@RichardRast Верно. Вы можете думать, ddxчто оперируете выражением, которое вы передаете ему, а не значением .
Натан Рид
Но видите, это достаточно странно, что это должно быть в документации. Я не могу думать ни о каком другом времени в моей жизни программирования, где это имело место.
Ричард Раст
Натан Рид отметил, что графические процессоры используют эти функции для выбора mipmap. Вы также можете использовать их для принудительного выбора графическим процессором желаемого уровня mipmap или для предотвращения неправильного выбора уровней mip-артефактов. Процесс описан на страницах 163 и 164 шейдера X3.
JamesHoux