Ich habe dies bei StackOverflow gefragt , aber es könnte hier sinnvoller sein:
Hat jemand verzögertes Rendern / Shading unter OpenGL ES 2.0 implementiert? MRTs werden nicht unterstützt. Mit nur einem Farbpuffer kann dies also nicht auf die "übliche" Weise implementiert werden.
Insbesondere erkunde ich iPad, iPhone4 (möglicherweise iPhone 3gs) und Android. In der GLESView-App auf iPad / iPhone4 / iPhone3gs ist die GL_OES_RGB8_RGBA8-Erweiterung vorhanden, und ich habe noch nicht zu tief geschaut, aber bei 8 Bit / Kanal ist diese Idee interessant: http://www.gamedev.net/topic/ 562138-opengl-es-20-and-latent-shading /
Irgendwelche anderen Ideen? Lohnt es sich überhaupt, dies in Bezug auf die Leistung zu tun?
android
ios
opengl-es2
Jim Buck
quelle
quelle
Antworten:
Ja, es ist möglich. Besonders lohnenswert ist es jedoch nicht.
Erstens können Framebuffer-Objekte unter ES 2.0 nur in einem Image gerendert werden, es sei denn, Sie haben Zugriff auf die Erweiterung NV_draw_buffers (wie der Name schon sagt, handelt es sich nur um NVIDIA) zu einer Zeit. Um Ihre G-Puffer zu generieren, müssen Sie Ihre Szene mehrmals rendern, wodurch einer der Vorteile des verzögerten Renderns wegfällt.
Zweitens ist die Bandbreite auf mobilen Plattformen nicht die gleiche wie auf GPUs mittlerer Qualität. Und Bandbreite ist entscheidend, damit sich verzögertes Rendern (für viele Lichter) lohnt. Ohne diese Bandbreite werden die Lichtpässe in Bezug auf die Leistung wirklich wehtun.
Drittens ist PowerVR-Hardware wirklich nicht für diese Art von Dingen ausgelegt. Es optimiert das Rendern mit seiner kachelbasierten Renderhardware. Daher wäre ein verzögertes Rendern darüber hinaus weniger hilfreich als in einer herkömmlichen Scan-Konvertierungsarchitektur.
quelle
Das Hauptproblem ist die Füllrate. Auf mobilen GPUs ist Ihre Füllrate niedrig, sodass Sie kein zeitversetztes Shading in Echtzeit mit nativer Auflösung durchführen können.
Bei iPhone 4 und iPad 1 ist die Füllrate einfach lächerlich. Das einzige IOS-Gerät mit guter Füllrate ist das iPad 2, aber ich bezweifle, dass es genug gibt ... Unter Android verfügen nur Tegra-Geräte über die GL_NV_draw_buffers, um MRT zu verwenden, aber die Füllrate ist auch sehr niedrig. Der Mali 400 scheint die beste Füllrate zu haben. Wenn Sie weinen möchten, versuchen Sie einfach, ein Farbrechteck mit 4-maliger Vollbildauflösung zu füllen ... Viele Geräte können es nicht mit 60 fps.
Auf Desktop-GPUs haben Sie eine 10-fache (oder höhere) Füllrate als auf Mobilgeräten. Vergessen Sie nicht, dass mobile GPUs denselben Arbeitsspeicher wie die CPU verwenden und Sie keinen dedizierten Arbeitsspeicher haben.
Es gibt einige Beispiele in WebGL (dieselbe API), damit die API nicht eingeschränkt wird.
quelle
Sie müssen sich wirklich überlegen, was das absolute Minimum ist, das Sie für einen verzögerten Renderer benötigen. Wenn Sie auf verzögertes Licht zurückgreifen, wird die Menge der Daten reduziert, die im GBuffer gespeichert werden müssen, und es ist wirklich eine Menge billiger als die Hälfte der Szene dreimal oder öfter zu rendern, um eine geringe Menge an Licht zu unterstützen.
Ich würde für das folgende GBuffer-Format gehen:
Die verzögerte Beleuchtung ähnelt dem verzögerten Rendern, mit der Ausnahme, dass Sie die Szene zweimal rendern:
Informationen zum Speichern der Beleuchtungsergebnisse. Ich habe es geliebt, diffuse Farbe und spiegelnde Luminanz zu speichern, so dass der Akkumulationspuffer nur eine standardmäßige 32-Bit-Farbtextur sein muss. Sie können die Spiegelfarbe abschätzen, indem Sie die Farbsättigung der diffusen Farbe berechnen und diese mit der Spiegelhelligkeit kombinieren.
Das Wichtigste ist jedoch, den Tiefenschablonenpuffer so gut wie möglich zu nutzen. Stellen Sie sicher, dass Sie keinen der Lichtcodes rendern, die nicht benötigt werden. Ich würde sogar so weit gehen, den Fragment-Shadern einige Discard-Anweisungen hinzuzufügen, die die Sichtbarkeit des Lichts unter den Anzeigebereich des Geräts senken (1e-3 ist normalerweise ein sicherer Grenzwert).
quelle
discard
ist wirklich sehr, sehr schlecht für kachelbasierte Pipelines, die von vielen / den meisten mobilen GPUs verwendet werden.Erwägen Sie eine verzögerte Beleuchtung. Kurz gesagt, die verzögerte Beleuchtung ist eine Technik, bei der eine reduzierte Version der verzögerten Schattierung verwendet wird, um eine Lightmap für den Bildschirmbereich zu berechnen. In einem zweiten Durchgang wird die Geometrie unter Verwendung der Screenspace-Lightmap als Beleuchtungsinformation erneut gerendert.
Diese Technik wird verwendet, um die Größe des G-Puffers zu reduzieren, da weniger Attribute benötigt werden. Sie haben auch den Vorteil, dass der G-Buffer und die Screenspace-Lightmap eine geringere Auflösung als der Bildschirm haben können.
Ich hatte einen strengen GLES 2.0-basierten Renderer implementiert (obwohl ein experimenteller) und es gelang mir, den G-Buffer auf eine RGBA-Textur zu reduzieren (ja, ich habe eine texture2D anstelle eines Renderbuffers verwendet). Es enthielt die normale Karte des Bildschirmbereichs + den Tiefenpuffer im Alphakanal (der, soweit ich mich erinnere, mit einem Logarithmus komprimiert wurde).
Die Position Attribute ( so genannte Welt hier) während der Beleuchtung Passes mit der Tatsache berechnet werden, dass in einem perspectivic Vorsprung, .xy durch geteilt wird .z , so dass:
Ich habe das xy des Positionsattributs wie folgt approximiert :
Hinweis: Ich musste abhängig von den Einstellungen der Projektionsmatrix weitere Anpassungen vornehmen.
Bemerkenswert ist auch, dass ich die .z- Komponente der normalen Vektoren weglassen konnte, da ich .z aus .xy rekonstruieren konnte, da der normale Vektor normalisiert ist, so dass:
Mit dieser Technik konnte ich einen anderen Kanal in meinem RGBA G-Buffer freigeben und damit die spiegelnde Bildschirmkarte (oder, wenn Sie so wollen, den Glanz) speichern.
quelle
Ja, das ist absolut möglich. Die Füllrate ist kein Problem, da mobile Grafikchips für Bildschirme mit sehr hoher Auflösung ausgelegt sind. Das verzögerte Rendern hilft dabei, da Ihre Beleuchtungsberechnung unabhängig von der Komplexität der Szene ist, sodass ein Überzeichnen keine Verlangsamung verursacht. Hier ist meine Implementierung auf einem iPad der vierten Generation: http://www.youtube.com/watch?v=K4X1oF6b4V8
Wenn Sie die vierfache Leistung erzielen möchten, benötigen Sie nur die Hälfte der Auflösung der Textur, auf die Sie rendern. Bei 3D-Grafiken auf einem Retina-Bildschirm kann ich sowieso keinen Unterschied feststellen.
Mobile Grafikchips eignen sich aufgrund der Art und Weise, wie sie Render-to-Texture verarbeiten, hervorragend für verzögertes Rendern. Im Gegensatz zu PC-Grafikkarten, die normalerweise einen großen Leistungseinbruch erleiden, wenn Sie beginnen, eine Textur anstelle eines Fensterkontexts zu rendern, sind mobile Grafiken so konzipiert, dass sie keine Leistungseinbußen verursachen. So erhalten Sie die Skalierbarkeit eines verzögerten Renderers, ohne die anfängliche Leistungseinbuße, die Sie bei einer Desktop-Grafikkarte erleben.
Zum Zeitpunkt meiner Implementierung fehlte OpenGLES das Rendern für mehrere Ziele, sodass ich die Bildschirmfarbe und die Normalfarbe in separaten Durchgängen zeichnen musste. Dies kann in neueren Versionen von OpenGLES behoben werden, weiß aber nicht, ob die Lösungen noch in mobiler Consumer-Hardware verfügbar sind.
quelle