Seite 1 von 1

Deferred rendering - Segen oder Fluch?

Verfasst: 05.02.2015, 13:53
von Zudomon
Das Problem ist ein einfaches, aber der Weg dahin scheint schwierig.

Ich würde gerne Füllrate sparen
Ich würde gerne Blut oder sonstiges im Screenspace über projizierte Sprites auftragen.
Ich würde bestimmt noch gerne viele andere Dinge machen, aber das ist gar nicht so einfach Möglich.

Zur Zeit speichere ich bein Deffered Rendering:
RT1 (RGBA 8) = Tex R | Tex G | Tex B | SSS
RT2 (RGBA 16) = Nor X | Nor Y | Nor Z | Depth
RT3 (RGBA 8) = Wetness | Reflection

Prinzipiell funktioniert das ganze sehr gut, aber würde z.B. bei projizierten Sprites versagen.
Warum?
Der Grund ist simpel: Weil die Positionen, die rekonstruiert werden, zwar im Worldspace vorliegen, aber NACH der Transformation im VertexShader.
Das Bedeutet, wenn z.B. eine Pflanze ein projiziertes Sprite erhält, diese aber vorher durch Wind verbogen wird, dann nutzt das Sprite die finalen Weltkoordinaten. Somit sieht es in Bewegungn so aus, als ob die Pflanze an dem Sprite vorbei huscht, weil das Sprite ja fest im Raum positioniert ist.

Die Frage ist, was kann man dagegen tun? Die Position durch "Depth" zu Rekonstruieren funktioniert nur, weil man auf die Pixel X Y Koordinaten des Screens zurück greifen kann. Möchte man aber nun eine willkürliche Raumkoordinate mitspeichern, so muss man schon X Y Z speichern, welches dann noch blöderweise auch in 32 Bit sein sollte, weil 16 Bit da nicht ausreicht. Das wiederum finde ich extreme Verschwendung, weil ich den ganzen Rest ja eigengtlich recht "Sparsam" unterkriege.

Habt ihr eine Idee, was man da am besten machen könnte um doch noch im Screenspace an die ursprünglichen Weltkoordinaten zu kommen?

Re: Deferred rendering - Segen oder Fluch?

Verfasst: 05.02.2015, 14:45
von Schrompf
Dein Problem mit Decals auf shader-verzerrten Dreiecken ist keins mit Deferred oder Forward Renderer, wenn ich das richtig verstanden habe. Wenn Du eine XYZ ausrendern wollen würdest, müsstest Du für dieses Problem die unverzerrte XYZ ausrendern, als ob die Pflanze unbewegt wäre- Und das würde sich dann wieder in der Beleuchtung und Schattierung zeigt - der Schatten der Sonne würde sich dann mit der Pflanze mitbiegen, was hinreichend komisch aussehen dürfte. Die Lösung für dieses Problem wäre, die Decals auf den shader-verzerrten Pflanzen identisch mitzuverzerren. Egal ob Deferred oder Forward.

Was die Füllraten-Problematik angeht, verstehe ich Dein Problem gut. Ich hatte bei Splatter das gleiche Problem - wenn ich die Schatten oder indirekte Beleuchtung weit genug runtergeregelt habe, wurde irgendwann die additiven Passes für alle Lichtquellen zum Flaschenhals. Und das war eine Art untere Grenze an Leistungsanforderung, die für viele Onboard-GPUs immernoch zu hoch lag. I'm looking at you, Intel.

Wenn man die ganzen Schatten usw. rausgerechnet hat, was war dann eigentlich der neue Flaschenhals? Das bisschen Mathe für die Beleuchtung war es sicher nicht. Stattdessen hatte ich die Textursamples und das Blending im Auge, hab es aber auf den Intel-Tools nie nachprüfen können. Wenn es aber die drei Textursamples und das Blending auf einem FP16-Rendertarget waren, dann wäre die einzige Lösung dafür, die Anzahl Passes pro Pixel zu senken. Also pro FragmentShader-Durchlauf mehrere Lichtquellen auf einmal zu berechnen und so die Kosten für das Auslesen der GBuffer-Attribute und das Sampling auf mehrere Lichtquellen zu verteilen.

An dieser Stelle setzen die sogenannten Tiled Renderer an. Die gibt es in den Geschmacksrichtungen Tiled Deferred Renderer und Tiled Forward Renderer. In Kurzform: man unterteilt den Bildschirm in quadratische Häppchen, die so groß sind, dass deren komplette Daten bequem in die Textur- und Rendertarget-Caches passen. Für ne aktuelle Gamer-GPU wäre das wohl mindestens 32x32, eher noch 64x64, weil die großen GPUs ja schon mehr Shader-Pipelines eingebaut haben, als überhaupt Pixel im Tile sind. Auf kleinen GPUs wie den Intel-Gurken dürfte eher 8x8 das Gebot der Stunde sein. Ist aber wieder nur Vermutung. Pro Tile bestimmt man jetzt die Lichtquellen, die das Volumen des Tiles bestimmen, und packt deren Indizes in irgendeinen Buffer. Jetzt kann man pro Tile ein Quad rendern, in dem der FragmentShader jeweils alle Lichtquellen in einem Aufwasch macht. Erspart (AnzLichtquellen minus Eins) mal Samples auf dem GBuffer und Blending, macht aber dafür zusätzlichen Aufwand zur Bestimmung der betroffenen Lichtquellen und eine gewisse Menge unnötig berechneter Lichtquellenpixel.

Man müsste wahrscheinlich sehr klug Array-Indizes im GeometrieShader schubsen, damit die Bestimmung und der Upload der LichtIndizes pro Segment nicht alle Performance auffrisst, die man beim Shading spart.

Re: Deferred rendering - Segen oder Fluch?

Verfasst: 05.02.2015, 15:04
von Zudomon
Danke für die ausführliche Antwort. Da sind einige Informationen, die ich mir mal im Hinterkopf behalte.

Was allerdings deine Lösung bzgl. des mitverzerrens angeht, so wird das nicht klappen. Die Pflanze ist ja nicht das einzige, was von dem Sprite beeinflusst sein soll, sondern eben alles, was dann natürlich auch etliches an anderer Vegetation sein könnte.
Auch was die Nässe bei regen angeht, da habe ich das gleiche Problem. Diese wird erst im ScreenSpace aufgetragen, um da dann auf die Beleuchtung einzugehen. Dafür muss ich dann allerdings einen Nässe Wert mitgeben, den ich beim rendern der Geometrie mit gebe.

Schade, als ich las, dass mein Problem eigenlich keins ist, hatte ich gedacht:"Puh zum Glück!" :D
Aber wenn ich das jetzt nicht falsch verstanden habe, dann ist das Problem noch nicht gelöst.

Re: Deferred rendering - Segen oder Fluch?

Verfasst: 05.02.2015, 16:04
von Schrompf
Nein, das Nässe- oder Decal-Problem auf bewegter Geometrie ist nicht gelöst. Ich sagte nur, dass es unabhängig von Deferred oder Forward Renderer ist :-)

Du splattest ein Decal auf den Boden. Eine Pflanze wird davon erfasst. Wenn die Pflanze sich jetzt im Wind hin- und herwiegt, bewegt sie sich quasi unter dem Decal hin und her - das sieht dann so aus, als würde das Decal auf der Pflanze hin- und herrutschen. Das kannst Du nur vermeiden, indem Du für diese konkrete Pflanze dedizierte Geometrie erzeugst, die sich mit der Pflanze mitbewegt. Das bedeutet natürlich auch, dass Du für die Pflanze daneben *eigene* Geometrie erzeugen musst, die dann deren Bewegung mitmacht. Oder Du renderst alle Meshes, die von einem Decal betroffen sind, separat aus und berechnest die Texturkoordinaten auf dem Decal im VertexShader anhand der unbewegten Geometrie. Beide Methoden bedeuten auf jeden Fall einen separaten DrawCall, was ne richtig doofe Sache ist. Sorry.

Re: Deferred rendering - Segen oder Fluch?

Verfasst: 05.02.2015, 19:24
von Sternmull
Naja, ich würde schon denken das man hier (beim Problem Decals für dynamische Objekte) mit einem Forward-Renderer besser/intuitiver vorgehen kann. Dort hat man die Chance das Decal im Object-Space zu erfassen (also in diesen zu transformieren) und es anschließend auch auf diesen zu mappen, egal wie der später transformiert und verzerrt wird. Bei den Deferred-Renderer-Technicken fehlt einem diese Information ja üblicherweise (man kann ja schlecht für jedes Objekt noch einen zusätzlichen Puffer anlegen und mit den Objekt-lokalen Koordinaten befüllen).