Sacred 2: Das 1080p/Technik-Interview
Einblick in die Arbeit der Engine-Coder
Ich habe mich entschlossen einige Konsolenentwickler anzusprechen, die Erfahrung mit 1080p Videospielen haben. Das Ziel war simpel: Die tiefergehenden Herausforderungen zu diskutieren, die damit einhergehen, die so genannte „Full-HD“-Auflösung zu coden.
Sacred-2-Programmierer Tobias Berghoff arbeitete direkt am 1080p-Renderer der PS3-Version des Spiels und hatte eine ganze Reihe spannender Einsichten in den Prozess. Das Projekt, an dem er arbeitete war insofern interessant, als dass es - anders als WipEout HD und der Großteil der 1080p-fähigen PS3-Titel - ein Mulitplattform-Spiel war: Sacred 2 ist erhältlich für PC, PlayStation 3 und Xbox 360. Beide Konsolenversionen unterstützen die maximale Auflösung von 1920x1080. Zuvor hatten wir eine Analyse der Performance des Spiels in jedem der unterstützten Modi erstellt. Und es ist interessant festzustellen, dass das Spiel, das intern mit Profilen für 720p und 1080p läuft, die niedrigere HD-Auflösung nur in heruntergerechneter Form für Gameplay in Standard-Auflösung ausgibt.
Lest im Anschluss das ungekürzte Interview: 100 Prozent technische Diskussion - genau wie wir es bei Digital Foundry lieben.
Digital Foundry: In Anbetracht der Tatsache, dass viele Leute immer noch SDTVs nutzen: Was war der Gedanke dahinter, sich für 1080p zu entscheiden. Habt ihr nicht das Gefühl, dass das Spiel ein bisschen übertechnisiert ist?
Tobias Berghoff: Um ehrlich zu sein, war das ein sehr gradueller Prozess. Als die Arbeiten an der Xbox-Version Ende 06 begannen war das Performance-Ziel 720p mit 2xMSAA. Die PC-Version war grafisch schon sehr weit fortgeschritten und es war sehr Performance-hungrig. Darüber hinaus hatten wir keine Erfahrung mit der Plattform, ein wenig Zurückhaltung war also eine gute Idee.
Die Entwicklung der PS3-Version begann Mitte 07 und wir hielten es eher für eine Art Experiment. Durch die Industrie geisterten all die Horror-Geschichten in Bezug auf PS3-Entwicklung, also waren wir nicht gerade überzeugt davon, dass es funktionieren würde. Wir haben es ein ganzes Jahr nicht angekündigt, damit wir es immer noch leicht absagen konnten, wenn die Plattform sich als zu große Herausforderung herausstellen sollte.
Wie wir erwartet hatten, erwies sich die Performance auf beiden Plattformen als recht problematisch. Wir haben einen Forward Renderer von der PC-Version geerbt, der Frametimes von 100 -200ms auf der 360 produziert und etwa 100ms mehr auf der PS3. Nach einigen zwecklosen Versuchen, das zu optimieren, entschied sich das Xbox-Team für einen Deferred Renderer, was für den ersten großen Performance-Durchbruch sorgte. Wir waren noch nicht ganz da, aber die 360-Version war definitiv in der Lage, in 720p zu rendern.
Wäre die PS3-Version nicht gewesen, hätten wir an dieser Stelle vermutlich aufgehört. Auch mit dem Deferred Renderer gingen unsere Frametimes in den Bereich 100ms+, wenn genügend Lichtquellen im Bild waren. Das Problem war der Pixel Shader der im Deferred Pass zum Einsatz kam. Der macht die gesamte Lichtberechnung in einem Durchlauf, was uns gamma-korrekte Beleuchtung mit bis zu 12 Pointlights erlaubt (von denen acht Shadowmaps haben können), plus der Sonne und ihrer Shadowmap. Ein Sony-Ingenieur hat mal gesagt „es produziert wirklich schöne Bilder, ist aber wahrscheinlich der schwerste Pixel Shader, den ich je gesehen habe“. Das Problem lag darin, dynamisch zu bestimmen, welche Lichtquellen bei welchen Pixeln ausgelassen werden konnten. Xenos konnte damit gut umgehen, RSX ist eine GeForce 7 und damit kein Freund von Branching.
Weil ich als einziger für das Rendering auf der PS3 zuständig war, hat mir das einige Kopfschmerzen bereitet. Die Lösung war, die SPUs zu nutzen, um festzustellen, welche Lichtquellen welchen Pixel beeinflussen und dann den Deferred Pass in Blöcke von 64 Pixeln zu unterteilen, damit alle Blöcke, die vom gleichen Licht berührt werden auf einmal gezeichnet werden können (*). Zusammen mit auf die tatsächliche Anzahl an Lichtquellen optimierten Pixel Shadern war die PS3 damit weit vor der Xbox - weit genug, dass 1080p in den Bereich des Möglichen rückte.
Ich glaube das war eigentlich der Punkt, an dem wir sagten “Ohhhh! Schick!“ und versuchten, es möglich zu machen. Wir hatten schon zuvor ein paar Test-Renders in 1080p und wussten sehr genau, dass die Grafikqualität mit all unserem alpha-getestetem Gras und Laub immens sein würde. Es war wirklich ein Unterschied wie „Tag und Nacht“.
Einige Zeit sah es sogar so aus, als würde die PS3 1080p bieten und die Xbox nicht, bis Stephan Hodes - der Xbox-Chef-Programmierer - eine etwas weniger wahnsinnige Version des oben beschriebenen Systems für die Xbox schrieb, die beide Versionen ziemlich genau auf denselben Level brachte (**).
Ist es also „übertechnisiert“? Vielleicht. Wir haben nicht die angepeilten Performance-Ziele erreicht und auf der PS3 - welches die einzige Version ist, über die ich genug weiß, um darüber zu sprechen - ist es fast komplett ein CPU-Problem. Das Rendering ist auf der Plattform also definitiv schneller als der CPU-seitige Code, was ein bisschen Verschwendung ist. Ich sollte aber darauf hinweisen, dass es - zumindest auf der PS3 - nicht besonders viel einfacher gewesen wäre, 720p mit 2xMSAA bei 30FPS zu bekommen, als ganz auf 1080p zu gehen. Es hätte also nicht geholfen, Entwicklungsarbeit vom Renderer auf den Game-Code zu verlagern.
Digital Foundry: Könntest du den Hauptunterschied zwischen dem Rendern von 720p und 1080p kurz und simpel umreißen?
Tobias Berghoff: Es ist die 2.25-fache Zahl an Pixeln. Das ist wirklich alles. Auf der PS3 werden deine Render-Ziele größer, was dich VRAM kostet und potentiell den Druck auf das Texturen-Streaming erhöht. Für uns hat das wirklich das SPU-Processing verkompliziert, das ich vorhin erwähnt habe. Wir müssen durch den gesamten Depth Buffer gehen, er muss also vom VRAM zum System RAM kopiert werden. Rendert man in 720p, braucht man 3,5MB Buffer dafür. In 1080p sind es 8MB, was eine ganze Menge zusätzlicher Speicher ist.
Ich hab also den Speicher halbiert, den RSX die linke Seite in den System RAM kopieren lassen, es mit der SPU verarbeiten lassen und diesen Vorgang mit der rechten Seite wiederholt. Was man wirklich nicht will, ist, dass die GPU untätig ist. Während also die SPUs arbeiteten, musste RSX ebenfalls Arbeit verrichten. Dazu brauchten wir etwas wie ein Interruptsystem, das den SPUs erlaubt, dem RSX zu sagen, die zweite Hälfte des Depth Buffers herunter zu kopieren. Alles ohne Beteiligung des PPU-seitigen Rendercodes und ohne zu wissen, woran RSX tatsächlich gerade arbeitet. Man macht also einige sehr interessante Dinge, um ein paar MBs RAM zu sparen.
Auf der 360 ist die Situation ein bisschen anders, weil deine Render-Ziele im eDRAM (den zusätzlichen 10MB ultra-schnellen RAMs, die mit der GPU verbunden sind) gespeichert werden. Je größer die Ziele also sind, desto mehr Tiles und Resolves (der Vorgang des Kopierens vom eDRAM zum System RAM) hat man. Wenn man wirklich die gesamten Ziele irgendwo als Texturen braucht, rennt man natürlich wieder in dieselben Speicherprobleme.
Das Hauptproblem ist aber das Pixel Processing. Je höher die Auflösung, desto wichtiger ist es, schnelle Pixel Shader zu haben und desto mehr Speicher-Bandreite wird durch die ROP (Render Output Units) verbraucht. Aber wenn man ein 1080p30 Spiel mit einem 720p60 Spiel vergleicht, liegen die Unterschiede im Spiel-Code nicht im Renderer.
* Inspiriert von der Arbeit der netten Leute von SCEE's PhyreEngine Team.
** Wie sich herausstellte hatte Naughty Dog vergleichbare, “weniger Wahnsinnige” Technik in Uncharted.