Copyright (c) 2023 Advanced Micro Devices, Inc. Alle Rechte vorbehalten.
Hiermit wird jeder Person, die eine Kopie dieser Software und der zugehörigen Dokumentationsdateien (die „Software“) erhält, kostenlos die Erlaubnis erteilt, mit der Software ohne Einschränkung zu handeln, einschließlich und ohne Einschränkung der Rechte zur Nutzung, zum Kopieren, Ändern und Zusammenführen , Kopien der Software zu veröffentlichen, zu verteilen, unterzulizenzieren und/oder zu verkaufen und Personen, denen die Software zur Verfügung gestellt wird, dies zu gestatten, vorbehaltlich der folgenden Bedingungen: Der obige Urheberrechtshinweis und dieser Genehmigungshinweis müssen in allen Kopien enthalten sein oder wesentliche Teile der Software.
DIE SOFTWARE WIRD „WIE BESEHEN“ ZUR VERFÜGUNG GESTELLT, OHNE JEGLICHE AUSDRÜCKLICHE ODER STILLSCHWEIGENDE GEWÄHRLEISTUNG, EINSCHLIESSLICH, ABER NICHT BESCHRÄNKT AUF DIE GEWÄHRLEISTUNG DER MARKTGÄNGIGKEIT, EIGNUNG FÜR EINEN BESTIMMTEN ZWECK UND NICHTVERLETZUNG. IN KEINEM FALL SIND DIE AUTOREN ODER URHEBERRECHTSINHABER HAFTBAR FÜR JEGLICHE ANSPRÜCHE, SCHÄDEN ODER ANDERE HAFTUNG, WEDER AUS EINER VERTRAGLICHEN HANDLUNG, AUS HANDLUNG ODER ANDERWEITIG, DIE SICH AUS, AUS ODER IN ZUSAMMENHANG MIT DER SOFTWARE ODER DER NUTZUNG ODER ANDEREN HANDELN IN DER SOFTWARE ERGEBEN SOFTWARE.
FSR2 nutzt zeitliches Feedback, um hochauflösende Bilder zu rekonstruieren und gleichzeitig die Bildqualität im Vergleich zum nativen Rendering beizubehalten oder sogar zu verbessern.
FSR2 kann „praktische Leistung“ für kostspielige Rendervorgänge wie Hardware-Raytracing ermöglichen.
HLSL
CS_6_2
CS_6_6*
* – CS_6_6 wird auf mancher Hardware verwendet, die 64-breite Wellenfronten unterstützt.
Um FSR2 zu verwenden, sollten Sie die folgenden Schritte ausführen:
Doppelklicken Sie im build
-Verzeichnis auf GenerateSolutions.bat
.
Öffnen Sie die Lösung, die Ihrer API entspricht, und erstellen Sie die Lösung.
Kopieren Sie die API-Bibliothek von bin/ffx_fsr2_api
in den Ordner, der einen Ordner in Ihrem Projekt enthält, der Bibliotheken von Drittanbietern enthält.
Kopieren Sie die Bibliothek, die dem FSR2-Backend entspricht, das Sie verwenden möchten, z. B. bin/ffx_fsr2_api/ffx_fsr2_api_dx12_x64.lib
für DirectX12.
Kopieren Sie die folgenden Kern-API-Headerdateien von src/ffx-fsr2-api in Ihr Projekt: ffx_fsr2.h
, ffx_types.h
, ffx_error.h
, ffx_fsr2_interface.h
, ffx_util.h
, shaders/ffx_fsr2_common.h
und shaders/ffx_fsr2_resources.h
. Es sollte darauf geachtet werden, die relative Verzeichnisstruktur am Zielort der Dateikopie beizubehalten.
Kopieren Sie die Header-Dateien für das API-Backend Ihrer Wahl, z. B. für DirectX12 würden Sie dx12/ffx_fsr2_dx12.h
und dx12/shaders/ffx_fsr2_shaders_dx12.h
kopieren. Es sollte darauf geachtet werden, die relative Verzeichnisstruktur am Zielort der Dateikopie beizubehalten.
Fügen Sie die Header-Datei ffx_fsr2.h
in Ihre Codebasis ein, wo Sie mit FSR2 interagieren möchten.
Erstellen Sie ein Backend für Ihre Ziel-API. Für DirectX12 sollten Sie beispielsweise ffxFsr2GetInterfaceDX12
aufrufen. Es sollte ein Arbeitspuffer mit der durch den Aufruf ffxFsr2GetScratchMemorySizeDX12
zurückgegebenen Größe zugewiesen und der Zeiger auf diesen Puffer an ffxFsr2GetInterfaceDX12
übergeben werden.
Erstellen Sie einen FSR2-Kontext, indem Sie ffxFsr2ContextCreate
aufrufen. Die Parameterstruktur sollte entsprechend der Konfiguration Ihrer Anwendung ausgefüllt werden. Weitere Einzelheiten finden Sie in der API-Referenzdokumentation.
Für jeden Frame sollten Sie ffxFsr2ContextDispatch
aufrufen, um FSR2-Workloads zu starten. Die Parameterstruktur sollte entsprechend der Konfiguration Ihrer Anwendung ausgefüllt werden. Weitere Informationen finden Sie in der API-Referenzdokumentation. Stellen Sie sicher, dass das Feld frameTimeDelta
in Millisekunden angegeben wird.
Wenn Ihre Anwendung beendet wird (oder Sie den Kontext aus einem anderen Grund zerstören möchten), sollten Sie ffxFsr2ContextDestroy
aufrufen. Die GPU sollte inaktiv sein, bevor diese Funktion aufgerufen wird.
Subpixel-Jittering sollte auf die Projektionsmatrix Ihrer Anwendung angewendet werden. Dies sollte beim Durchführen des Hauptrenderings Ihrer Anwendung erfolgen. Sie sollten die Funktion ffxFsr2GetJitterOffset
verwenden, um die genauen Jitter-Offsets zu berechnen. Weitere Einzelheiten finden Sie im Abschnitt Kamera-Jitter.
Für die beste Upscaling-Qualität wird dringend empfohlen, die Reaktivmaske und die Transparenz- und Kompositionsmaske gemäß unseren Richtlinien auszufüllen. Sie können auch ffxFsr2ContextGenerateReactiveMask
als Ausgangspunkt verwenden.
Anwendungen sollten Skalierungsmodi in ihrer Benutzeroberfläche in der folgenden Reihenfolge verfügbar machen: Qualität, Ausgewogen, Leistung und (optional) Ultra-Leistung.
Anwendungen sollten außerdem einen Schieberegler für die Schärfung bereitstellen, damit Endbenutzer zusätzliche Qualität erzielen können.
Zur Vereinfachung für Endbenutzer bietet die FSR2-API eine Reihe voreingestellter Skalierungsverhältnisse, die benannt sind.
Qualität | Skalierungsfaktor pro Dimension |
---|---|
Qualität | 1,5x |
Ausgewogen | 1,7x |
Leistung | 2,0x |
Ultra-Leistung | 3,0x |
Wir empfehlen dringend, dass Anwendungen in ihrer Benutzeroberfläche konsistente Namens- und Skalierungsverhältnisse übernehmen. Dadurch soll sichergestellt werden, dass die Benutzererfahrung für die Benutzer Ihrer Anwendung konsistent ist, die möglicherweise Erfahrung mit anderen Anwendungen haben, die FSR2 verwenden.
Abhängig von Ihrer Zielhardware und Betriebskonfiguration arbeitet FSR2 mit unterschiedlichen Leistungsniveaus.
Die folgende Tabelle fasst die gemessene Leistung von FSR2 auf einer Vielzahl von Hardware in DX12 zusammen.
Zielauflösung | Qualität | RX 7900 XTX | RX 6950 XT | RX 6900 XT | RX 6800 XT | RX 6800 | RX 6700 XT | RX 6650 XT | RX 5700 XT | RX Vega 56 | RX 590 |
---|---|---|---|---|---|---|---|---|---|---|---|
3840x2160 | Qualität (1,5x) | 0,7 ms | 1,1 ms | 1,2 ms | 1,2 ms | 1,4 ms | 2,0 ms | 2,8 ms | 2,4 ms | 4,9 ms | 5,4 ms |
Ausgewogen (1,7x) | 0,6 ms | 1,0 ms | 1,0 ms | 1,1 ms | 1,4 ms | 1,8 ms | 2,6 ms | 2,2 ms | 4,1 ms | 4,9 ms | |
Leistung (2x) | 0,6 ms | 0,9 ms | 1,0 ms | 1,0 ms | 1,3 ms | 1,7 ms | 2,3 ms | 2,0 ms | 3,6 ms | 4,4 ms | |
Ultraperf. (3x) | 0,5 ms | 0,8 ms | 0,8 ms | 0,9 ms | 1,1 ms | 1,5 ms | 1,8 ms | 1,7 ms | 2,9 ms | 3,7 ms | |
2560x1440 | Qualität (1,5x) | 0,3 ms | 0,5 ms | 0,5 ms | 0,5 ms | 0,7 ms | 0,9 ms | 1,2 ms | 1,1 ms | 1,9 ms | 2,3 ms |
Ausgewogen (1,7x) | 0,3 ms | 0,5 ms | 0,5 ms | 0,5 ms | 0,6 ms | 0,8 ms | 1,1 ms | 1,0 ms | 1,7 ms | 2,1 ms | |
Leistung (2x) | 0,3 ms | 0,4 ms | 0,4 ms | 0,4 ms | 0,6 ms | 0,8 ms | 0,9 ms | 0,9 ms | 1,5 ms | 1,9 ms | |
Ultraperf. (3x) | 0,2 ms | 0,4 ms | 0,4 ms | 0,4 ms | 0,5 ms | 0,7 ms | 0,8 ms | 0,8 ms | 1,2 ms | 1,7 ms | |
1920x1080 | Qualität (1,5x) | 0,2 ms | 0,3 ms | 0,3 ms | 0,3 ms | 0,4 ms | 0,5 ms | 0,6 ms | 0,6 ms | 1,0 ms | 1,3 ms |
Ausgewogen (1,7x) | 0,2 ms | 0,3 ms | 0,3 ms | 0,3 ms | 0,4 ms | 0,5 ms | 0,6 ms | 0,6 ms | 0,9 ms | 1,2 ms | |
Leistung (2x) | 0,2 ms | 0,2 ms | 0,2 ms | 0,3 ms | 0,3 ms | 0,5 ms | 0,5 ms | 0,5 ms | 0,8 ms | 1,1 ms | |
Ultraperf. (3x) | 0,1 ms | 0,2 ms | 0,2 ms | 0,2 ms | 0,3 ms | 0,4 ms | 0,4 ms | 0,4 ms | 0,7 ms | 0,9 ms |
Die Angaben sind auf 0,1 ms gerundet, ohne zusätzliche sharpness
und können sich ändern.
Für die Verwendung von FSR2 muss zusätzlicher lokaler GPU-Speicher zur Nutzung durch die GPU zugewiesen werden. Bei Verwendung der FSR2-API wird dieser Speicher zugewiesen, wenn der FSR2-Kontext erstellt wird, und zwar über die Reihe von Rückrufen, aus denen die Backend-Schnittstelle besteht. Dieser Speicher wird zum Speichern von Zwischenoberflächen verwendet, die vom FSR2-Algorithmus berechnet werden, sowie von Oberflächen, die über viele Frames der Anwendung hinweg persistent sind. Die folgende Tabelle enthält die von FSR2 unter verschiedenen Betriebsbedingungen verwendete Speichermenge. Die Spalte „Arbeitssatz“ gibt die Gesamtmenge an Speicher an, die von FSR2 verwendet wird, während der Algorithmus auf der GPU ausgeführt wird. Dies ist die Menge an Speicher, die FSR2 zum Ausführen benötigt. Die Spalte „Persistenter Speicher“ gibt an, wie viel von der Spalte „Arbeitssatz“ für nachfolgende Frames der Anwendung intakt bleiben muss; In diesem Speicher werden die von FSR2 verbrauchten Zeitdaten gespeichert. Die Spalte „Aliasable Memory“ gibt an, wie viel der Spalte „Working Set“ durch Oberflächen oder andere Ressourcen, die von der Anwendung außerhalb der Betriebsgrenzen von FSR2 verwendet werden, gealiased werden kann.
Sie können die Ressourcenerstellung in FSR2 steuern, indem Sie die Ressourcenerstellungs- und -vernichtungsteile der FSR2-Backend-Schnittstelle überschreiben und die Aliasing-Flags weiterleiten. Das bedeutet, dass für eine perfekte Integration von FSR2 abhängig von Ihren Betriebsbedingungen zusätzlicher Speicher in Höhe der Spalte „Persistenter Speicher“ der folgenden Tabelle erforderlich ist.
Auflösung | Qualität | Arbeitssatz (MB) | Persistenter Speicher (MB) | Aliasierbarer Speicher (MB) |
---|---|---|---|---|
3840x2160 | Qualität (1,5x) | 448 MB | 354 MB | 93 MB |
Ausgewogen (1,7x) | 407 MB | 330 MB | 77 MB | |
Leistung (2x) | 376 MB | 312 MB | 63 MB | |
Ultra-Leistung (3x) | 323 MB | 281 MB | 42 MB | |
2560x1440 | Qualität (1,5x) | 207 MB | 164 MB | 43 MB |
Ausgewogen (1,7x) | 189 MB | 153 MB | 36 MB | |
Leistung (2x) | 172 MB | 143 MB | 29 MB | |
Ultra-Leistung (3x) | 149 MB | 130 MB | 19 MB | |
1920x1080 | Qualität (1,5x) | 115 MB | 90 MB | 24 MB |
Ausgewogen (1,7x) | 105 MB | 85 MB | 20 MB | |
Leistung (2x) | 101 MB | 83 MB | 18 MB | |
Ultra-Leistung (3x) | 84 MB | 72 MB | 11 MB |
Bei den Zahlen handelt es sich um Näherungswerte, aufgerundet auf die nächsten MB unter Verwendung einer RX 6700XT-GPU in DX12. Änderungen vorbehalten.
Einzelheiten zur Verwaltung der Speicheranforderungen von FSR2 finden Sie im Abschnitt dieses Dokuments, der sich mit der Speicherverwaltung befasst.
FSR2 ist ein zeitlicher Algorithmus und erfordert daher Zugriff auf Daten sowohl des aktuellen als auch des vorherigen Frames. In der folgenden Tabelle sind alle für FSR2 erforderlichen externen Eingaben aufgeführt.
Die Auflösungsspalte gibt an, ob die Daten die Auflösung „gerendert“ oder „Präsentation“ haben sollen. Die „gerenderte“ Auflösung gibt an, dass die Ressource mit der Auflösung übereinstimmen sollte, mit der die Anwendung ihr Rendering durchführt. Umgekehrt gibt „Präsentation“ an, dass die Auflösung des Ziels mit der Auflösung übereinstimmen sollte, die dem Benutzer präsentiert werden soll. Alle Ressourcen stammen aus dem aktuell gerenderten Frame. Für DirectX(R)12- und Vulkan(R)-Anwendungen sollten alle Eingaberessourcen vor dem Aufruf von
ffxFsr2ContextDispatch
aufD3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE
bzw.VK_ACCESS_SHADER_READ_BIT
umgestellt werden.
Name | Auflösung | Format | Typ | Notizen |
---|---|---|---|---|
Farbpuffer | Machen | APPLICATION SPECIFIED | Textur | Der von der Anwendung bereitgestellte Farbpuffer für die Renderauflösung für den aktuellen Frame. Wenn sich der Inhalt des Farbpuffers im hohen Dynamikbereich (HDR) befindet, sollte das Flag FFX_FSR2_ENABLE_HIGH_DYNAMIC_RANGE im flags Feld der FfxFsr2ContextDescription -Struktur festgelegt werden. |
Tiefenpuffer | Machen | APPLICATION SPECIFIED (1x FLOAT) | Textur | Der von der Anwendung bereitgestellte Tiefenpuffer für die Renderauflösung für den aktuellen Frame. Die Daten sollten als einzelner Gleitkommawert bereitgestellt werden, dessen Genauigkeit der Kontrolle der Anwendung unterliegt. Die Konfiguration der Tiefe sollte FSR2 über das flags Feld der FfxFsr2ContextDescription -Struktur beim Erstellen des FfxFsr2Context mitgeteilt werden. Sie sollten das Flag FFX_FSR2_ENABLE_DEPTH_INVERTED setzen, wenn Ihr Tiefenpuffer invertiert ist (das ist der Bereich [1..0]), und Sie sollten das Flag FFX_FSR2_ENABLE_DEPTH_INFINITE setzen, wenn Ihr Tiefenpuffer eine unendliche Fernebene hat. Wenn die Anwendung den Tiefenpuffer im D32S8 -Format bereitstellt, ignoriert FSR2 die Schablonenkomponente des Puffers und erstellt eine R32_FLOAT -Ressource, um den Tiefenpuffer zu adressieren. Auf GCN- und RDNA-Hardware werden Tiefenpuffer getrennt von Schablonenpuffern gespeichert. |
Bewegungsvektoren | Rendern oder Präsentieren | APPLICATION SPECIFIED (2x FLOAT) | Textur | Die 2D-Bewegungsvektoren für den aktuellen Frame, die von der Anwendung im Bereich [ (<-width, -height> .. <width, height> ] bereitgestellt werden. Wenn Ihre Anwendung Bewegungsvektoren mit einem anderen Bereich rendert, können Sie das Feld motionVectorScale von verwenden die FfxFsr2DispatchDescription -Struktur, um sie an den erwarteten Bereich für FSR2 anzupassen. Intern verwendet FSR2 in vielen Fällen 16-Bit-Größen, um Bewegungsvektoren darzustellen dass zwar Bewegungsvektoren mit höherer Präzision bereitgestellt werden können, FSR2 jedoch nicht von der erhöhten Präzision profitiert. Die Auflösung des Bewegungsvektorpuffers sollte der Renderauflösung entsprechen, es sei denn, das Flag FFX_FSR2_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS ist im flags -Feld der FfxFsr2ContextDescription -Struktur festgelegt Erstellen des FfxFsr2Context . In diesem Fall sollte er der Präsentationsauflösung entsprechen. |
Reaktive Maske | Machen | R8_UNORM | Textur | Da einige Bereiche eines gerenderten Bildes keinen Fußabdruck im Tiefenpuffer hinterlassen oder Bewegungsvektoren enthalten, bietet FSR2 Unterstützung für eine reaktive Maskentextur, die verwendet werden kann, um FSR2 anzuzeigen, wo sich solche Bereiche befinden. Gute Beispiele hierfür sind Partikel oder Alpha-gemischte Objekte, die keine Tiefen- oder Bewegungsvektoren schreiben. Wenn diese Ressource nicht festgelegt ist, wird die Logik zur Erkennung von Schattierungsänderungen von FSR2 diese Fälle so gut wie möglich behandeln. Für optimale Ergebnisse sollte diese Ressource jedoch festgelegt werden. Weitere Informationen zur reaktiven Maske finden Sie im Abschnitt „Reaktive Maske“. |
Belichtung | 1x1 | R32_FLOAT | Textur | Eine 1x1-Textur, die den für den aktuellen Frame berechneten Belichtungswert enthält. Diese Ressource ist optional und kann weggelassen werden, wenn das FFX_FSR2_ENABLE_AUTO_EXPOSURE Flag beim Erstellen von FfxFsr2Context im flags -Feld der FfxFsr2ContextDescription -Struktur festgelegt ist. |
Alle Eingaben, die mit Renderauflösung bereitgestellt werden, mit Ausnahme von Bewegungsvektoren, sollten mit Jitter gerendert werden. Auf Bewegungsvektoren sollte kein Jitter angewendet werden, es sei denn, das Flag FFX_FSR2_ENABLE_MOTION_VECTORS_JITTER_CANCELLATION
ist vorhanden.
Es wird dringend empfohlen, mit FSR2 einen invertierten Puffer mit unendlicher Tiefe zu verwenden. Es werden jedoch alternative Tiefenpufferkonfigurationen unterstützt. Eine Anwendung sollte die FSR2-API über ihre Tiefenpufferkonfiguration informieren, indem sie während der Erstellung des FfxFsr2Context
die entsprechenden Flags setzt. Die folgende Tabelle enthält die entsprechenden Flags.
FSR2-Flag | Notiz |
---|---|
FFX_FSR2_ENABLE_DEPTH_INVERTED | Ein Bit, das angibt, dass die bereitgestellten Eingabetiefenpufferdaten invertiert sind [max..0]. |
FFX_FSR2_ENABLE_DEPTH_INFINITE | Ein Bit, das angibt, dass die bereitgestellten Eingabetiefenpufferdaten eine unendliche Fernebene verwenden. |
Ein wichtiger Teil eines zeitlichen Algorithmus (sei es Antialiasing oder Upscaling) ist die Bereitstellung von Bewegungsvektoren. FSR2 akzeptiert Bewegungsvektoren in 2D, die die Bewegung von einem Pixel im aktuellen Frame bis zur Position desselben Pixels im vorherigen Frame kodieren. FSR2 erwartet, dass Bewegungsvektoren von der Anwendung im Bereich [ <-width, -height> .. <width, height> ] bereitgestellt werden; Dies entspricht dem Bildschirmbereich. Beispielsweise würde ein Bewegungsvektor für ein Pixel in der oberen linken Ecke des Bildschirms mit einem Wert von <width, height> eine Bewegung darstellen, die die gesamte Breite und Höhe der Eingabeoberflächen durchquert und ihren Ursprung in der unteren rechten Ecke hat .
Wenn Ihre Anwendung Bewegungsvektoren in einem anderen Raum berechnet – beispielsweise im normalisierten Gerätekoordinatenraum –, können Sie das Feld motionVectorScale
“ der FfxFsr2DispatchDescription
-Struktur verwenden, um FSR2 anzuweisen, sie an den erwarteten Bereich für FSR2 anzupassen. Die folgenden Codebeispiele veranschaulichen, wie Bewegungsvektoren auf den Bildschirmbereich skaliert werden können. Der folgende HLSL- und C++-Beispielcode veranschaulicht, wie Bewegungsvektoren im NDC-Raum mithilfe der FSR2-Host-API skaliert werden können.
// GPU: Example of application NDC motion vector computation
float2 motionVector = (previousPosition.xy / previousPosition.w) - (currentPosition.xy / currentPosition.w);
// CPU: Matching FSR 2.0 motionVectorScale configuration
dispatchParameters.motionVectorScale.x = ( float )renderWidth;
dispatchParameters.motionVectorScale.y = ( float )renderHeight;
Intern verwendet FSR2 in vielen Fällen 16-Bit-Größen zur Darstellung von Bewegungsvektoren. Das bedeutet, dass zwar Bewegungsvektoren mit höherer Präzision bereitgestellt werden können, FSR2 jedoch derzeit nicht von der erhöhten Präzision profitieren wird. Die Auflösung des Bewegungsvektorpuffers sollte der Renderauflösung entsprechen, es sei denn, das Flag FFX_FSR2_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS
ist beim Erstellen von FfxFsr2Context
im flags
-Feld der FfxFsr2ContextDescription
-Struktur festgelegt. In diesem Fall sollte es der Präsentationsauflösung entsprechen.
FSR2 führt eine hochwertigere Hochskalierung durch, wenn mehr Objekte ihre Bewegungsvektoren bereitstellen. Es wird daher empfohlen, dass alle undurchsichtigen, Alpha-getesteten und Alpha-gemischten Objekte ihre Bewegungsvektoren für alle abgedeckten Pixel schreiben sollten. Wenn Vertex-Shader-Effekte angewendet werden – wie z. B. scrollende UVs – sollten diese Berechnungen auch in die Berechnung der Bewegung einbezogen werden, um die besten Ergebnisse zu erzielen. Bei Objekten mit Alpha-Mischung wird außerdem dringend empfohlen, den Alpha-Wert jedes abgedeckten Pixels im entsprechenden Pixel in der reaktiven Maske zu speichern. Dadurch kann FSR2 Alpha-Blending-Objekte während der Hochskalierung besser verarbeiten. Die reaktive Maske ist besonders wichtig für Objekte mit Alpha-Mischung, bei denen das Schreiben von Bewegungsvektoren möglicherweise unerschwinglich ist, beispielsweise bei Partikeln.
Im Kontext von FSR2 bedeutet der Begriff „Reaktivität“, wie viel Einfluss die für den aktuellen Frame gerenderten Samples auf die Produktion des endgültigen hochskalierten Bildes haben. Typischerweise tragen die für den aktuellen Frame gerenderten Samples nur einen relativ geringen Anteil zum von FSR2 berechneten Ergebnis bei; Es gibt jedoch Ausnahmen. Um die besten Ergebnisse für sich schnell bewegende Objekte mit Alpha-Mischung zu erzielen, erfordert FSR2, dass die Phase „Neu projizieren und akkumulieren“ für solche Pixel reaktiver wird. Da es keine gute Möglichkeit gibt, anhand von Farbe, Tiefe oder Bewegungsvektoren zu bestimmen, welche Pixel mithilfe von Alpha-Blending gerendert wurden, schneidet FSR2 am besten ab, wenn Anwendungen solche Bereiche explizit markieren.
Daher wird dringend empfohlen, dass Anwendungen eine reaktive Maske für FSR2 bereitstellen. Die reaktive Maske leitet FSR2 an, wo es seine Abhängigkeit von historischen Informationen beim Zusammenstellen des aktuellen Pixels reduzieren und stattdessen zulassen sollte, dass die Samples des aktuellen Frames mehr zum Endergebnis beitragen. Die reaktive Maske ermöglicht es der Anwendung, einen Wert von [0,0..1,0] bereitzustellen, wobei 0,0 angibt, dass das Pixel überhaupt nicht reaktiv ist (und die standardmäßige FSR2-Kompositionsstrategie verwenden sollte), und ein Wert von 1,0 angibt, dass das Pixel vollständig reaktiv sein sollte reaktiv. Dies ist ein Gleitkommabereich und kann an verschiedene Situationen angepasst werden.
Während es andere Anwendungen für die reaktive Maske gibt, besteht die Hauptanwendung der reaktiven Maske darin, bessere Ergebnisse bei der Hochskalierung von Bildern zu erzielen, die Objekte mit Alpha-Überblendung enthalten. Ein guter Indikator für die Reaktivität ist tatsächlich der Alpha-Wert, der beim Einfügen eines mit Alpha gemischten Objekts in die Szene verwendet wird. Daher sollten Anwendungen alpha
in die reaktive Maske schreiben. Es ist zu beachten, dass es unwahrscheinlich ist, dass ein reaktiver Wert von nahe 1 jemals zu guten Ergebnissen führt. Wir empfehlen daher, den maximalen Blindwert auf etwa 0,9 zu begrenzen.
Wenn FSR2 keine reaktive Maske bereitgestellt wird (indem das reactive
Feld von FfxFsr2DispatchDescription
auf NULL
gesetzt wird), wird eine intern generierte 1x1-Textur mit einem gelöschten reaktiven Wert verwendet.
Um Anwendungen bei der Generierung der Reaktivmaske und der Transparenz- und Kompositionsmaske zu unterstützen, bietet FSR2 eine optionale Hilfs-API. Unter der Haube startet die API einen Compute-Shader, der diese Werte für jedes Pixel mithilfe einer auf Luminanz basierenden Heuristik berechnet.
Anwendungen, die dies tun möchten, können die Funktion ffxFsr2ContextGenerateReactiveMask
aufrufen und sollten zwei Versionen des Farbpuffers übergeben, von denen eine nur undurchsichtige Geometrie enthält und die andere sowohl undurchsichtige als auch Alpha-gemischte Objekte enthält.
Zusätzlich zur reaktiven Maske ermöglicht FSR2 der Anwendung die Kennzeichnung von Bereichen anderer spezieller Darstellungen, die während des Upscaling-Prozesses berücksichtigt werden sollten. Beispiele für ein solches spezielles Rendering sind Bereiche mit Raytrace-Reflexionen oder animierte Texturen.
Während die reaktive Maske das Akkumulationsgleichgewicht anpasst, passt die Transparenz- und Kompositionsmaske die Schutzmechanismen für den Pixelverlauf an. Die Maske beseitigt auch den Effekt des Luminanzinstabilitätsfaktors. Ein Pixel mit dem Wert 0 in der Transparenz- und Kompositionsmaske führt keine zusätzliche Änderung an der Sperre für dieses Pixel durch. Umgekehrt bedeutet ein Wert von 1, dass die Sperre für dieses Pixel vollständig entfernt werden sollte.
Wenn für FSR2 keine Transparenz- und Kompositionsmaske bereitgestellt wird (durch Festlegen des Felds transparencyAndComposition
von FfxFsr2DispatchDescription
auf NULL
), wird eine intern generierte 1x1-Textur mit einem gelöschten Transparenz- und Kompositionswert verwendet.
FSR2.2 enthält eine experimentelle Funktion zum automatischen Generieren einer Reaktivmaske und einer Transparenz- und Kompositionsmaske. Um dies zu ermöglichen, muss das Feld enableAutoReactive
von FfxFsr2DispatchDescription
auf „TRUE“ gesetzt werden und eine Kopie der nur undurchsichtigen Teile des Backbuffers muss in „colorOpaqueOnly“ bereitgestellt werden. FSR2 generiert und verwendet dann intern automatisch die Reaktivmaske und die Transparenz- und Kompositionsmaske. Die Masken werden in einem Rechendurchgang generiert, indem die Differenz des Farbpuffers mit und ohne transparente Geometrie analysiert und mit dem vorherigen Frame verglichen wird. Basierend auf dem Ergebnis dieser Berechnungen werden jedem Pixel Werte für die reaktive Maske und die Transparenz- und Kompositionsmaske zugewiesen. Um die automatische Generierung der Masken zu verwenden, müssen auch die folgenden 4 Werte zur Skalierung und Begrenzung der Intensität der Masken bereitgestellt werden (beachten Sie, dass die genannten Standardwerte empfohlene Startwerte sind, aber je nach Titel angepasst werden sollten):
Diese Funktion soll bei der Integration von FSR2.2 in eine neue Engine oder einen neuen Titel helfen. Für die beste Qualität empfehlen wir jedoch weiterhin, die Reaktivmaske und die Transparenz- und Kompositionsmaske selbst zu rendern, da die Generierung dieser Werte basierend auf dem Material voraussichtlich zuverlässiger ist als die automatische Generierung aus dem endgültigen Bild.
Bitte beachten Sie, dass sich diese Funktion noch im experimentellen Stadium befindet und sich in Zukunft erheblich ändern kann.
FSR2 stellt zwei Werte bereit, die die beim Hochskalieren verwendete Belichtung steuern. Sie lauten wie folgt:
Der Belichtungswert sollte mit dem Wert übereinstimmen, den die Anwendung bei allen nachfolgenden Tonemapping-Durchgängen verwendet, die von der Anwendung durchgeführt werden. Dies bedeutet, dass FSR2 konsistent mit dem arbeitet, was wahrscheinlich im endgültigen Tonemapping-Bild sichtbar ist.
In verschiedenen Phasen des in diesem Dokument beschriebenen FSR2-Algorithmus berechnet FSR2 seinen eigenen Expositionswert für den internen Gebrauch. Es ist zu beachten, dass bei allen Ausgängen von FSR2 diese interne Tonzuordnung umgekehrt wird, bevor der endgültige Ausgang geschrieben wird. Das bedeutet, dass FSR2 Ergebnisse im gleichen Bereich wie das ursprüngliche Eingangssignal zurückgibt.
Schlecht ausgewählte Belichtungswerte können drastische Auswirkungen auf die endgültige Qualität der Hochskalierung von FSR2 haben. Daher wird empfohlen, FFX_FSR2_ENABLE_AUTO_EXPOSURE
von der Anwendung zu verwenden, es sei denn, es gibt einen besonderen Grund dagegen. Wenn FFX_FSR2_ENABLE_AUTO_EXPOSURE
im flags
-Feld der FfxFsr2ContextDescription
-Struktur festgelegt ist, wird die im folgenden HLSL-Code gezeigte Belichtungsberechnung verwendet, um den Belichtungswert zu berechnen, der der Belichtungsreaktion von ISO 100-Filmmaterial entspricht.
float ComputeAutoExposureFromAverageLog ( float averageLogLuminance)
{
const float averageLuminance = exp (averageLogLuminance);
const float S = 100.0f ; // ISO arithmetic speed
const float K = 12.5f ;
const float exposureIso100 = log2 ((averageLuminance * S) / K);
const float q = 0.65f ;
const float luminanceMax = ( 78.0f / (q * S)) * pow ( 2.0f , exposureIso100);
return 1 / luminanceMax;
}
Das Hauptziel von FSR2 besteht darin, die Leistung beim Rendern von Anwendungen zu verbessern, indem ein zeitlicher Hochskalierungsalgorithmus verwendet wird, der auf einer Reihe von Eingaben basiert. Daher ist seine Platzierung in der Pipeline von entscheidender Bedeutung, um das richtige Gleichgewicht zwischen höchster visueller Qualität und hervorragender Leistung sicherzustellen.
Bei jedem Bildhochskalierungsansatz ist es wichtig zu verstehen, wie andere Bildraumalgorithmen in Bezug auf den Hochskalierungsalgorithmus platziert werden. Die Platzierung dieser anderen Bildraumeffekte vor der Hochskalierung hat den Vorteil, dass sie mit einer niedrigeren Auflösung ausgeführt werden, was der Anwendung natürlich einen Leistungsvorteil verleiht. Für einige Klassen von Bildraumtechniken ist es jedoch möglicherweise nicht geeignet. Beispielsweise können viele Anwendungen Rauschen oder Körnung in das endgültige Bild einbringen, möglicherweise um eine physische Kamera zu simulieren. Wenn Sie dies vor einem Upscaler tun, kann es sein, dass der Upscaler das Rauschen verstärkt, was zu unerwünschten Artefakten im resultierenden hochskalierten Bild führt. Die folgende Tabelle unterteilt gängige Echtzeit-Bildraumtechniken in zwei Spalten. „Nachbearbeitung A“ enthält alle Techniken, die normalerweise vor der Hochskalierung von FSR2 ausgeführt werden, was bedeutet, dass sie alle mit Renderauflösung ausgeführt werden. Umgekehrt enthält die Spalte „Nachbearbeitung B“ alle Techniken, deren Ausführung nach FSR2 empfohlen wird, was bedeutet, dass sie mit der größeren Präsentationsauflösung ausgeführt werden.
Nachbearbeitung A | Nachbearbeitung B |
---|---|
Bildschirmspiegelungen | Filmkörnung |
Umgebungsokklusion im Bildschirmbereich | Chromatische Aberration |
Rauschunterdrücker (Schatten, Reflexionen) | Vignette |
Belichtung (optional) | Tonemapping |
Blühen | |
Schärfentiefe | |
Bewegungsunschärfe |
Bitte beachten Sie, dass die Empfehlungen hier nur Orientierungszwecken dienen und von den genauen Merkmalen der Implementierung Ihrer Anwendung abhängen.
Während es möglich ist, die entsprechenden Zwischenressourcen zu generieren, den Shader-Code zu kompilieren, die Bindungen festzulegen und die Dispatches zu übermitteln, ist es viel einfacher, die bereitgestellte FSR2-Host-API zu verwenden.
Um die API zu verwenden, sollten Sie die FSR2-Bibliotheken verknüpfen (mehr dazu in Kürze) und die Header-Datei ffx_fsr2.h
einschließen, die wiederum die folgenden Header-Abhängigkeiten aufweist:
ffx_assert.h
ffx_error.h
ffx_fsr2_interface.h
ffx_types.h
ffx_util.h
Um die FSR2-API zu verwenden, sollten Sie ffx_fsr2_api_x64.lib
verknüpfen, das die Symbole für die anwendungsorientierten APIs bereitstellt. Die API von FSR2 verfügt jedoch über ein modulares Backend, was bedeutet, dass durch die Verwendung eines passenden Backends verschiedene Grafik-APIs und Plattformen angesprochen werden können. Daher sollten Sie zusätzlich die Backend-Bibliothek einschließen, die Ihren Anforderungen entspricht, und dabei auf die Tabelle unten verweisen.
Ziel | Bibliotheksname |
---|---|
DirectX(R)12 | ffx_fsr2_dx12_x64.lib |
Vulkan(R) | ffx_fsr2_vk_x64.lib |
Bitte beachten Sie, dass die modulare Architektur der FSR2-API die Implementierung benutzerdefinierter Backends ermöglicht. Weitere Einzelheiten finden Sie im Abschnitt „Modulares Backend“.
Um mit der Verwendung der API zu beginnen, sollte die Anwendung zunächst eine FfxFsr2Context
-Struktur erstellen. Diese Struktur sollte sich an einem Ort befinden, dessen Lebensdauer in etwa der Ihres Backbuffers entspricht. Irgendwo auf dem Heap der Anwendung ist normalerweise eine gute Wahl. Durch den Aufruf ffxFsr2ContextCreate
wird die FfxFsr2Context
-Struktur mit den erforderlichen Daten gefüllt. Darüber hinaus erfolgt eine Reihe von Aufrufen von ffxFsr2ContextCreate
an das Backend, das FfxFsr2Context
als Teil der FfxFsr2ContextDescription
-Struktur bereitgestellt wird. Diese Aufrufe führen Aufgaben wie das Erstellen von Zwischenressourcen aus, die für FSR2 erforderlich sind, und das Einrichten von Shader und dem zugehörigen Pipeline-Status. Die FSR2-API führt keine dynamische Speicherzuweisung durch.
Für jeden Frame Ihrer Anwendung, in dem eine Hochskalierung erforderlich ist, sollten Sie ffxFsr2ContextDispatch
aufrufen. Diese Funktion akzeptiert die FfxFsr2Context
Struktur, die früher in der Lebensdauer der Anwendung erstellt wurde, sowie eine Beschreibung, wie genau die Hochskalierung durchgeführt werden soll und für welche Daten. Diese Beschreibung wird von der Anwendung bereitgestellt, die eine FfxFsr2DispatchDescription
-Struktur ausfüllt.
Das Zerstören des Kontexts erfolgt durch Aufrufen von ffxFsr2ContextDestroy
. Bitte beachten Sie, dass die GPU inaktiv sein sollte, bevor Sie versuchen, ffxFsr2ContextDestroy
aufzurufen, und dass die Funktion keine implizite Synchronisierung durchführt, um sicherzustellen, dass Ressourcen, auf die FSR2 zugreift, derzeit nicht in Betrieb sind. Der Grund für diese Wahl besteht darin, zu vermeiden, dass FSR2 zusätzliche GPU-Flushes für Anwendungen einführt, die an dem Punkt, an dem sie möglicherweise den FfxFsr2Context
zerstören möchten, bereits eine angemessene Synchronisierung durchführen. Dadurch kann eine Anwendung die FSR2-API so effizient wie möglich erstellen und abbauen, wenn erforderlich.
Es gibt zusätzliche Hilfsfunktionen, die als Teil der FSR2-API bereitgestellt werden. Diese Hilfsfunktionen führen Aufgaben wie die Berechnung von Subpixel-Jitter-Offsets sowie die Berechnung von Rendering-Auflösungen basierend auf Dispatch-Auflösungen und den von FSR2 bereitgestellten Standard-Skalierungsmodi aus.
Eine ausführlichere Dokumentation der FSR2-API finden Sie in der bereitgestellten API-Referenzdokumentation.
Das Design der FSR2-API bedeutet, dass die Kernimplementierung des FSR2-Algorithmus nicht weiß, auf welcher Rendering-API sie sitzt. Stattdessen ruft FSR2 Funktionen auf, die ihm über eine Schnittstelle bereitgestellt werden, sodass verschiedene Backends mit FSR2 verwendet werden können. Dieses Design ermöglicht es Anwendungen, die FSR2 integrieren, auch, ihre eigene Backend-Implementierung bereitzustellen, was bedeutet, dass Plattformen, die FSR2 derzeit nicht unterstützt, durch die Implementierung einer Handvoll Funktionen angegriffen werden können. Darüber hinaus können Anwendungen, die über eigene Rendering-Abstraktionen verfügen, auch ihr eigenes Backend implementieren und so die Kontrolle über alle Aspekte der zugrunde liegenden Funktion von FSR2 übernehmen, einschließlich Speicherverwaltung, Ressourcenerstellung, Shader-Kompilierung, Shader-Ressourcenbindungen und die Übermittlung von FSR2-Workloads an das Grafikgerät .
Standardmäßig wird die FSR2-API in mehrere Bibliotheken kompiliert, wobei die bereits beschriebene Trennung zwischen der Kern-API und den Backends erfolgt. Das heißt, wenn Sie die mit FSR2 bereitgestellten Backends verwenden möchten, sollten Sie sowohl die FSR2-API-Kernbibliothek als auch das Ihren Anforderungen entsprechende Backend verknüpfen.
Die öffentliche Version von FSR2 enthält DirectX(R)12- und Vulkan(R)-Backends, andere Backends sind jedoch auf Anfrage erhältlich. Weitere Informationen erhalten Sie von Ihrem AMD Developer Technology-Vertreter.
Wenn die FSR2-API mit einem der bereitgestellten Backends (z. B. DirectX(R)12 oder Vulkan(R)) verwendet wird, werden alle von FSR2 benötigten Ressourcen als festgeschriebene Ressourcen direkt über das von der Hostanwendung bereitgestellte Grafikgerät erstellt. Durch Überschreiben der in der Backend-Schnittstelle vorhandenen Funktionsfamilie „Erstellen“ und „Zerstören“ ist es einer Anwendung jedoch möglich, die Speicherverwaltung von FSR2 präziser zu steuern.
Dazu können Sie FSR2 entweder über die an die Funktion ffxFsr2ContextCreate
übergebene FfxFsr2ContextDescription
-Struktur ein vollständiges benutzerdefiniertes Backend bereitstellen oder Sie können das Backend für Ihre gewünschte API abrufen und die Funktionen zur Ressourcenerstellung und -zerstörung überschreiben, um sie selbst zu verwalten. Überschreiben Sie dazu einfach die Funktionszeiger fpCreateResource
und fpDestroyResource
.
// Setup DX12 interface.
const size_t scratchBufferSize = ffxFsr2GetScratchMemorySizeDX12();
void * scratchBuffer = malloc(scratchBufferSize);
FfxErrorCode errorCode = ffxFsr2GetInterfaceDX12(&contextDescription.callbacks, m_pDevice-> GetDevice (), scratchBuffer, scratchBufferSize);
FFX_ASSERT (errorCode == FFX_OK);
// Override the resource creation and destruction.
contextDescription.callbacks.createResource = myCreateResource;
contextDescription.callbacks.destroyResource = myDestroyResource;
// Set up the context description.
contextDescription.device = ffxGetDeviceDX12(m_pDevice-> GetDevice ());
contextDescription.maxRenderSize.width = renderWidth;
contextDescription.maxRenderSize.height = renderHeight;
contextDescription.displaySize.width = displayWidth;
contextDescription.displaySize.height = displayHeight;
contextDescription.flags = FFX_FSR2_ENABLE_HIGH_DYNAMIC_RANGE
| FFX_FSR2_ENABLE_DEPTH_INVERTED
| FFX_FSR2_ENABLE_AUTO_EXPOSURE;
// Create the FSR2 context.
errorCode = ffxFsr2ContextCreate(&context, &contextDescription);
FFX_ASSERT (errorCode == FFX_OK);
Ein interessanter Vorteil einer Anwendung, die die Kontrolle über die für FSR2 erforderliche Speicherverwaltung übernimmt, besteht darin, dass möglicherweise ein Ressourcen-Aliasing durchgeführt wird, was zu einer Speichereinsparung führen kann. Die Tabelle unter „Speicheranforderungen“ zeigt die Einsparungen, die durch die Verwendung dieser Technik möglich sind. Um die in dieser Tabelle gezeigten Einsparungen zu realisieren, sollte ein geeigneter Speicherbereich gefunden werden, der mit den für FSR2 erforderlichen Alias-Ressourcen gemeinsam genutzt werden kann – dessen Inhalte nicht erforderlich sind, um einen Aufruf an die FSR2-Dispatches überdauern zu können. Jeder FfxFsr2CreateResourceFunc
Aufruf, der von der FSR2-Kern-API über die FSR2-Backend-Schnittstelle durchgeführt wird, enthält eine Reihe von Flags als Teil der FfxCreateResourceDescription
-Struktur. Wenn FFX_RESOURCE_FLAGS_ALIASABLE
im flags
-Feld festgelegt ist, bedeutet dies, dass die Ressource sicher mit anderen Ressourcen im Rendering-Frame verknüpft werden kann.
Temporales Antialiasing (TAA) ist eine Technik, die die Ausgabe früherer Frames nutzt, um aus dem aktuellen Frame eine Ausgabe mit höherer Qualität zu erstellen. Da FSR2 ein ähnliches Ziel verfolgt – allerdings mit dem zusätzlichen Ziel, auch die Auflösung des gerenderten Bildes zu erhöhen – ist es nicht mehr erforderlich, einen separaten TAA-Durchgang in Ihre Anwendung aufzunehmen.
FSR2 ist darauf angewiesen, dass die Anwendung beim Rendern Subpixel-Jitter anwendet – dieser ist normalerweise in der Projektionsmatrix der Kamera enthalten. Um die Anwendung von Kamera-Jitter zu vereinfachen, stellt die FSR2-API eine kleine Reihe von Hilfsfunktionen bereit, die den Subpixel-Jitter-Offset für einen bestimmten Frame innerhalb einer Folge separater Jitter-Offsets berechnet.
int32_t ffxFsr2GetJitterPhaseCount ( int32_t renderWidth, int32_t displayWidth);
FfxErrorCode ffxFsr2GetJitterOffset ( float * outX, float * outY, int32_t jitterPhase, int32_t sequenceLength);
Intern implementieren diese Funktionen eine Halton[2,3]-Sequenz [Halton]. Ziel der Halton-Sequenz ist es, räumlich getrennte Punkte bereitzustellen, die den verfügbaren Raum abdecken.
Es ist wichtig zu verstehen, dass die von ffxFsr2GetJitterOffset
zurückgegebenen Werte im Einheitspixelraum vorliegen. Um diese korrekt in eine Projektionsmatrix zusammenzusetzen, müssen wir sie in Projektionsoffsets konvertieren. Das obige Diagramm zeigt ein einzelnes Pixel im Einheitspixelraum und im Projektionsraum. Die folgende Codeliste zeigt, wie der Subpixel-Jitter-Offsetwert korrekt in einer Projektionsmatrix zusammengesetzt wird.
const int32_t jitterPhaseCount = ffxFsr2GetJitterPhaseCount(renderWidth, displayWidth);
float jitterX = 0 ;
float jitterY = 0 ;
ffxFsr2GetJitterOffset (&jitterX, &jitterY, index, jitterPhaseCount);
// Calculate the jittered projection matrix.
const float jitterX = 2 . 0f * jitterX / ( float )renderWidth;
const float jitterY = - 2 . 0f * jitterY / ( float )renderHeight;
const Matrix4 jitterTranslationMatrix = translateMatrix(Matrix3::identity, Vector3(jitterX, jitterY, 0 ));
const Matrix4 jitteredProjectionMatrix = jitterTranslationMatrix * projectionMatrix;
Jitter sollte auf alle Renderings angewendet werden. Dazu gehören undurchsichtige, alphatransparente und Raytracing-Objekte. Bei gerasterten Objekten können die von der Funktion ffxFsr2GetJitterOffset
berechneten Subpixel-Jitterwerte auf die Kameraprojektionsmatrix angewendet werden, die letztendlich zur Durchführung von Transformationen während der Scheitelpunktschattierung verwendet wird. Beim Raytracing-Rendering sollte der Subpixel-Jitter auf den Ursprung des Strahls angewendet werden – häufig auf die Position der Kamera.
Unabhängig davon, ob Sie sich für die empfohlene ffxFsr2GetJitterOffset
-Funktion oder Ihren eigenen Sequenzgenerator entscheiden, müssen Sie das Feld jitterOffset
der FfxFsr2DispatchDescription
-Struktur festlegen, um FSR2 über den Jitter -Offset zu informieren, der angewendet wurde, um jeden Frame zu rendern. Wenn Sie die empfohlene ffxFsr2GetJitterOffset
-Funktion nicht verwenden, sollte darauf geachtet werden, dass Ihre Jitter -Sequenz niemals einen Nullvektor generiert. Das ist Wert von 0 sowohl in den x- als auch in y -Dimensionen.
Die folgende Tabelle zeigt die Jitter -Sequenzlänge für jeden der Standardqualitätsmodi.
Qualitätsmodus | Skalierungsfaktor | Sequenzlänge |
---|---|---|
Qualität | 1,5x (pro Dimension) | 18 |
Ausgewogen | 1,7x (pro Dimension) | 23 |
Leistung | 2,0x (pro Dimension) | 32 |
Ultra -Leistung | 3,0x (pro Dimension) | 72 |
Brauch | [1..n] x (pro Dimension) | ceil(8 * n^2) |
Die meisten Anwendungen mit Echtzeit-Rendering haben ein großes Maß an zeitlicher Konsistenz zwischen zwei beliebigen aufeinanderfolgenden Rahmen. Es gibt jedoch Fälle, in denen eine Änderung der Transformation einer Kamera zu einer abrupten Änderung dessen führen kann. In solchen Fällen ist es unwahrscheinlich, dass FSR2 alle Daten, die sie aus früheren Frames angesammelt haben, wiederverwenden können, und sollten diese Daten so löschen, dass sie sie von der Berücksichtigung des Kompositionsprozesses ausschließen. Um FSR2 anzuzeigen, dass ein Sprungschnitt mit der Kamera aufgetreten ist, sollten Sie das reset
-Feld der FfxFsr2DispatchDescription
-Struktur auf den ersten Rahmen der diskontinuierlichen Kamera -Transformation true
.
Die Rendering-Leistung kann bei Verwendung des Reset-Flags etwas weniger als typischer Rahmenbetrieb betragen, da FSR2 zusätzliche interne Ressourcen löscht.
Durch die Anwendung einer negativen MIPMAP -Verzerrung werden normalerweise ein hochkaltiges Bild mit besseren Texturdetails erzeugt. Wir empfehlen, die folgende Formel auf Ihre MIPMAP -Voreingenommenheit anzuwenden:
mipBias = log2(renderResolution/displayResolution) - 1.0 ;
Es wird vermutet, dass Anwendungen die MIP-Vorspannung für spezifische Hochfrequenz-Texturinhalte anpassen, die anfällig für die Anzeige zeitlicher Aliasingprobleme sind.
Die folgende Tabelle zeigt den MIPMAP -Verzerrungsfaktor, der sich aus der Bewertung des obigen Pseudocode für die Skalierungsverhältnisse ergibt, die den vorgeschlagenen Qualitätsmodi entsprechen, die Anwendungen den Endbenutzern aussetzen sollten.
Qualitätsmodus | Skalierungsfaktor | MIPMAP -Vorspannung |
---|---|---|
Qualität | 1,5x (pro Dimension) | -1.58 |
Ausgewogen | 1,7x (pro Dimension) | -1.76 |
Leistung | 2,0x (pro Dimension) | -2.0 |
Ultra -Leistung | 3,0x (pro Dimension) | -2.58 |
Die FSR2 -API erfordert, dass frameTimeDelta
durch die Anwendung über die FfxFsr2DispatchDescription
-Struktur bereitgestellt wird. Dieser Wert liegt in Millisekunden : Wenn der Wert mit 60 fps ausgeführt wird, sollte der Wert bei 16,6 F liegen.
Der Wert wird innerhalb der zeitlichen Komponente der FSR 2-automatischen Expositionsfunktion verwendet. Dies ermöglicht die Einstellung der Geschichte der Geschichte für Qualitätszwecke.
Bilder mit hohem Dynamikbereich werden in FSR2 unterstützt. Um dies zu aktivieren, sollten Sie das Bit FFX_FSR2_ENABLE_HIGH_DYNAMIC_RANGE
im Feld FfxFsr2ContextDescription
in das Feld flags
festlegen. Im linearen Farbraum sollten Bilder an FSR2 zur Verfügung gestellt werden.
Die Unterstützung für zusätzliche Farbräume könnte in einer zukünftigen Überarbeitung von FSR2 bereitgestellt werden.
FSR2 wurde entwickelt, um die Hardwarebeschleunigung der Hälfte der Präzision (FP16) zu nutzen, um die höchstmögliche Leistung zu erzielen. Um jedoch die maximale Kompatibilität und Flexibilität für Anwendungen bereitzustellen, umfasst FSR2 auch die Möglichkeit, die Shader mit FP32 -Operationen (FP32) zu kompilieren.
Es wird empfohlen, die FP16 -Version von FSR2 für alle Hardware zu verwenden, die sie unterstützt. You can query your graphics card's level of support for FP16 by querying the D3D12_FEATURE_DATA_SHADER_MIN_PRECISION_SUPPORT
capability in DirectX(R)12 - you should check that the D3D[11/12]_SHADER_MIN_PRECISION_16_BIT
is set, and if it is not, fallback to the FP32 version of FSR2. Wenn VkPhysicalDeviceFloat16Int8FeaturesKHR::shaderFloat16
nicht festgelegt ist, sollten Sie die FP32 -Version von FSR2 fallen. Wenn VkPhysicalDevice16BitStorageFeatures::storageBuffer16BitAccess
nicht festgelegt ist, sollten Sie auch in die FP32 -Version von FSR2 zurückfallen.
Um den FP32 -Pfad im FSR2 -Shader -Quellcode zu aktivieren, sollten Sie FFX_HALF
auf 1
sein. Um den Großteil des Quellcode des Algorithmus sowohl zwischen FP16 als auch zwischen FP16 und FP32 zu teilen (um eine hohe Code -Freigabe zu gewährleisten, um die laufende Wartung zu unterstützen), werden Sie feststellen 16-Bit- und 32-Bit-Grundtypen in der Shader-Quelle.
FidelityFX -Typ | FP32 | FP16 |
---|---|---|
FFX_MIN16_F | float | min16float |
FFX_MIN16_F2 | float2 | min16float2 |
FFX_MIN16_F3 | float3 | min16float3 |
FFX_MIN16_F4 | float4 | min16float4 |
Die obige Tabelle zählt die Zuordnungen zwischen den abstrakten FidelityFX -SDK -Typen und dem unterlagenen intrinsischen Typ, der abhängig von der Konfiguration der Shaderquelle während der Kompilierung ersetzt wird.
Moderne GPUs führen Sammlungen von Threads aus - als Wellenfronten genannt - zusammen auf Simt -Weise. Die genaue Anzahl von Threads, die eine einzelne Wellenfront bilden, ist eine hardwarespezifische Menge. Einige Hardware wie GPUs-basierte GPUs von AMD unterstützen das Sammeln von 64 Threads in eine einzelne Wellenfront. Abhängig von den genauen Eigenschaften der Ausführung eines Algorithmus kann es mehr oder weniger vorteilhaft sein, eine bestimmte Wellenfrontbreite zu bevorzugen. Mit der Einführung von Shader Model 6.6 fügte Microsoft die Möglichkeit hinzu, die Breite einer Wellenfront über HLSL zu spezifizieren. Für Hardware wie rDNA, die sowohl 32- als auch 64 Wide -Wavefront -Breiten unterstützt, ist dies ein sehr nützliches Werkzeug für Optimierungszwecke, da es eine saubere und tragbare Möglichkeit bietet, den Treibersoftware -Stack zu bitten, eine Wellenfront mit einer bestimmten Breite auszuführen.
Für DirectX (R) -Basierte Anwendungen, die auf rDNA- und rDNA2-basierten GPUs ausgeführt werden, und mit der Microsoft Agility SDK wird die FSR2-Host-API eine 64-weite Wellenfrontbreite ausgewählt.
Die Kontextbeschreibungsstruktur kann mit einer Rückruffunktion zur Übergabe von Textwarnungen aus der Laufzeit FSR 2 an die zugrunde liegende Anwendung angegeben werden. Das fpMessage
-Mitglied der Beschreibung ist vom Typ FfxFsr2Message
, der ein Funktionszeiger für die Übergabe von Zeichenfolgennachrichten verschiedener Typen ist. Das Zuweisen dieser Variablen einer geeigneten Funktion und Übergabe des FFX_FSR2_ENABLE_DEBUG_CHECKING
-Flags innerhalb des Flags -Mitglieds von FfxFsr2ContextDescription
aktiviert die Funktion. Es wird empfohlen, dass dies nur in Debug -Entwicklung ermöglicht wird.
Ein Beispiel für die Art der Ausgabe, die auftreten kann, wenn der Checker mögliche Probleme beobachtet, finden Sie unten:
FSR2_API_DEBUG_WARNING: FFX_FSR2_ENABLE_DEPTH_INFINITE and FFX_FSR2_ENABLE_DEPTH_INVERTED present, cameraFar value is very low which may result in depth separation artefacting
FSR2_API_DEBUG_WARNING: frameTimeDelta is less than 1.0f - this value should be milliseconds (~16.6f for 60fps)
Der FSR2 -Algorithmus wird in einer Reihe von Phasen implementiert, die wie folgt sind:
Jede Passphase des Algorithmus ist in den folgenden Abschnitten festgelegt, der Datenfluss für den vollständigen FSR2 -Algorithmus ist jedoch im folgenden Diagramm angezeigt.
Die Rechenluminanzpyramidenstufe hat zwei Verantwortlichkeiten:
Die folgende Tabelle enthält alle Ressourcen, die von der Rechenluminanzpyramidenstufe konsumiert werden.
Die zeitliche Schicht gibt an, aus welchem Rahmen die Daten bezogen werden sollten. "Aktueller Rahmen" bedeutet, dass die Daten aus Ressourcen entnommen werden sollten, die für den als nächstes vorgestellten Rahmen erstellt werden sollen. 'Vorheriger Frame' zeigt an, dass die Daten aus Ressourcen bezogen werden sollten, die für den gerade vorgelegten Rahmen erstellt wurden. Die Spalte Auflösungsspalte gibt an, ob die Daten bei der Auflösung der "gerenderten" Auflösung oder "Präsentation" vorliegen sollten. Die Auflösung von 'gerenderter' zeigt, dass die Ressource mit der Auflösung übereinstimmt, bei der die Anwendung ihr Rendering durchführt. Umgekehrt zeigt 'Präsentation' an, dass die Lösung des Ziels dem Benutzer übereinstimmen sollte, was dem Benutzer präsentiert werden soll.
Name | Zeitschicht | Auflösung | Format | Typ | Notizen |
---|---|---|---|---|---|
Farbpuffer | Stromrahmen | Machen | APPLICATION SPECIFIED | Textur | Der Farbpuffer der Renderauflösung für den aktuellen Rahmen, der von der Anwendung bereitgestellt wird. Wenn sich der Inhalt des Farbpuffers in einem hohen Dynamic -Bereich (HDR) befindet, sollte das Flag FFX_FSR2_ENABLE_HIGH_DYNAMIC_RANGE im Feld FfxFsr2ContextDescription in das Feld flags eingestellt werden. |
Die folgende Tabelle enthält alle Ressourcen, die durch das Rechenluminanzpyramidenstadium erstellt oder modifiziert wurden.
Die zeitliche Schicht gibt an, aus welchem Rahmen die Daten bezogen werden sollten. "Aktueller Rahmen" bedeutet, dass die Daten aus Ressourcen entnommen werden sollten, die für den als nächstes vorgestellten Rahmen erstellt werden sollen. 'Vorheriger Frame' zeigt an, dass die Daten aus Ressourcen bezogen werden sollten, die für den gerade vorgelegten Rahmen erstellt wurden. Die Spalte Auflösungsspalte gibt an, ob die Daten bei der Auflösung der "gerenderten" Auflösung oder "Präsentation" vorliegen sollten. Die Auflösung von 'gerenderter' zeigt, dass die Ressource mit der Auflösung übereinstimmt, bei der die Anwendung ihr Rendering durchführt. Umgekehrt zeigt 'Präsentation' an, dass die Lösung des Ziels dem Benutzer übereinstimmen sollte, was dem Benutzer präsentiert werden soll.
Name | Zeitschicht | Auflösung | Format | Typ | Notizen |
---|---|---|---|---|---|
Belichtung | Stromrahmen | 1x1 | R32_FLOAT | Textur | Eine 1x1 -Textur, die den für den aktuellen Rahmen berechneten Belichtungswert enthält. Diese Ressource ist optional und kann weggelassen werden FfxFsr2ContextDescription wenn das Flag FFX_FSR2_ENABLE_AUTO_EXPOSURE im Feld flags beim Erstellen des FfxFsr2Context festgelegt wird. |
Aktuelle Luminanz | Stromrahmen | Render * 0.5 + Mipchain | R16_FLOAT | Textur | Eine Textur bei 50% der Textur der Renderauflösung, die die Luminanz des aktuellen Rahmens enthält. Eine vollständige MIP -Kette wird zugewiesen. |
Die Pyramidenstufe der Berechnung der Luminanz wird unter Verwendung von FidelityFX -Single -Pass -Downs implementiert