Цілком технічний термін fwidth(p)
визначається як
fwidth(p) := abs(dFdx(p)) + abs(dFdy(p))
І dFdx(p)
/ dFdy(p)
є частковими похідними значень p
щодо розмірів екрана x
та y
. Так вони позначають, як p
веде себе значення, коли йде один піксель вправо ( x
) або один піксель вгору ( y
).
Тепер, як їх можна практично обчислити? Що ж, якщо ви знаєте значення сусідніх пікселів для p
, ви можете просто обчислити ці похідні як прямі кінцеві відмінності, як наближення до їхніх фактичних математичних похідних (які можуть не мати точного аналітичного рішення):
dFdx(p) := p(x+1) - p(x)
Але, звичайно, тепер ви можете запитати, як ми навіть знаємо значення значень p
(які могли б вплинути на будь-яке довільно обчислене значення всередині програми шейдерів) для сусідніх пікселів? Як ми можемо обчислити ці значення, не зазнаючи великих накладних витрат, зробивши цілі шейдерні обчислення два (або три) рази?
Ну, ви знаєте що, ці сусідні значення так чи інакше обчислюються, оскільки для сусіднього пікселя ви також запускаєте шейдер фрагмента. Отже, все, що вам потрібно, це доступ до виклику цього сусіднього фрагмента шейдера при запуску для сусіднього пікселя. Але це ще простіше, тому що ці сусідні значення також обчислюються точно в той самий час.
Сучасні растризатори називають фрагменти шейдерів у більших плитках з більш ніж одного сусіднього пікселя. У найменших це була б сітка 2х2 пікселів. І для кожного такого піксельного блоку шейдер фрагмента викликається для кожного пікселя, і ці виклики виконуються в ідеально паралельному кроці блокування, так що всі обчислення виконуються в точно такому ж порядку і в точно той же час для кожного з цих пікселів у блоці (саме тому розгалуження в шейдері фрагмента, хоча і не смертельне, слід уникати, якщо це можливо, оскільки кожен виклик блоку повинен був би досліджувати кожну гілку, яка приймається принаймні однією з викликів, навіть якщо вона просто викидає результати після цього, як також зазначено у відповідях на це пов'язане питання). Тож у будь-який момент теоретично фрагмент шейдера теоретично має доступ до значень фрагментів шейдерів сусідніх пікселів. І поки ви не маєте прямий доступ до цих значень, ви маєте доступ до значень обчислених з них, як і похідних функцій dFdx
, dFdy
, fwidth
, ...
dFdx(p) = p(x1) - p(x)
, тодіx1
може бути або,(x+1)
або(x-1)
, залежно від положення пікселяx
на квадратику. У будь-якому випадку,x1
він повинен знаходитися в тій самій основі / хвилі, що іx
. Я прав?