PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Klassisches Rendering vs Raytracing


neustadt
2010-08-29, 21:39:18
Hallo,

ich setzt mich gerade zum ersten mal so richtig mit Bildsysthese auseinander und würde gerne die genauen Unterschiede zwischen klassischem Rendering und Raytracing verstehen.

Zur Zeit verstehe ich Rendern, als Zusammenfassung der Schritte: Anwendung, Geometrie und Rasterung.
Raytracing verstehe ich als Verfahren zur Sichtbarkeit und Farbberechnung von Pixeln aus Sicht der Kammera. So wie ich das sehe: Dem Part der beim klassischen Rendern durch shading berechnet wird. Also nur ein kleiner Part des gesamten Renderns.
Rasterisierung verstehe ich als Umwandlung der Primitive in Pixel mit passendem Farbwert.

Wenn ich nun Sätze lese wie: "Alle aktuellen Spiele benutzen derzeit eine Renderingtechnologie namens „Rasterisierung“." (Raytracing in Spielen 3.0 (http://www.computerbase.de/artikel/grafikkarten/2009/bericht-quake-wars-mit-raytracing/2/)) Stellen sich mir folgende Fragen:
Kann Raytracing doch mehr als nur Verdeckungsberechnung oder wird Rendering und Rasterisierung häufig in einen Topf geworfen?
Wieso muss beim Raytracing nicht rasterisiert werden? Raytracing verwendet doch ebenfalls Primitive als Ausgangsobjekte und die sind doch immer vektorbasiert.

:uconf2:

So wie ich Raytracing bis jetzt verstehe kann daraus nur dann eine Engine entwickelt werden, wenn sie mit dem klassischen Rendern kombiniert wird. Aber irgendwie hat sich das früher beim Lesen von Artikeln immer anders angehört.
Wäre schön wenn mich jemand aufklären könnte. :smile:

Monger
2010-08-29, 22:02:43
Kurz: das Gegenteil von Rasterisierung ist Raytracing.

Rasterisierung berechnet den Farbwert jedes Pixels dadurch, dass einem Objekt eine bestimmte Farbe gegeben wird. Der aktuelle Viewport wird dann von hinten nach vorne nacheinander mit allen Objekten übermalt, bis man das vollständige Bild hat. Vorteil: relativ einfache mathematische Berechnungen, lässt sich gut und einfach parallelisieren. Nachteil: die gesamte Szene muss bekannt und geladen sein.

Raytracing funktioniert so, dass von jedem Pixel des Viewports aus ein Lichtstrahl losgeschickt wird, bis er auf eine Oberfläche trifft. Wenn diese wenigstens eine Farbe reflektiert (sprich: sie ist nicht schwarz), wird auch die Reflektion berechnet, so lange bis der Strahl auf eine Lichtquelle trifft. Von da aus gesehen wird dann auf umgekehrtem Wege die Farbe des Pixels berechnet.

Vorteil: Sehr effizient und präzise, weil genau das berechnet wird was tatsächlich zur Entstehung dieses Bildes notwendig ist. Nachteil: lässt sich schlecht optimieren, und ist in bestimmten Szenarien grottenlangsam.

In der Realität sind die Grenzen ohnehin nicht mehr so scharf. Shader sind im Endeffekt auch nichts anderes, als der Versuch die Vorteile des Raytracens mit der Rasterisierung zu verheiraten.

Edit: Rendern heißt erstmal nichts anderes als "Zeichnen". Darunter sind also alle Verfahren zusammengefasst, die irgendwas auf den Monitor malen.

Coda
2010-08-29, 22:28:03
Weder zeichnet man bei Rasterisierung zwangsläufig von vorne nach hinten, noch verfolgt man bei Raytracing Strahlen "solange bis sie auf eine Lichtquelle" treffen.

Shader sind im Endeffekt auch nichts anderes, als der Versuch die Vorteile des Raytracens mit der Rasterisierung zu verheiraten.
Bullshit.

Spasstiger
2010-08-29, 22:33:40
Beim Echtzeit-Raytracing werden in der Regel schon direkt nach der ersten Reflektion die Strahlen zu den Lichtquellen "geschossen". Wenn sich auf dem Weg einer dieser Strahlen ein Hindernis befindet, ist der Beitrag von diesem Strahl zum Pixel schwarz.

Monger
2010-08-29, 23:23:38
Weder zeichnet man bei Rasterisierung zwangsläufig von vorne nach hinten

Ja, ich weiß. Stencil Shadows und so.


, noch verfolgt man bei Raytracing Strahlen "solange bis sie auf eine Lichtquelle" treffen.

Ray=Strahl
Trace=verfolgen

Man verfolgt einen Strahl so lange, bis man dessen Quelle ausgemacht hat. Wenn das Ausgangsmaterial nichts emittiert, bleibt es dunkel.


Bullshit.
Weil?
Ich freue mich ja auf den Tag, wo du tatsächlich mal konstruktiv zu irgendeiner Diskussion beiträgst, statt nur zu flamen. Aber andere an deiner Weisheit teilhaben zu lassen, ist ja unter deiner Würde.

Coda
2010-08-30, 00:24:47
Ja, ich weiß. Stencil Shadows und so.
Nein, das hat nichts mit Stencil Shadows zu tun.

In der Regel rendert man heutzutage sogar grob von vorne nach hinten weil es viel effizienter ist.

Man verfolgt einen Strahl so lange, bis man dessen Quelle ausgemacht hat. Wenn das Ausgangsmaterial nichts emittiert, bleibt es dunkel.
Das ist korrekt, trotzdem wird nicht bis zur Lichtquelle verfolgt, sondern nur bis zum Material. Die Lichtberechnung des Materials erzeugt dann möglicherweise Sekundärstrahlen zu (beliebig vielen) Lichtquellen. Wenn man keine Schatten will braucht man diese aber nicht und macht einfach nur die Lichtberechnung.

Weil?
Dazu gibt's nichts zu sagen, es ist einfach kompletter Unsinn.

Ich freue mich ja auf den Tag, wo du tatsächlich mal konstruktiv zu irgendeiner Diskussion beiträgst, statt nur zu flamen.
Und ich freu mich auf den Tag, wenn du dich mit deinem Halbwissen zurückhältst.

Ich wollte am Anfang was zu dem Thema streiten, aber jetzt habe ich schon wieder keine Lust mehr.

Neomi
2010-08-30, 00:45:26
Rasterisierung berechnet den Farbwert jedes Pixels dadurch, dass einem Objekt eine bestimmte Farbe gegeben wird. Der aktuelle Viewport wird dann von hinten nach vorne nacheinander mit allen Objekten übermalt, bis man das vollständige Bild hat. Vorteil: relativ einfache mathematische Berechnungen, lässt sich gut und einfach parallelisieren. Nachteil: die gesamte Szene muss bekannt und geladen sein.

Die Farbe eines Pixels kann auf beliebige Art berechnet werden. Einem Objekt eine Farbe zu geben, ist nur die simpelste aller denkbaren Möglichkeiten, wird aber so gut wie nie eingesetzt. Der Painters Algorithm (von hinten nach vorne) ist auch nur bei Tranzparenz relevant, ansonsten tut man sich keinen Gefallen damit. Bei den soliden Teilen einer Szene sollte man nach Möglichkeit von vorne nach hinten rendern (Rasterisierung gibt keine Reihenfolge vor), um z.B. Early Z nutzen zu können. Daß die gesamte Szene geladen und bekannt sein muß, ist beim Raytracing so, bei der Rasterisierung aber Quatsch. Das sollte natürlich so sein, wenn es performant sein soll, aber man kann technisch gesehen auch immer ein Objekt von der Platte laden, in die Szene rendern, das Objekt wieder entladen und mit dem nächsten weitermachen.

Raytracing funktioniert so, dass von jedem Pixel des Viewports aus ein Lichtstrahl losgeschickt wird, bis er auf eine Oberfläche trifft. Wenn diese wenigstens eine Farbe reflektiert (sprich: sie ist nicht schwarz), wird auch die Reflektion berechnet, so lange bis der Strahl auf eine Lichtquelle trifft. Von da aus gesehen wird dann auf umgekehrtem Wege die Farbe des Pixels berechnet.

Vorteil: Sehr effizient und präzise, weil genau das berechnet wird was tatsächlich zur Entstehung dieses Bildes notwendig ist. Nachteil: lässt sich schlecht optimieren, und ist in bestimmten Szenarien grottenlangsam.

Lichtstrahlen sind die, die von Lichtquellen ausgehen, nicht von Kameras. Wie die Farbe eines getroffenen Primitivs letztendlich berechnet wird, ist durch Raytracing an sich ebenfalls nicht festgeschrieben. Mit der von dir beschriebenen Methode ließe sich jedenfalls nichts berechnen, was kein perfekt spiegelndes Objekt ist, und die sind doch recht selten. Schlechte Optimierbarkeit kann man Raytracing jetzt auch nicht wirklich ankreiden, es ist sogar ein massiv parallelisierbares Problem. Die Erstellung des Scene-Trees ist da noch am schwierigsten, beim eigentlichen Raytracing kann man aber nahezu beliebig mittels Recheneinheiten skalieren. Sogar über die Zahl der zu berechnenden Pixel hinaus, wenn mehrere Samples pro Pixel und/oder entsprechende Shader mit mehreren Sekundärstrahlen genutzt werden.

In der Realität sind die Grenzen ohnehin nicht mehr so scharf. Shader sind im Endeffekt auch nichts anderes, als der Versuch die Vorteile des Raytracens mit der Rasterisierung zu verheiraten.

Shader sind eine flexible Möglichkeit zur Berechnung von Farben oder Daten, wie auch immer man sie nutzen will. Mit Rasterisierung oder Raytracing hat das erstmal nichts zu tun, ist aber bei beidem sehr nützlich.


Und nun zum tatsächlichen Unterschied zwischen Rasterisierung und Raytracing, runtergebrochen aus das wesentliche (Optimierungen, die aber am Grundprinzip nichts ändern, mal außen vor gelassen):

- Bei der Rasterisierung wird ein Dreieck nach dem anderen berechnet. Für jedes Dreieck wird ermittelt, welche Pixel davon betroffen sind. Mit den interpolierten Eckdaten des Dreiecks (erstmal nur baryzentrische Koordinaten) wird dann auf unspezifizierte Art jeder dieser Pixel berechnet.

- Beim Raytracing wird ein Pixel nach dem anderen berechnet. Für jeden Pixel wird ein Strahl losgeschickt und ermittelt, welches Dreieck davon getroffen wurde und mit welchen baryzentrischen Koordinaten. Dann wird auf unspezifizierte Art mittels dieser Daten der Pixel berechnet.

Das ist auch schon der ganze Unterschied, mehr ist da nicht. Natürlich gibt es haufenweise Optimierungsmöglichkeiten, die sich in beiden Ansätzen unterscheiden, aber die gehören nicht zum Kern. Ob jetzt beim Raytracing Sekundärstrahlen gespawnt werden, hängt von der konkreten Nutzung ab. Und bei beiden Ansätzen, Rasterizing und Raytracing, muß es nichtmal um Farben gehen. Das ist bloß die bekannteste Anwendung, gehört aber ebenfalls nicht zum Kern der Sache.

neustadt
2010-08-30, 01:26:37
Ok, dann habe ich den Begriff des Renderns (Überbegriff für die Erzeugung einer Szene) doch richtig wahrgenommen und Sätze wie der oben zitierte sind (zumindest für jemanden der sich gerade mit der materie auseinandersetzt ;() unglücklich gewählt. Ein Teil eines Ganzen kann ja nicht ein Synonym für das Ganze an sich sein.

Zur Rasterizierung:
Ok, also die Farbbrechung, wie auch immer sie durchgeführt wird (mit oder ohne Z-Buffer, mit oder ohne Shader, ...) zählt zur Rasterisierung. Ich dachte da werden nur die Primitive gerastet und die Pixel mit den zuvor berechneten Farbklecksen versehen.
Inzwischen macht es auch Sinn für mich, dass Raytracing Fabberechung und Rasterung der Primitive in einem ist. Ein Raytracingverfahren ermöglicht also alle Punkte der Geometrie und Rasterung aus diesem Beispiel einer Grafikpipeline (http://de.wikipedia.org/wiki/Grafikpipeline) außer den Transformationen zusammen zu fassen. Richtig?

Ich hab dann aber noch weitere Fragen ;)

Entsteht wieso beim Raytracing eigentlich kein Aliasing? Das vektorielle Modell einer Szene wird doch ebenfalls in ein Raster mit "geringerer" Auslösung gezwängt?

Wenn Larrabee aus x86 Kernen besteht, (also keine Vektoreinheiten besitzt) wären die geometrischen Berechnungen dann nicht deutlich langsamer als in aktuellen Grafikkarten. Ich dachte geometrischen Berechnungen können bei einer hohen Polygonanzahl einen deutlichen Anteil an Rechenlast ausmachen.

Gibt es denn bei aktuellen Grafikkarten eine Unterscheidung zwischen Recheneinheiten für die geometrischen Operationen auf Polygone (Vermutung: Vektor Recheneinheiten bieten sich an, da häufig eine Operation auf viele Polygone angewendet wird) und Einheiten welche für das Rasteriszieren, also inkl Farbberechung mittels Shader zuständig sind?

Wenn ja in welchem Verhältnis stehen die zueinander. Also auf Einheitenzahl/Chipfläche bezogen?

Hoffentlich macht das noch Sinn was ich schreibe. Kopf raucht :redface: Sollte langsam pennen gehen.

Coda
2010-08-30, 01:34:55
Ok, also die Farbbrechung, wie auch immer sie durchgeführt wird (mit oder ohne Z-Buffer, mit oder ohne Shader, ...) zählt zur Rasterisierung.
Nein eigentlich nicht.

Die Rasterisierung ermittelt nur welche Pixel nachher schattiert werden, genauso wie beim Raytracing Schnittpunkte mit Objekten ermittelt werden die schattiert werden.

Inzwischen macht es auch Sinn für mich, dass Raytracing Fabberechung und Rasterung der Primitive in einem ist. Ein Raytracingverfahren ermöglicht also alle Punkte der Geometrie und Rasterung aus diesem Beispiel einer Grafikpipeline (http://de.wikipedia.org/wiki/Grafikpipeline) außer den Transformationen zusammen zu fassen. Richtig?
Ich vermute, dass du das richtige meinst, aber erklär's nochmal genauer.

Entsteht wieso beim Raytracing eigentlich kein Aliasing? Das vektorielle Modell einer Szene wird doch ebenfalls in ein Raster mit "geringerer" Auslösung gezwängt?
Selbstverständlich entsteht bei Raytracing auch Aliasing wenn man nur einen Primärstrahl pro Pixel einsetzt.

Wenn Larrabee aus x86 Kernen besteht, (also keine Vektoreinheiten besitzt) wären die geometrischen Berechnungen dann nicht deutlich langsamer als in aktuellen Grafikkarten. Ich dachte geometrischen Berechnungen können bei einer hohen Polygonanzahl einen deutlichen Anteil an Rechenlast ausmachen.
LRB hat pro Kern eine 16x32-Bit breite Vector-ALU.

Gibt es denn bei aktuellen Grafikkarten eine Unterscheidung zwischen Recheneinheiten für die geometrischen Operationen auf Polygone (Vermutung: Vektor Recheneinheiten bieten sich an, da häufig eine Operation auf viele Polygone angewendet wird) und Einheiten welche für das Rasteriszieren, also inkl Farbberechung mittels Shader zuständig sind?
Die Recheneinheiten für alle Shader sind die gleichen, allerdings wird die Rasterisierung an sich von fixed function Logik durchgeführt.

Neomi
2010-08-30, 01:48:29
Du hast das völlig falsch verstanden. Farbberechnung gehört nicht zur Rasterisierung. Rasterisierung ermittelt zu einem Primitiv (heutzutage fast ausschließlich Dreiecke) die betroffenen Pixel und zu jedem dieser Pixel die interpolierten Eckdaten des Primitivs. Das ist alles, sonst wird da nichts weiter gemacht. Deshalb ist ein Rasterizer auch keine Grafikkarte, sondern nur ein kleiner Teil der GPU.

Auch Raytracing ist nicht Farbberechnung und Rasterisierung der Dreiecke in einem, es ist nichts davon. Raytracing ist nur die Berechnung, welches Dreieck von einem Strahl getroffen wurde und an welcher Stelle. Auch hier ist nichts weiter dabei. Die Rasterung (wenn man ein Bild raytracen will) geschieht vor dem Raytracing, die Farbberechnung danach mit dem Ergebnis des Raytracings bzw. dazwischen, falls noch Sekundärstrahlen benutzt werden.

Zu den weiteren Fragen:

Aliasing entsteht nicht durch das Raytracing selbst, sondern durch eine fehlende Zerlegung eines Pixels in separat berechnete Subpixel bzw. durch die Zerlegung in zu wenig davon. Also außerhalb des eigentlichen Raytracings.

Alle gängigen x86 Prozessoren haben Vektoreinheiten (SIMD), nennt sich SSE. Beim Larrabee habe ich gerade den aktuellen Stand nicht im Kopf, aber der hat mit Sicherheit auch irgendeine (wahrscheinlich sogar relativ zum restlichen Kern aufgebohrte) Vektoreinheit pro Kern.

Bei aktuellen Grafikkarten haben sich aus gutem Grund Unified Shader durchgesetzt. Aus logischer Sicht müssen die verschienenen Shaderarten (momentan Vertex Shader, Hull Shader, Domain Shader, Geometry Shader und Pixel Shader) natürlich separat angesteuert werden können, in Hardware werden diese Arten aber von den gleichen Einheiten berechnet. Dann gibt es noch diverse festverdrahtete Funktionsblöcke, der Rasterizer ist einer davon. Hier kannst du dir ein Diagramm zur aktuellen Direct3D 11 Pipeline anschauen:
http://msdn.microsoft.com/en-us/library/ff476882%28v=VS.85%29.aspx

neustadt
2010-08-30, 01:51:44
- Bei der Rasterisierung wird ein Dreieck nach dem anderen berechnet. Für jedes Dreieck wird ermittelt, welche Pixel davon betroffen sind. Mit den interpolierten Eckdaten des Dreiecks (erstmal nur baryzentrische Koordinaten) wird dann auf unspezifizierte Art jeder dieser Pixel berechnet.

Mehrere Polygone können aber auch, je nach Sichtbarkeitsalgorithmus, gleichzeitig gerastert werden (z.b. scanline algorithmus) oder?

EDIT: stand nix schlaues ;)

neustadt
2010-08-30, 02:37:55
Auch Raytracing ist nicht Farbberechnung und Rasterisierung der Dreiecke in einem, es ist nichts davon. Raytracing ist nur die Berechnung, welches Dreieck von einem Strahl getroffen wurde und an welcher Stelle. Auch hier ist nichts weiter dabei. Die Rasterung (wenn man ein Bild raytracen will) geschieht vor dem Raytracing, die Farbberechnung danach mit dem Ergebnis des Raytracings bzw. dazwischen, falls noch Sekundärstrahlen benutzt werden.

Hm. Wenn man jeden Pixel des Bildschirmrasters als Quelle eines Strahls ansieht und diesen geradeaus auf die Szene sendet und weiß an welcher Stelle ein Dreieck getroffen wird, dann kann man damit doch die Szene rastern. So hab ich mir das vorgestellt.

Wegen der Farbwerte: Die werden dann also wie sonst auch anhand der Farbe der Lichtquelle(n) und den Materialeigenschaften des Objekts berechnet, nur dass man eine genauere Beleuchtung der Szene durch genauere Schatten und Lichtreflexionen(wenn man z.b. von path tracying ausgeht) hat?

Ok thx für eure Ausführungen schonmal. Ich werd jetzt erstmal in meinem Zimmer eine Szene ohne Lichtquelle simulieren.

Coda
2010-08-30, 12:45:53
Mehrere Polygone können aber auch, je nach Sichtbarkeitsalgorithmus, gleichzeitig gerastert werden (z.b. scanline algorithmus) oder?
GPUs rendern nur Dreiecke. Wenn man gleichzeitig mehrere Dreiecke rastert, wie bei neusten GPUs, muss penibel darauf geachtet werden, dass die Reihenfolge erhalten bleibt wenn sie sich überlappen.

Hm. Wenn man jeden Pixel des Bildschirmrasters als Quelle eines Strahls ansieht und diesen geradeaus auf die Szene sendet und weiß an welcher Stelle ein Dreieck getroffen wird, dann kann man damit doch die Szene rastern. So hab ich mir das vorgestellt.
Man nennt das Zeichnen eines Primitives am Stück Rasterisieriung. Raytracing fällt da nicht rein.

Wegen der Farbwerte: Die werden dann also wie sonst auch anhand der Farbe der Lichtquelle(n) und den Materialeigenschaften des Objekts berechnet, nur dass man eine genauere Beleuchtung der Szene durch genauere Schatten und Lichtreflexionen(wenn man z.b. von path tracying ausgeht) hat?
Ja, das ist korrekt.

neustadt
2010-08-30, 14:58:19
GPUs rendern nur Dreiecke. Wenn man gleichzeitig mehrere Dreiecke rastert, wie bei neusten GPUs, muss penibel darauf geachtet werden, dass die Reihenfolge erhalten bleibt wenn sie sich überlappen.

Die Rasterung (wenn man ein Bild raytracen will) geschieht vor dem Raytracing, die Farbberechnung danach mit dem Ergebnis des Raytracings bzw. dazwischen, falls noch Sekundärstrahlen benutzt werden.


Dann erfolgt das rastern also dreidimensional und es werden alle Objekte der Szene berücksichtigt. Beim rastern ohne anschließendes Raytracing wird der Z-Buffer hierbei erstellt und im nächsten Schritt wird dieser verwendet um herauszufinden zu welchen Pixel überhaupt zu bepinseln sind?

Ist hier grob bekannt nach welchem Prinzip das dreidimensionale Rastern bei aktueller Hardware funktioniert (Name)?

Beim rastern mit anschließendem Raytracing frage ich mich:
Werden nach dem Rastern die Materialeigenschaften in den Pixeln gespeichert oder können diese ihren Objekten im nachhinein noch zugeordnet werden? Die Materialeigenschaften sind ja essenziell fürs Raytracing.
Werden beim RT wirklich Strahlen zu allen gerasterten Pixeln der Szene ausgesandt oder gibt es da Optimierungen die erkennen ob sich ein Pixel z.B. innerhalb eines total reflektierenden Objekts befindend?

Tesseract
2010-08-30, 15:29:23
Dann erfolgt das rastern also dreidimensional und es werden alle Objekte der Szene berücksichtigt. Beim rastern ohne anschließendes Raytracing wird der Z-Buffer hierbei erstellt und im nächsten Schritt wird dieser verwendet um herauszufinden zu welchen Pixel überhaupt zu bepinseln sind?

was meinst du mit dreidimensionalem rastern?

mal ganz knapp zusammengefasst: du transformierst die vertices in der 3d-szene so, dass sie bei parallelprojektion auf die bildebene perspektivisch erscheinen.
würdest du die z-koordinate der vertices einfach weglassen wären sie auf auf die bildebene projeziert. durch diesen "trick" erspart man sich komplett das ray tracing.
der z-buffer macht nix anderes als sichtbarkeit. du resettest ihn für das frame auf minus unendlich und schaust bei jedem pixel den du berechnest ob sein z-wert größer als der des z-buffers ist. wenn ja schreibst du diesen wert in den z-buffer und das pixel in den framebuffer. wenn nicht liegt ein anderes davor und du bist fertig. welche farbe du für das pixel in den framebuffer schreibst ist dann aufgabe des shaders, der diese farbe mehr oder weniger beliebig ermitteln kann und dafür positionen von lichtquellen, oberflächennormale und andere derartige werte zur verfügung haben kann.

raytracing hingegen ist etwas vollkommen anderes. hier schneidest du von jedem pixel einen strahl mit der szene (und gehst rekursiv weiter, berechnest schattenfühler oder ähnliches)
das hat mit einer parallelprojektion nur im spezialfall und mit geometrietransformationen überhaupt nix zutun.

Neomi
2010-08-30, 17:24:31
Dann erfolgt das rastern also dreidimensional und es werden alle Objekte der Szene berücksichtigt. Beim rastern ohne anschließendes Raytracing wird der Z-Buffer hierbei erstellt und im nächsten Schritt wird dieser verwendet um herauszufinden zu welchen Pixel überhaupt zu bepinseln sind?

Es wird nix 3D gerastert. Wenn du ein 2D-Bild raytracen willst, geben die Pixel des Bildes das Raster vor (und zwar 2D), da muß nicht mehr wirklich was gerastert werden. Dann wird pro Pixel ein Strahl (oder mehrere, je nach gewünschter Qualität) rausgeschickt.

Werden nach dem Rastern die Materialeigenschaften in den Pixeln gespeichert oder können diese ihren Objekten im nachhinein noch zugeordnet werden? Die Materialeigenschaften sind ja essenziell fürs Raytracing.

Hast du überhaupt die bisherigen Postings gelesen? Pro Pixel gibt es einfach nur Daten, und zwar welches Dreieck an welcher Stelle da hin soll, beim Rasterizer und beim Raytracer. Was danach kommt, ist dann wieder eine andere Sache. Materialeigenschaften interessieren einen Raytracer überhaupt nicht. Wenn jetzt beim Raytracing ein Strahl ein bestimmtes Dreieck an einer bestimmten Stelle trifft, ist es völlig egal, ob das Material an der Stelle grün, rot oder voll spiegelnd ist. Das interessiert allerdings den Materialshader, der danach zum Einsatz kommt und im spiegelnden Fall einen weiteren Sekundärstrahl (oder mehrere bei unscharfer Reflektion) losschicken kann. Man muß aber keine Farbe berechnen, man kann auch IDs von Objekten, Indizes von Dreiecken und baryzentrische Koordinaten des Treffers speichern.

Lies einfach nochmal nach, was ich schon über den Unterschied zwischen Rasterizern und Raytracern geschrieben habe und zu dem, wie die beiden arbeiten. Und interpretier bitte nicht wieder sonstwas dazu, das ist nur schlecht fürs Verständnis.

neustadt
2010-08-31, 15:26:55
Ja ich lese eure Postings :) aber anscheinend scheitere ich dabei die einzelnen Schritte im Kontext des ganzen Rendervorgangs zu verstehen.

Ich will mal mein aktuelles Verständnis über den Renderpath einer starren 3D Szene darstellen wie sie in einer aktuellen Grafikkarte stattfindet. Falls ich was in Dinge rein interpretiere, dann um mein Verständnis besser darlegen. :redface: Rede ich von Pixeln, meine ich die durch die Rasterisierung entstandenen Punkte, welche die Szene darstellen. Nicht die Pixel des Bildschirms, falls es da einen unterschied geben sollte.

1. Die Grafikkarte bekommt eine Szene in Form von Objekten aus Primitiven, Lichtquellen und Beobachtern übergeben. Die Maße und Position der Objekte liegen vektoriell vor.

2. Die Grafikkarte rechnet jedes Objekt in ein vielfaches von Dreiecken um. Es existieren für die Grafikkarte also nur noch Flächen ohne Volumen in der Szene. Dabei werden den Vertices der Dreiecke anhand der Materialeigenschaften des Objekts, der Lichtquellen und der Textur(en) eine Farbe zugewiesen.

3. Die Dreiecke bzw. deren Vertices werden mit Hilfe der Zentralprojektion so transformiert, dass sie aus Sicht des Betrachters einen Tiefeineindruck ergeben. Die nun nicht mehr benötigte Z Koordinate eines Vertices wird im Z-Buffer hinterlegt.

4. Die sichtbaren Dreiecke werden gerastert. Die Farbwerte der Pixel ergeben sich aus den Farbwerten der drei Vertices.

5. Durch den Pixel-Shader können die Farbwerte jedes einzelnen Pixels im nach hinein verändert werden.


Kommen wir nun zum Raytracing:
Raytracing ist erstmal nur ein Verfahren zu Ermittlung von Verdeckung. Erweiterungen von Raytracing, wie Pathtracing oder Photonmapping erlauben die Berechnung eines globalen Beleuchtungsmodells der Szene. Schatten Lichtreflexion- und brechung sind damit darstellbar. Laut Wikipedia (http://de.wikipedia.org/wiki/Path_Tracing) heißt es:

Beim Path Tracing wird jeder Strahl, der in die Szene geschossen wird, beim Auftreffen auf Oberflächen reflektiert, gebrochen oder absorbiert, wobei jedes Mal (außer im Falle der Absorption) mindestens ein zufälliger Strahl generiert wird, der das Integral der Rendergleichung nähert.
Somit müssen die Materialeigenschaften beim auftreffen des Strahls bekannt sein.

Für mich stellt sich nun die Frage an welcher Stelle des Renderpaths tracingartige Verfahren angewandt werden (können), um eine Szene realistischer darzustellen. Neomi schreib dazu: Die Rasterung (wenn man ein Bild raytracen will) geschieht vor dem Raytracing, die Farbberechnung danach mit dem Ergebnis des Raytracings bzw. dazwischen, falls noch Sekundärstrahlen benutzt werden.


Wenn RT dazu dient Verdeckung zu erkennen und nach dem rastern eingesetzt wird, kann das doch nur mit einer dreidimensionalen Rasterung der Szene funktionieren. :confused: Alle Tiefeninformationen wurden bei einem klassischen Renderpath inzwischen verworfen, bzw. im Z-Buffer abgelegt. Diesen in Kombination mit RT zu verwenden würde das RT an sich ad absurdum führen.

Wird anstelle von RT ein mächtigerer Algorithmus wie PT verwendet und die Strahlen nach dem rastern auf die Pixel der Szene geworfen werden, dann muss jedem Pixel sein zugehöriges Objekt oder direkt seine Materialeigenschaft bekannt sein, um das Verhalten das Primärstrahls als auch die der Sekundärstrahlen berechnen zu können.

Wieso wird nicht so vorgegangen: Wenn man jeden Pixel des Bildschirmrasters als Quelle eines Strahls ansieht und diesen geradeaus auf die Szene sendet und weiß an welcher Stelle ein Dreieck getroffen wird, dann kann man damit doch die Szene rastern. So hab ich mir das vorgestellt.


So, ich hoffe meine Schlussfolgerungen und Fragen erscheinen euch schlüssig.

RLZ
2010-08-31, 16:18:29
Ohne jetzt viel schreiben zu wollen mal zwei Denkanstöße, mit denen du nochmal neu drüber nachdenken kannst.

- Die Grafikkarte bekommt die Geometrie schon nur noch in Form von Dreiecken
- Du hast den Z-Buffer irgendwie nicht richtig verstanden. Wikipedia erklärt das recht schön:
Das Prinzip des Z-Buffering ist sehr einfach. Neben dem sichtbaren Teil des Bildspeichers, der die aktuellen Farbwerte enthält, gibt es einen weiteren Speicher, den Z-Buffer, der die Tiefe des sichtbaren Objekts an jedem Pixel enthält. Alternativ können die Pixelwerte im Framebuffer um einen z-Wert erweitert werden. Zu Beginn werden die Einträge im Z-Buffer auf einen Wert gesetzt, der für eine unendliche Entfernung steht. Der Framebuffer wird mit der Hintergrundfarbe initialisiert. Jedes Polygon wird nun gerastert. Nur wenn der aktuell gerasterte Punkt des Polygons nicht weiter weg vom Betrachter liegt als der Punkt, dessen Entfernung im Z-Buffer eingetragen ist, werden die Werte im Z-Buffer und im Framebuffer durch die Entfernung beziehungsweise die Farbe des aktuellen Polygons ersetzt.

Vielleicht solltest du erstmal die normale Rasterisierungspipeline vollständig verstehen, bevor du versuchst Unterschiede zum Raytracing zu finden.

Coda
2010-08-31, 16:20:33
1. Die Grafikkarte bekommt eine Szene in Form von Objekten aus Primitiven, Lichtquellen und Beobachtern übergeben. Die Maße und Position der Objekte liegen vektoriell vor.
Naja, eigentlich bekommt sie nur Daten zu Verarbeitung. Wie dann etwas interpretiert wird entscheidet heute der Programmierer mit dem Shader.

Aber gut, so kann man sich das vielleicht vereinfacht vorstellen

2. Die Grafikkarte rechnet jedes Objekt in ein vielfaches von Dreiecken um.
Nein. Sie rechnet gar nichts um. Die Geometriedaten liegen zum Rendern bereits als Dreiecksliste vor.

Dabei werden den Vertices der Dreiecke anhand der Materialeigenschaften des Objekts, der Lichtquellen und der Textur(en) eine Farbe zugewiesen.
Kann man machen. Was aber an die Vertices übergeben wird entscheidet der Vertex Shader.

Die Dreiecke bzw. deren Vertices werden mit Hilfe der Zentralprojektion so transformiert, dass sie aus Sicht des Betrachters einen Tiefeineindruck ergeben.
Kann man im Vertex Shader machen, ja. Es ist aber jede beliebige Transformation möglich.

Die nun nicht mehr benötigte Z Koordinate eines Vertices wird im Z-Buffer hinterlegt.
Nein. Z ist zusammen mit X, Y und Z eine Ausgabe des Vertex Buffers. Es wird während des Rasterns über das Dreieck interpoliert und für jeden Pixel mit dem bestehenden Z-Wert im Z-Buffer verglichen. Normalerweise wird dann gerendert wenn der neue Wert "näher" ist.

4. Die sichtbaren Dreiecke werden gerastert. Die Farbwerte der Pixel ergeben sich aus den Farbwerten der drei Vertices.
Das kann man so machen, aber in der Regel ergibt sich die Farbe aus den Texturen, die im Pixel Shader gesampled wird.

Durch den Pixel-Shader können die Farbwerte jedes einzelnen Pixels im nach hinein verändert werden.
Nicht im Nachhinein. Der Pixel Shader arbeitet für jeden Pixel der vom Rasterizer ausgegeben wird. Das geschieht alles zusammen.

neustadt
2010-08-31, 20:55:32
Neben dem sichtbaren Teil des Bildspeichers, der die aktuellen Farbwerte enthält, gibt es einen weiteren Speicher, den Z-Buffer, der die Tiefe des sichtbaren Objekts an jedem Pixel enthält.

Frage: Wie können Pixelinformationen in den Z-Buffer geschrieben werden, wenn die Szene noch nicht gerastert worden ist. Also für mein Verständnis noch nicht aus Pixeln besteht?
Der Framebuffer wird doch auch während des Rasterns gefüllt oder? Wiki ist da nicht gerade aufschlussreich.

Coda
2010-08-31, 21:23:29
Die Tiefe wird natürlich beim Rastern geschrieben.

RLZ
2010-08-31, 21:30:36
Frage: Wie können Pixelinformationen in den Z-Buffer geschrieben werden, wenn die Szene noch nicht gerastert worden ist. Also für mein Verständnis noch nicht aus Pixeln besteht?
Der Framebuffer wird doch auch während des Rasterns gefüllt oder? Wiki ist da nicht gerade aufschlussreich.
Wiki ist da eigentlich aufschlußreich. Du versucht nur deine falsche Vorstellung in die Beschreibung zu pressen.

Die Pipeline sieht für einfache Fälle und ganz primitiv beschrieben so aus.

Vertex Shader:
Eingangsdaten: Dreiecke
Grundfunktion: Transformation der Vertexdaten (Projektion der Vertices auf eine Ebene)
Ausangsdaten: Dreiecke

Setup:
Eingangsdaten: Transformierte Dreiecke
Grundfunktion: Vorbereiten der Daten für die Rasterisierung (Backface Culling, Clipping, etc.)

Rasterisierer:
Eingangsdaten: immer noch Dreiecke
Grundfunktion: Rasterisiert :)
Ausgangsdaten: Pixel/Fragments

PixelShader:
Funktion: Farbe für Pixel berechnen
Ausgangsdaten: Fertige Pixel/Fragments

Z-Culling + Blending:
Funktion: Testen, ob berechnetes Fragment sichtbar ist. Wenn ja, Pixel mit Framebuffer verrechnen (Blending) und Z-Buffer updaten.


Nun merkt man, dass es eigentlich doof ist, den Pixelshader für das Fragment noch auszuführen, wenn man vorher weiss, dass es nicht sichtbar ist. Deswegen hat man Early-Z (TM) erfunden. Man wirft Pixel unter gewissen Randbedingungen (Pixelshader darf z-Wert nicht verändern und den Pixel nicht selbstständig wegwerfen wegen Alphatest oä.) direkt nach Rasterisierung weg, wenn es nicht sichtbar ist.

Demirug
2010-08-31, 22:06:44
Nun merkt man, dass es eigentlich doof ist, den Pixelshader für das Fragment noch auszuführen, wenn man vorher weiss, dass es nicht sichtbar ist. Deswegen hat man Early-Z (TM) erfunden. Man wirft Pixel unter gewissen Randbedingungen (Pixelshader darf z-Wert nicht verändern und den Pixel nicht selbstständig wegwerfen wegen Alphatest oä.) direkt nach Rasterisierung weg, wenn es nicht sichtbar ist.

Die meisten Chips machen den Early-Z heute bereits als weitere Optimierung während der Rasterisierung für größere Pixelkacheln.

Tesseract
2010-08-31, 22:07:44
Frage: Wie können Pixelinformationen in den Z-Buffer geschrieben werden, wenn die Szene noch nicht gerastert worden ist. Also für mein Verständnis noch nicht aus Pixeln besteht?
Der Framebuffer wird doch auch während des Rasterns gefüllt oder? Wiki ist da nicht gerade aufschlussreich.

der z-buffer hat für jeden farbwert im framebuffer einen tiefenwert.
wenn du ein primitiv in den framebuffer renderst merkst du dir für jedes geschriebene pixel was seine tiefe war. wenn du jetzt ein anderes primitiv in den framebuffer renderst, dass sich teilweise mit dem alten überlappt kannst du den z-wert des aktuellen pixels mit dem im z-buffer vergleichen und damit erkennen, ob dieses pixel des alten objekts vor oder hinter dem aktuellen liegt.

im prinzip kannst du in den z-buffer reinschreiben was du willst, allerdings kann dann natürlich viel scheiße entstehen.
du kannst z.B. zwischen 2 objekten den z-buffer clearen, dann ist das neue objekt immer vollständig vor dem alten. das kann man z.B. für interfaceelemente verwenden, die immer vollständig vor der szene liegen sollen oder derartiges.
wenn du den z-buffer garnicht cleast füllt sich das bild in einer bewegten szene schnell mit artefaktmüll bis du nixmehr erkennst usw.

Gast
2010-09-01, 12:08:58
Wieso muss beim Raytracing nicht rasterisiert werden? Raytracing verwendet doch ebenfalls Primitive als Ausgangsobjekte und die sind doch immer vektorbasiert.

Die dinge haben mehr gemeinsam als die meisten wahrhaben wollen ;).

Beim rasterisieren auf modernen GPUs geht man dreieck fuer dreieck durch und testet pixel fuer pixel, was davon zu sehen ist.
beim raytracen geht man pixel fuer pixel des bildes durch und testet dreieck fuer dreieck welches zu sehen ist.

algorithmisch also
rasterizer:

for every triangle
for every pixel
if(visible(pixel,triangle))
output


raytracen

for every pixel
for every triangle
if(visible(pixel,triangle))
output


und in der simpelsten form, also ohne optimierungen laeuft es genau so ab.

natuerlich kannst du bei beiden systemen viel verbessern und es gibt verschiedene wege der verbesserungen die sich ausschliessen.
z.B.
beim raytracen ein solid-bsp aufbauen. das ist eine hierarchie von ebenen die dir erlaubt von vorn nach hinten zu travesieren, sobald du etwas triffst, kannst du 100% sicher sein dass es das erste ist was sichtbar ist und du gibst es aus.
z.B.
beim rasterisieren weisst du dass du nach der projektion alle sichtbarkeitsstrahlen parallel hast, du musst also den schnittpunkt nicht erst ermitteln um zu testen ob dieser im dreieck ist, du kannst direkt die bildschirmkoordinate des pixels gegen eine einfache 2d gleichung des dreiecks testen.


entsprechend, wenn du dir z.b. den "Moller triangle intersection test" oder die "homogenous space triangle rasterization" anschaust, beide transformieren die zu testenden punkte/strahlen in den raum das dreiecks und testen dann ob x>0 y> und x+y<1 ist (das ist exemplarisch, in wirklichkeit ist es ein wenig komplexer).

der wahre unterschied ist also nur die ausgangssituation der beiden kaskadierten schleifen und wie daraufhin optimiert wird. als programmierer geht man immer davon aus "innere schleifen sind die kritischen". entsprechend versucht man beim rasterisieren effizient so wenig punkte wie moeglich zu testen. beim raytracen effizient so wenig dreiecke wie moeglich.

neustadt
2010-09-01, 13:49:29
Erstmal thx für eure zahlreiche beteiligung

der z-buffer hat für jeden farbwert im framebuffer einen tiefenwert.
wenn du ein primitiv in den framebuffer renderst merkst du dir für jedes geschriebene pixel was seine tiefe war. wenn du jetzt ein anderes primitiv in den framebuffer renderst, dass sich teilweise mit dem alten überlappt kannst du den z-wert des aktuellen pixels mit dem im z-buffer vergleichen und damit erkennen, ob dieses pixel des alten objekts vor oder hinter dem aktuellen liegt.


ok für mich wird grad erst erkennbar dass es viele rastervorgänge pro frame gibt.
Du schreibst von einzelnen dreiecken die gerastert werden und auch coda hat schon angedeutet, dass nur ein (oder wenige) dreick(e) zur zeit gerastert werden. Wie passt das mit dem scanline algorithmus zusammen?

Ich versteh die rastervorgänge grad so: Wenn ein rastervorgang ein kompletter scanline durchlauf aller vertikalen pixelreihen ist, ergeben sich so viele rastervorgänge pro frame, wie es tiefeneben gibt. Die dreiecke welche auf der ersten ebene liegen (wenn man von vorn nach hinten zeichnet), werden immer gerastert, da der z-buffer mit plus unendlich initialisiert wurde.


im prinzip kannst du in den z-buffer reinschreiben was du willst, allerdings kann dann natürlich viel scheiße entstehen [...]
interessant.

Der Framebuffer wird doch auch während des Rasterns gefüllt oder? Wiki ist da nicht gerade aufschlussreich. Wiki ist da eigentlich aufschlußreich. Du versucht nur deine falsche Vorstellung in die Beschreibung zu pressen.
War auf den Wiki Framebuffer Artikel bezogen. Der ist für das Verständnis des/der Rastervorgangs/gänge dafür wirklich nicht aufschlussreich.

Beim rasterisieren auf modernen GPUs geht man dreieck fuer dreieck durch und testet pixel fuer pixel, was davon zu sehen ist.
beim raytracen geht man pixel fuer pixel des bildes durch und testet dreieck fuer dreieck welches zu sehen ist.

vllt bin ich da jetzt kleinlich was die definition der rasterisierung angeht, aber:
wird das bild zuvor gerastert, um es pixel für pixel durch zugehen, oder kann man sagen, dass pro bildschirmpixel ein strahl ausgesandt wird und dadurch das bild gerastert wird?

Coda
2010-09-01, 13:54:06
Wie passt das mit dem scanline algorithmus zusammen?
Gar nicht. Der wird von GPUs so auch nicht verwendet. Auch in Software kommt der für 3D eigentlich nicht zum Einsatz.

Ich versteh die rastervorgänge grad so: Wenn ein rastervorgang ein kompletter scanline durchlauf aller vertikalen pixelreihen ist, ergeben sich so viele rastervorgänge pro frame, wie es tiefeneben gibt. Die dreiecke welche auf der ersten ebene liegen (wenn man von vorn nach hinten zeichnet), werden immer gerastert, da der z-buffer mit plus unendlich initialisiert wurde.
Es wird ein Dreieck nach dem anderen gerastert und seine Pixel werden dabei in einer beliebigen Reihenfolge ausgegeben. Schlag dir das mit der Scanline aus dem Kopf.

Und nein, es gibt auch nicht "einen Rendervorgang pro Tiefenebene". Die Dreiecke werden so gerendert wie sie kommen, egal wie ihre Z-Werte sind. Was nachher sichtbar ist, wird durch den Z-Test und die Werte im Z-Buffer eindeutig bestimmt - unabhängig von der Reihenfolge.

Wenn du nur undurchsichtig Dreiecke hast kannst du ihre Renderreihenfolge beliebig mischen. Es wird immer (bis auf Präzisionsprobleme, wenn ihre Z-Werte nahezu gleich sind) exakt das gleiche rauskommen.

neustadt
2010-09-01, 14:01:03
alles klar. hab halt bis jetzt immer nur von scanline gelesen.
kannst du mir sagen wie ich an infos der tatsächlich verwendeten algorithmen komm? gibts da starke unterschiede zwischen den grafikarten herstellern oder gar hardware generationen?

Coda
2010-09-01, 14:02:02
Es gibt starke Unterschied.

Das sollte dich aber auch eigentlich nicht weiter interessieren, weil es wie gesagt völlig irrelevant ist in welcher Reihenfolge die zu rendernden Pixel eines Dreiecks erzeugt werden.

Icare3D (http://www.icare3d.org/GPU/CN08) hat das ganze Mal für G80 beschrieben.

neustadt
2010-09-01, 14:05:29
das wie ist für mich auch eher die spannendere frage, falls es nicht zu komplex ist. scanline ist ja schön easy.

Neomi
2010-09-01, 14:16:09
wird das bild zuvor gerastert, um es pixel für pixel durch zugehen, oder kann man sagen, dass pro bildschirmpixel ein strahl ausgesandt wird und dadurch das bild gerastert wird?

Wie schon ein paar mal gesagt, wird beim Raytracing nicht gerastert. Die separaten Pixel eines 2D-Bildes beschreiben bereits das Raster. Gerastert wird quasi dadurch, daß die zu rendernde Auflösung festgelegt wird. Beim Raytracing selbst (und anschließendem bzw. damit interleavtem Shading) werden dann nur noch die Informationen berechnet, die man in das Raster eintragen will, meist Farbwerte. Wäre das Bild nicht schon vorher gerastert, gäbe es keine Pixel, zu denen man Farbwerte berechnen könnte. Vor dieser Berechnung sind zwar die Farbwerte noch nicht vorhanden und die Pixel damit unvollständig, aber vorhanden müssen die Pixel schon sein.

Coda
2010-09-01, 14:16:17
das wie ist für mich auch eher die spannendere frage, falls es nicht zu komplex ist. scanline ist ja schön easy.
Das kann dir hier niemand beantworten, weil es hardwarespezifisch ist und sowas nicht dokumentiert wird.

GPUs rendern heutzutage auch direkt in 4D homogenen Koordinaten um das Clipping gleich mit zu machen.