HomeMapIndexSearchNewsArchivesLinksAbout LF
[Top Bar]
[Bottom Bar]

von:Carlos Calzada Grau

Inhalt:

  1. Einleitung
  2. Installation
  3. Erste Schritte
  4. Ausblick

RenderMan

Zusammenfassung: Die Firma Pixar hat RenderMan, einen Rendering Interface Standard, entwickelt. RenderMan erlaubt es Modellierern zu spezifizieren, was gerendert werden muß, ohne genau festzulegen, welcher Algorithmus benutzt werden soll. Dieser Artikle gibt einen Einblick in dieses fantastische Programm.


Einleitung

Wer hat noch nie von Pixar gehört? Wer hat noch nie Toy Story gesehen? Pixar Animation Studios sind seit langem für ihre Computeranimationen bekannt. Luxo Jr. (1986) war der erste Film mit 3D Graphik, der für einen Oskar nominiert wurde, und erhielt über 20 Preise auf internationalen Filmfestivals.

Red's Dream gewann 1987 mehrere Preise auf dem World Animation Festival in Zagreb und auf dem International Film Festival in San Francisco.

Der erste Animationsfilm, der einen Oskar erhielt war Tin Toy (1988); Pixar modellierte das Gesicht eines Babys mit über 40 Muskeln, die ein Animator kontrollieren konnte.

Knick Knack, die Geschichte eines Schneemanns, der in einer Kristallkugel lebt, erschien 1989. Der Film wurde ursprünglich als 3D Film produziert, später aber in einer ``normalen'' Fassung herausgegeben.

Wenig später kamen eine Reihe von erfolgreichen Filmen wie z.B. Toy Story, einer der ersten Filme voller Länge, die vollständig auf einem Computer produziert wurden. Die Pixar­Homepage enthält eine Menge interessanter Informationen, darunter auch das Erscheinungsdatum für Toy Story 2, der 1999 erscheinen soll.

Pixar entwickelte RenderMan um "Modeler" und "Renderer" voneinander zu trennen und unabhängig voneinander zu warten. Ein Modeler wird dazu benutzt, Szenen zu zeichnen und Animationen zu entwerfen. Die einzige Aufgabe eines Renderers ist es, die mit dem Modeler entworfenen Szenen so realistisch wie möglich zu zeichnen (oder rendern, wie die Angelsachsen sagen); der Renderer ist für die lebensechte Erzeugung von Schatten, Lichtfall und Texturen verantwortlich.

RenderMan erlaubt es, die Angaben, was darzustellen ist, vom wie des Renderns zu trennen. Ein Modeler sollte sich nicht um das Rendern kümmern müssen. Ein Renderer, der den von RenderMan spezifizierten Standard erfüllt, kann, unabhängig von RenderMan, eine Vielfalt von Methoden zum ``Zeichnen'' der Objekte benutzen, wie z.B. Z-Buffer, Scan-Line, Ray-Tracing oder Radiosity. Man kann das Interface, das RenderMan bereitstellt, als ein Format zum Beschreiben von Szenen ansehen, genauso wie PostScript ein Format zum Beschreiben (in zweierlei Hinsicht) von Seiten ist. Dieser Standard hängt weder vom Betriebssystem noch von der zugrundeliegenden Architektur ab.

        
Die RenderMan@ Interface Prozeduren und das RIB Protokol sind:
Copyright 1988, 1989, Pixar.
Alle Rechte vorbehalten.
RenderMan@ ist ein eingetragenes Warenzeichen von Pixar

Wir werden in diesem Artikel versuchen, eine kleine Einführung in RenderMan mit Hilfe der Blue Moon Rendering Tools zu geben, die komplett von Larry Gritz geschrieben wurden. Dieses Paket ist ein frei verfügbarer Renderer (nur die Binärdateien für persönlichen Gebrauch), der für viele verschiedene Systeme erhältlich ist, unter anderem auch für Linux, für das er in der Tat zuerst implementiert wurde. Er benutzt sowohl Ray-Tracing als auch Radiosity und läßt im Vergleich zu Pixars kommerziellem Photorealistic RenderMan (PRMan) wenig zu wünschen übrig.

Das Welt- und Kamerakoordinatensystem sind anfänglich identisch, nämlich ein linkshändiges System wie in PovRay; der Ursprung befindet sich in der Mitte des Bildschirms, die X Achse verläuft nach rechts, die Y Achse nach oben und die Z Achse geht in den Bildschirm hinein. Ein rechtsändiges Koordinatensystem unterscheidet sich dadurch, daß die Z Achse aus dem Bildschirm herauskommt.

Die folgende Abbildung zeigt die Standardkamera (die X Achse ist rot, die Y Achse grün und die Z Achse blau; der Sourcecode kann durch einen Klick auf das Bild erhalten werden)

Das Weltkoordinatensystem in PovRay ist fest, was zur Folge hat, daß man die Kamera durch die Welt bewegt und Objekte durch Transformationen positioniert. RenderMan verhält sich genau umgekehrt: die Kamera befindet sich an einer festen Stelle und man verändert das Weltkoordinatensystem, um unterschiedliche Ansichten zu erhalten. All das wird verständlicher werden, wenn wir ein Beispiel "sezieren".

RenderMan hat viele eingebaute Funktionen, sowohl zur Definition von Objekten als auch für Lichter usw. Wir werden uns jetzt als Beispiel einige Quadriken anschauen. Andere eingebaute Objekte (Primitive) wären Bezier-patches oder Polygone.

   Scheibe    Höhe    Radius    Thetamax 

    Scheibe     5            10            300 

    Kegel    Höhe    Radius    Thetamax 

    Kegel    15            10            300 

Zylinder    Radius    zmin    zmax    thetamax 

    Zylinder    10            -5        10        300 

 Kugel    Radius    zmin    zmax    thetamax 

    Kugel     10        -4            8            300 

Torus    gr Rad    kl Rad    phimin    phimax    thetamax 

    Torus    10           &nbs p;        4            &nb sp;   90            320            300 

Paraboloid    Radius    zmin    zmax    thetamax 

    Paraboloid     10            4            15        300 

   Hyperboloid    Punkt1            Punkt2        thetamax 

    Hyperboloid    0 10 -5        10 5 15        300 

Es mag dem aufmerksamen Leser schon aufgefallen sein, daß das Format dieser Primitive nicht gerade einfach ist, was aber nicht allzu schlimm ist, da die RIB Datei von einem Modeler erzeugt wird; für diese Schnittstelle ist das Dateiformat knapp genug und angemessen.

Installation

Als erstes müssen wir das Programm von der Blue Moon Rendering Tools-Seite herunterladen. Die aktuelle Version ist im Moment 2.3.6. Das Archiv läßt sich wie gewohnt auspacken:
rabit:~/$ gzip -d BMRT2.3.6.linux.tar.gz
rabit:~/$ tar xvf BMRT2.3.6.linux.tar

Das Auspacken erzeugt das Verzeichnis BMRT2.3.6. Es enthält ausführbare Programme (in bin/), Beispiele (in examples/) und die Anleitung, sowohl als PostScript als auch als HTML (in doc/), Die README Datei enthält zusätzliche Hinweise für die Installation.

Erste Schritte

Um uns an RenderMans Benutzung zu gewöhnen, gehen wir Schritt für Schritt durch ein typisches Beispiel (../../common/May1998/disptest.rib). Die folgende Abbildung kann mit dem Befehl rendrib -v ../../common/May1998/disptest.rib erzeugt werden (ein Klick auf das Bild liefert es in 1024x768 Auflösung und mit 2x2 anti-aliasing).

../../common/May1998/disptest.rib ist eines der vielen Beispiele im Verzeichnis examples von BMRT. Der Leser wird feststellen, daß die Datei, aus der es erzeugt wurde, nicht sehr groß ist. Das Erzeugen von Animationen läßt die Dateigröße natürlich beträchtlich wachsen.

Das Verzeichnis bin enthält mehrere Programme: rendrib, rendribv und rgl. rendrib ist der eigentliche Renderer, rendribv funktioniert ähnlich, nur daß es Objekte als "Wireframes" zeichnet, und rgl rendert Polygone. Die beiden letzten Renderer werden dazu verwendet, schnell eine Grobversion der Szene (preview) zu erhalten, wohingegen rendrib für das endgültige Rendern benutzt wird.

Das RIB Format (Renderman Interface Bytestream) ist einfach, ohne dadurch an Ausdruckskraft einzubüßen. RIB Dateien werden als einfache ASCII Dateien gespeichert, genau wie die entsprechenden Dateien für PovRay. Eine ordentliches RIB Datei enthält die folgenden Elemente:

  1. Globale Optionen für alle frames (Auflösung, Anti-Aliasing, etc...)
  2. FrameBegin
  3. Initialisierung der Optionen für diesen Frame (Name der Ausgabedatei, Level of Detail, etc...)
  4. Graphikattribute für diesen Frame (Lichter, welche Projektion, etc...)
  5. WorldBegin
  6. Änderungen am Graphikzustand und Festlegen der Geometrie des aktuellen Frames.
  7. WorldEnd. Dieser Eintrag hat zur Folge, daß der Frame gerendert und gespeichert wird, alle Lichter und Geometrieänderungen, die in (6) definiert wurden, werden gelöscht und der Graphikzustand ist derselbe wie direkt vor Schritt (5)
  8. FrameEnd. Dies stellt den internen Zustand von Schritt (2) wieder her.
  9. Die Schritte (2) bis (8) werden für alle folgenden Frames wiederholt.

Der Graphikzustand enthält alle Informationen, die benötigt werden, um Primitive zu zeichnen. Er besteht aus zwei Teilen: einem globalen Zustand, der allen Primitiven gemeinsam ist und einem aktuellen Zustand, individuell für jedes primitive Objekt. Die Parameter des globalen Zustands heißen Optionen, und die des aktuellen Zusatnds heißen Attribute.

Wir werden jetzt Zeile für Zeile das folgende Beispiel analysieren und so besser verstehen, wie die verschiedenen Optionen und Attribute verwendet werden und wie Szenen mit RenderMan beschrieben werden.

 1.-  ##RenderMan RIB-Structure 1.0   
 2.-  version 3.03   
 3.-   
 4.-
###########################################################################   
 5.-  #   
 6.-  # Diese RIB Datei zeigt einige komplexe prozedurale Texturen.   
 7.-  # Zwei Kugeln zeigen, wie "stucco" und "dented" displacement shaders
 benutzt werden.
 8.-  # Der Boden zeigt den gmarbtile_polish shader, polierte grüne
Marmorkacheln.
 9.-  # Der Shader erzielt die Reflektionen durch Aufruf der   
 10.- # Funktion trace() function, statt reflection mapping zu benutzen.
 11.- #   
 12.-
###########################################################################   
 13.-   
 14.- Option "searchpath" "shader" [".:../shaders:&"]   
 15.- Display "balls2.tif" "file" "rgb"   
 16.- Format 400 300 -1   
 17.- PixelSamples 1 1   
 18.-   
 19.- Declare "prmanspecular" "integer"   
 20.- Option "render" "prmanspecular" [0]   
 21.- Projection "perspective" "fov" 35   
 22.- Translate 0 -0.55 8   
 23.- Rotate -110 1 0 0   
 24.-   
 25.-   
 26.- WorldBegin   
 27.-   
 28.- LightSource "ambientlight" 1 "intensity" 0.02   
 29.-   
 30.- Declare "shadows" "string"   
 31.- Attribute "light" "shadows" "on"   
 32.- LightSource "distantlight" 1 "from" [0 1.5 4] "to" [0 0 0]
"intensity" 0.6   
 33.-   
 34.- AttributeBegin   
 35.-   Declare "txtscale" "float"   
 36.-   Declare "Kr" "float"   
 37.-   Declare "darkcolor" "color"   
 38.-   Declare "lightcolor" "color"   
 39.-   Declare "veincolor" "color"   
 40.-   Surface "gmarbtile_polish" "Ka" 1 "txtscale" 0.5 "Kr" .25 "Kd" 0.3
"Ks" 0.2 "roughness" 0.02   
 41.-   Patch "bilinear" "P"  [ -5 -5 0 5 -5 0 -5 5 0 5 5 0  ]   
 42.- AttributeEnd   
 43.-   
 44.- AttributeBegin   
 45.-   Color  [ .6 .6 .6 ]   
 46.-   Translate -1.5 0 1   
 47.-   Surface "matte"   
 48.-   Declare "frequency" "float"   
 49.-   Declare "Km" "float"   
 50.-   Displacement "stucco" "frequency" 20 "Km" 0.3   
 51.-   Sphere 1 -1 1 360   
 52.- AttributeEnd   
 53.-   
 54.- AttributeBegin   
 55.-   Translate 1.5 0 1   
 56.-   Color 1 .45 .05   
 57.-   Declare "Kr" "float"   
 58.-   Declare "Km" "float"   
 59.-   Surface "shiny" "Kd" 0 "Kr" 0.25 "roughness" 0.15 "specularcolor"
[1 .5 .06]   
 60.-   Displacement "dented" "Km" 0.5   
 61.-   Sphere 1 -1 1 360   
 62.- AttributeEnd   
 63.-   
 64.- WorldEnd   

Kommentare in einer RIB Datei werden mit # begonnen und gehen bis zum Ende der Zeile (genau wie // Kommentare in C++). Kommentare können überall in der Datei verwendet werden.

Zeile 2 zeigt ein Beispiel der version Anweisung. Es gibt an, das die Version des benutzten Interfaces 3.03 ist; die neueste Version ist 3.1 vom September 1989 (ja, 1989, kein Fehler), obwohl es eine Revision vom Mai 1995 gibt.

Die Anweisungen searchpath und shader in Zeile 14 definieren den Pfad für die "Shader"; das sind Objekte, die dem Renderer mitteilen, wie ein bestimmtes Objekt zu rendern ist (als Solid, transparent, usw.), da die Texturen der Objekte als Plug-Ins implementiert sind, was das Interface sehr mächtig macht und das Hinzufügen neuer Texturen und Effekte sehr erleichtert. Diese Einstellungen werden gewöhnlich mit der Environment-Variablen SHADER vorgenommen.

Die Option Display erscheint auf Zeile 15. Sie legt fest, daß die Ausgabe in die Datei "balls2.tiff" erfolgt, und vom Typ "file" "rgb" sein soll.

Zeile 16 definiert die Auflösung des Bildes mit der Option Format. Die Auflösung für unser Beispiel ist 400x300, die -1 definiert das Seitenverhältnis (der Wert sollte +1 sein, ich bin nicht sicher, warum hier -1 verwendet wurde).

Die nächste Zeile gibt an, wieviele Rays für jedes Pixel verwendet werden sollen. Jedes Pixel wird dabei in horizontale und vertikale Richtung in die angegebene Anzahl von Subpixeln unterteilt. Die Angabe PixelSamples 2 2 resultiert in 4 Rays durch jedes Pixel, was die Bildqualität erheblich verbessern kann, natürlich unter Vergrößerung der Rechenzeit. Unser Beispiel kann mit 1 x 1 = 1 Rays pro Pixel in zufridenstellender Qualität und Geschwindigkeit gezeichnet werden.

Zeile 19 definiert den Eintrag prmanspecular vom Typ integer. prmanspecular ist jetzt ein Token, das von einer ganzen Zahl gefolgt werden muß.

Zeile 21 gibt an, daß eine Zentralprojektion verwendet werden soll und daß die Größe des Sichtfelds ("fov") 25 Grad beträgt.

Die Zeilen 22 und 23 definieren die Kameraposition durch eine Verschiebung gefolgt von einer Drehung. Transformationen werden immer in "von rechts nach links" angewendet: hier, zuerst die Drehung, dann die Verschiebung (Anm. des Übers: das ist dasselbe wie in mathematischer Notation). Die Transformationen werden erst ausgeführt, wenn RenderMan den Eintrag WorldBegin findet. Die Drehung ist eine Drehung um -100 Grad um die X Achse. (eine 45 Grad Drehung um die Y Achse kann durch Rotate 45 0 1 0 erzielt werden) Die Verschiebung erfolgt um -0.55 Einheiten entlang der Y-Achse und um 8 Einheiten entlang der Z-Achse. Es ist wichtig, daß nicht die Kamera sondern das Weltkoordinatensystem transformiert wird. (Anm. des engl. Übers.: OpenGL benutzt dasselbe Schema) Die folgenden Abbildungen zeigen verschiedene Zustände während der Transformationen:

Nach diesen globalen Definitionen kommt jetzt die eigentliche Szene. Jede Szene (bestehend aus Lichtern, Objekten usw.) beginnt mit einem WorldBegin und endet mit einem WorldEnd. (Zeilen 26 und 64) Die ersten Zeilen (28 bis 32) deklarieren die Beleuchtung; jedes Licht hat eine (eindeutige) Nummer. Das erste Licht ist Streulicht (ambient light) und hat die Intensität 0.02. Als nächstes wird die Variable shadows vom Typ string deklariert und die Beleuchtungsoption für Schattenwurf aktiviert. Zeile 32 fügt eine Lichtquelle vom Typ distantlight, eine unendlich ferne Lichtquelle, wie z.B. die Sonne, hinzu und gibt diesem erneut die Nummer 1; wie oben beschrieben sollte diese Zahl eine andere (z.B. 2) sein. Da die BMRT aber anscheinend diese Nummern ignorieren, hat das keine Konsequenzen, obwohl wir uns um der lieben Kompatibilität, z.B. mit Pixars PRMan, willen strikter an die Definition des Interfaces halten sollten. Die Intensität für die zweite Lichtquelle ist 0.6; der Richtungsvektor, der durch die from und to Angaben definiert wird, schickt alle Lichtstrahlen parallel zu diesem Vektor, wie sich das für eine unendlich ferne Lichtquelle gehört.

Die drei Objekte, die die Szene ausmachen, werden jedes zwischen einem AttributeBegin und AttributeEnd deklariert, da jedes Objekt seine eigenen Eigenschaften hat (sowohl Position als auch Erscheinung). Wenn sich nur die Position von Objekt zu Objekt ändern würde, könnte man die Textur global deklarieren und die Objekte dann mittels TransformBegin und TransformEnd definieren. Das erste Objekt (Zeilen 34 bis 42) ist ein patch. Patches können auf unterschiedliche Weise konstruiert werden: uniform oder nicht-uniform, rational oder polynomial und bilinear oder bikubisch usw. Bikubische patches führen zu Bezier und B-Spline patches; näheres dazu kann man in den meisten Büchern über Computergraphik finden. Unser Beispiel enthält einen bilinearen patch durch vier Punkte; die Geometrie des patches wird durch ein "P" gefolgt von den (x,y,z)-Koordinaten der Punkte definiert. Die Textur des Objektes wird durch den Befehl Surface gezeichnet; das erste Argument ist eine shader-Datei und die restlichen Argumente sind spezifisch für den gewählten shader. Das nächste Bild zeigt die Szene, die wir bis jetzt konstruiert haben.

Die Zeilen 44 bis 52 definieren etliche Objekte in der Szene: eine Kugel (Zeile 51), deren Farbe mit der Angabe Color [R G B] festgelegt wird. Die Kugel wird verschoben und erhält eine Oberfläche vom Typ matte. Als nächstes kommt die wichtigste Eigenschaft von BMRT: die Displacement shaders. Sie funktionieren analog zu bump-maps in PovRay, nur daß in BRMT die "bumps" nicht simuliert sind, sondern echt. Der erzielte Effekt ist, daß sowohl die Oberfläche als auch die Ränder der Kugel rauh erscheinen. Displacement shaders sind denen für Texturen sehr ähnlich, sie werden stets durch den Namen des gewünschten shaders gefolgt von den zugehörigen Parametern deklariert. Die Spezifikation der Kugel ist etwas gewöhnungsbedürftig: zuerst kommt der Radius, dann zmin und zmax, die die Kugel in Richtung der z-Achse abschneiden (z.B., die Werte -1 und 1 würden keine Änderungen der Kugel zur Folge haben, wohingegen die Werte 0 und 1 die Kugel halbieren würden), der letzte Wert gibt den Winkel (in Grad) an, den die Kugel umfaßt (360 ist die ganze Kugel, 180 eine Halbkugel, usw.) Hier ist ein Bild der Kugel in ihrer Position:

Das nächste Bild unterscheidet sich vom letzten nur dadurch, daß die Textur- und Displacementparameter geändert wurden. Es ist daher unnötig, daß ich dieselben Erklärungen nochmals gebe; wir können einfach den Code benutzen und erhalten das folgende:

Damit ist unsere Beschreibung der Eingabedatei vollständig. Es sollte klargeworden sein, daß das Entwerfen von Szenen nicht komplex ist, daß aber eine komplizierte Szene oder Animation die Datei sehr komplex machen kann. Um dem zu entgehen, genügt es, einen Modeler zu verwenden, der RenderMan unterstützt (jeder Modeler, der etwas auf sich hält, kann RIB Dateien exportieren); alternativ kann die Animation in C programmiert werden. Die Distribution der BMRT enthält ein include Verzeichnis und die nötigen Bibliotheken. Sie enthalten Funktionen, die die RIB Datei auf der Standardausgabe erzeugen. Beide Methoden sind identisch: dem WorldBegin in einer RIB Datei entspricht der Aufruf RiWorldBegin() in einem C Programm. (Um mehr darüber zu lernen, sollte man RenderMan for Poets im doc/ Verzeichnis lesen.)

Ausblick

RenderMan ist ein mächtiges Interface, das unter anderem bei der Herstellung von Toy Story benutzt wurde, zusamen mit einem Modeler namens marionet. Die Seite www.toystory.com enthält einige Artikel im Zusammenhang mit dem Film. Die Spezifikation des RenderMan Interfaces befindet sich in giga.cps.unizar.es. Zusätzlich zur Spezifikation gibt es noch das PRMan Manual (Pixars Renderer) und mehr Beispiele.

Im nächsten Artikel werden wir ein kleines Objekt modellieren. Wir werden dazu C verwenden; das hat den Vorteil, daß es später einfacher ist, Animationen zu erzeugen und wird uns natürlich auch die Programmier-Bibliothek näher bringen. Das Objekt, das wir animieren werden, könnte ein Linux-Pinguin sein, oder vielleicht Bill Gates (oder beide; wir könnten vielleicht auch den Pinguin dazu bringen, sich einen Bill Gates zu braten... :)


Weitere Informationen:

Webpages maintained by Miguel Ángel Sepúlveda
© Carlos Calzada Grau 1998
Übersetzt von:David Lutterkort
LinuxFocus 1998