Erstens ist es hilfreich zu wissen, dass GPUs immer Fragment- / Pixel-Shader auf 2x2 Pixelblöcken gleichzeitig auswerten. (Auch wenn letztendlich nur einige dieser Pixel gezeichnet werden müssen, während andere außerhalb des Polygons liegen oder verdeckt sind - die nicht benötigten Fragmente werden ausgeblendet, anstatt am Ende geschrieben zu werden.)
Die Bildschirmbereichsableitung einer Variablen (oder eines Ausdrucks) v
in Ihrem Shader ist die Differenz im Wert von v
(an diesem Punkt im Code) von einer Seite dieses 2x2-Pixel-Quad zur anderen. dh. ddx
ist der Wert von v
im rechten Pixel minus dem Wert von v
im linken Pixel und ähnlich für ddy
die Vertikale.
Dies antwortet: "Wie schnell nimmt v
zu oder ab, wenn wir uns horizontal (ddx) oder vertikal (ddy) über den Bildschirm bewegen?" - dh. In Bezug auf die Berechnung approximiert es die partiellen Ableitungen Ihrer Variablen (ungefähr, weil bei jedem Fragment diskrete Stichproben verwendet werden, anstatt das infinitesimale Verhalten der Funktion mathematisch zu bewerten).
Für skalare Größen können wir dies auch als einen Gradientenvektor betrachten, ∇v = float2(ddx(v), ddy(v))
der entlang der Bildschirmbereichsrichtung zeigt, in der er v
am schnellsten zunimmt.
Diese Art von Informationen wird häufig intern verwendet, um eine geeignete Mipmap oder einen anisotropen Filterkern für Textur-Lookups auszuwählen . Wenn meine Kamera beispielsweise fast parallel zur vertikalen uv
Richtung einer strukturierten Bodenebene aussieht , ist ddy(uv.y)
sie im Vergleich zu sehr groß ddx(uv.x)
(da die vertikale Achse auf dem Bildschirm verkürzt ist - ein Pixelschritt deckt vertikal einen längeren Abschnitt des Texturraums ab) teilt der Textur-Sampling-Hardware mit, dass ich eine anisotrope Filterung benötige, um die vertikale Texturrichtung stärker als die horizontale zu verwischen, um Aliasing-Artefakte zu vermeiden.
Für die meisten einfachen Effekte müssen Sie diese Ableitungen nicht verwenden, da die grundlegenden 2D-Texturabtastmethoden dies für Sie erledigen. Wie Le Comte du Merde-fou in einem Kommentar oben erwähnt, müssen Sie beim Verzerren Ihrer Textur-Lookups möglicherweise die zu verwendenden Screenspace-Derivate manuell abrufen und / oder massieren, um die Hardware bei der Auswahl der geeigneten Filterung zu unterstützen (z. B. via tex2Dlod
in HLSL)
Bildschirmabziehbilder sind ein solcher Fall, bei dem ein einzelner 2x2-Block eine große Sprungdiskontinuität in der berechneten Texturkoordinate abdecken kann, was zu einer verschmierten oder aliasierten Kante führt, wenn Sie das System den Filterpegel naiv berechnen lassen. Dieser Artikel geht detailliert auf dieses Artefakt ein und versucht, es zu mildern .
Diese Ableitungen können auch nützlich sein, wenn Sie Rauschfunktionen bei der Erzeugung prozeduraler Texturen verwenden. Wenn Sie beispielsweise prozedurales Rauschen in eine normale Karte umwandeln möchten, geben ddx & ddy eine einfache, wenn auch ungefähre Methode, um zu berechnen, wie sich der Rauschwert in der Nähe des aktuellen Fragments ändert und in welche Richtung er abfällt kann eine entsprechende Normalen konstruieren.
Techniken zum Rendern von Antialias-Linien oder Schnittpunkten können auch Bildschirmbereichsableitungen verwenden, um sicherzustellen, dass die Dicke / der Abfall konsistent ist und nicht von der Geometrie oder dem Betrachtungswinkel abhängt.
In diesem Vortrag über Sand-Rendering in Journey erwähnt der Redner, dass sie diese abgeleiteten Funktionen hätten verwenden können, um zu steuern, wie funkelnd der Sand entlang flüchtiger Kanten ist ... wenn sie zu diesem Zeitpunkt davon gewusst hätten (stattdessen verwendeten sie einen Mipmapping-Trick) die unter der Haube sowieso von solchen Derivaten angetrieben wird)
Ein letzter Hinweis: Bildschirmbereichsableitungen können mit "grober" / geringer Genauigkeit (dh ein Paar von Ableitungen wird vom gesamten Quad geteilt) oder "fein" / hoher Genauigkeit (dh jedes Pixel wird nur mit seiner unmittelbaren verglichen) berechnet werden Nachbarn im Quad, die vier verschiedene Ableitungspaare über dem Quad ergeben könnten). Grob ist im Allgemeinen ausreichend, aber wenn Sie feststellen, dass in Ihrem Effekt 2x2 Blöcke sichtbar sind, ist dies ein guter Hinweis, den Sie auf Fein / Hochpräzision umstellen möchten. ;)
(In der Abbildung oben habe ich Berechnungen für feine Ableitungen verwendet, aber Vorsicht, dass nur ddx / ddy für sich genommen standardmäßig grobe Ableitungen verwenden kann.)