Raytracing mit POV-Ray: Erstellen von Texturen



Grundsätzliches zu Oberflächen

Bearbeiten

In diesem Kapitel lernen wir, wie man (kompliziertere) Oberflächen (Texturen) erstellt. Dabei setzt sich die Oberfäche aus folgenden Elementen zusammen:

  • pigment: Die Farbe des Objekts, kann zum Beispiel auch ein auf das Objekt projiziertes Bild sein. (Dies muss immer angegeben werden)
  • normal: Die Oberflächenstruktur. Die Oberfläche kann glatt sein, sie kann auch rau sein oder regelmäßig strukturiert.
  • finish: Die Politur der Oberfläche, von glänzend bis matt.

Grundsätzlich sieht damit eine Obfläche in der povray Syntax folgendermaßen aus:

sphere { <0,0,0> 1
    texture {
        pigment { ... }
        normal  { ... }
        finish  { ... }
    }
}

Sowohl für Farben als auch für Strukturen (Texturen) gibt es vorgefertigte Include-Dateien, die mit jeder povray Installation mitkommen.

Unter Linux liegen diese Dateien unter "/usr/share/povray/include"

colors.inc
Diverse Farben
textures.inc
Allgemeine Texturen
glass.inc
Glas
metals.inc
Metalle, je 5 Oberflächen für Messing, Kupfer, Silber und Chrome
golds.inc
Gold T_Gold_[XY] Wobei für X Werte von 1 - 5 und für Y Werte von A - E eingesetzt werden können
stones1.inc
Diverse Gesteinsarten T_Stone1 bis T_Stone24
stones2.inc
Diverse Gesteinsarten T_Stone25 bis T_Stone44
stones.inc
Zusammenfassung der vorherigen beiden Includes
skies.inc
Wolken für die Himmelskugel
woods.inc
Diverse Hölzer, T_Wood1 - T_Wood_34

Farben werden in Povray durch 5 Zahlenwerte definiert:

rgbft<1,0,0,0,0>

Die ersten drei geben den Rot-, Grün-, und Blau-Anteil der Farbe an, der vierte Wert ist der filter-Wert, der letzte der transmit-Wert.

Wenn f oder t oder beide nicht vorhanden sind, werden die fehlenden Werte auf 0 gesetzt.

Ein rotes Objekt mit einem transmit-Wert von 0.7 wird also beschrieben durch:

rgbt<1,0,0,0.7>

Dabei wir der filter-Wert auf 0 gesetzt.

Die in "colors.inc" vordefinierten Farben kann man auch mit zusätzlichen filter- und transmit-Werten versehen, zum Beispiel durch

color Red filter 0.4

oder

color Green transmit 0.8


RGB-Farben

Bearbeiten

Man kann in Povray die vordefinierten Farben aus "colors.inc" benutzen. Wer jedoch für bestimmte Zwecke ganz individuelle Farben benötigt soll auch nicht zu kurz kommen. Man braucht in "pigment" nur das "color White" durch

rgb<1,1,1>

zu ersetzen.

Wie unschwer zu erkennen ist, handelt es sich um die rgb-Funktion die vielleicht schon von HTML o.ä. bekannt ist. Die drei Werte in den spitzen Klammern stehen für den Rot-,Grün- und Blauanteil der Farbe zwischen 0 und 1. Ein paar Beispiele:

rgb<0,0,0> //Schwarz
rgb<1,0,0> //Rot
rgb<0,1,0> //Grün
rgb<0,0,1> //Blau
rgb<1,1,0> //Gelb
rgb<1,0,1> //Pink
rgb<0,1,1> //Türkis
rgb<1,0.5,0> //Orange
rgb<0,0.5,0> //Waldgrün

transmit

Bearbeiten
 
Transparenz zwischen 0 und 1

Mittels

rgbt<1,1,1, 0.7>

lassen sich transparente Farben definieren, die vierte Zahl steht dabei für die Durchlässigkeit, wobei 1 völlig transparent ist. Dabei wird einfach zur Farbe des Objekts ein Anteil der durch das Objekt hindurch scheinenden Farbe hinzu addiert. Im Beispiel wird zu 70% (wegen transmit=0.7) des hindurch scheinenden Lichts 30% des Lichts des Objekts addiert.

Transmit kann man verwenden, um zum Beispiel die Farbe eines Vorhangs festzulegen.

Ähnlich wie bei transmit scheint ein Teil des Lichts durch das Objekt hindurch. Nur wird diesmal das Licht durch das Objekt gefiltert.

Beispiel:

sphere {
   texture {
      pigment {color Red filter 0.7 }
   }
}

Hier wird eine Kugel als Rotfilter definiert. Der Rot-Anteil des hindurch scheinenden Lichts kann passieren, der Blau- und Grün-Anteil wird verschluckt. Wieder werden wegen filter=0.7 70% des gefilterten hindurch scheinenden Lichts mit 30% der Farbe der Kugel, in diesem Fall mit Rot, gemischt.

Muster (Patterns)

Bearbeiten

Patterns (Muster) sind Funktionen, die jedem Ort im Raum einen Wert zwischen 0 und 1 zuordnen. Diesen Werten können dann zum Beispiel Farben (color_map) oder Oberflächennormalen (normal_map) zugewiesen werden. Ein Pattern ist also immer eine Funktion im Raum und kein 2-dimensionales Muster, das um die Objekte herum gewickelt wird.

Am besten stellt man sich einen Block (Holz, Stein, etc.) vor, in dem das Muster durchgehend vorhanden ist. Die Objekte werden aus diesem Block herausgeschnitten.

Bei ein paar patterns (brick, checker, hexagon, object) kann man nur zwei bis drei Werte (z.B. Farben) setzen, bei allen anderen kann man den Zahlen von 0 bis 1 beliebige Farben, Normalen, Texturen, etc. zuordnen.

Farbmuster

Bearbeiten

Man kann Farbmuster mit einer "color_map" definieren. Im Beispiel wird "gradient y" verwendet. Diese Funktion steigt in y-Richtung an. Im Prinzip wird von jedem Punkt im Raum einfach nur die y-Koordinate gewählt. Da ein pattern in Povray einen Wert zwischen 0 und 1 liefern muss, wird dabei der Teil der y-Koordinate vor dem Komma abgeschnitten. gradient y steigt also immer von 0 nach 1 an, fällt dann abrupt auf 0 zurück, steigt wieder an, usw.

In einer "color_map" wird nun in eckigen Klammern den Werten zwischen 0 und 1 Farben zugewiesen. Die Farbübergänge sind fließend.

 
pigment{
  gradient y
  color_map{
    [0.2 color Blue  ]
    [0.4 color Red   ]
    [0.6 color Yellow]
    [0.8 rgb<0,1,0>  ]
    [1.0 rgb<0,0,1>  ]
           }
      }


 

In diesem Fall erhält man die Regenbogenfarben von unten nach oben. Auch hier kann man mittels "scale<x,y,z>" die Textur stauchen bzw. strecken. Wie man sieht, wird ein mehr oder minder weicher Farbübergang erzielt. Will man scharfe Grenzen, so ist die Farbe an beiden Kanten anzugeben. Mit entsprechender Skalierung kann man diese nun nutzen, um Entfernungen anzuzeigen.

#declare Axis_texture = //
pigment {
  gradient <1,0,0>
  color_map {[0.0 color <1,1,1>]
    [0.5 color <1,1,1>]
    [0.5 color <1,0,0>] 
    [1.0 color <1,0,0>]
  }
    scale 2 
}

Damit es nicht so langweilig wird kann man nun im wahrsten Sinne des Wortes Turbulenz einbringen: "turbulence" verzerrt die gesamte Textur.

 
Das obige Bild etwas turbulenter
pigment{
    gradient y
    color_map{
        [0.2 color Blue  ]
        [0.4 color Red   ]
        [0.6 color Yellow]
        [0.8 rgb<0,1,0>  ]
        [1.0 rgb<0,0,1>  ]
              }
   turbulence 1
   }

So wird das obige Beispiel etwas "verwirbelt".

Neben gradient kann man die Farben auch noch mit weiteren Mustern versehen In der Beschreibung des jeweiligen Bildes ist auch der Quelltext enthalten




Oberflächenstruktur (normal)

Bearbeiten

Eine wirklich raue Oberfläche zu modellieren, wäre rechnerisch viel zu aufwändig. Povray geht deswegen anders vor. Die Ausleuchtung der verschiedenen Oberflächenpunkte eines Objekts und die Reflexion an dieser Stelle hängt von der Orientierung dieses Oberflächenstücks im Raum ab. Dies Orientierung wird festgelegt durch einen Normalenvektor. Das ist ein Pfeil, der senkrecht auf der Fläche steht. Wenn man nun diese Normale verändert, scheint die Oberfläche eine Struktur zu haben, obwohl sie rechnerisch völlig glatt ist.

In der normal-Anweisung kann man alle in Povray vorhandenen Muster (=patterns) verwenden.

Beispiel:

normal {
   granite
   scale 0.4
}

Diese Anweisung erzeugt eine raue Oberfläche, wie z.B. Granit. Je nach Entfernung des Objekts von der Kamera muss man mit scale die Oberflächenstruktur verkleinern oder vergrößern, um ein gutes Ergebnis zu erhalten.


slope_map

Bearbeiten

Man kann den Werten zwischen 0 und 1, die ein pattern ausrechnet, direkt eine Normale zuordnen. Dies geschieht durch eine slope_map. Die Syntax ist ähnlich wie bei einer color_map.

normal {
   gradient x
   slope_map {
      [0    <0,1> ] //Beginn bei 0, Steigung 1
      [0.25 <1,0> ] //Im höchsten Punkt bei 1 Steigung 0
      [0.5  <0,-1>] //Es geht wieder abwärts zu 0, an dieser Stelle Steigung -1
      [0.75 <-1,0>] //Im tiefsten Punkt bei -1 Steigung 0
      [1    <0,1> ] //Wir sind wieder am Ausgangspunkt bei 0 mit Steigung 1
   }
}

Jedem Wert zwischen 0 und 1 werden hier zwei Werte zugewiesen: Die relative Höhe über der Oberfläche und die Steigung an dieser Stelle. Mit dem regelmäßigen Muster gradient x wird hier also eine gewellte Oberfläche modelliert.

normal_map

Bearbeiten

Man kann auch patterns verschachteln, also den Werten, die ein pattern ausrechnet, andere Werte zuordnen.

Beispiel:

normal {
   gradient x
   normal_map {
      [0 granite scale 1]
      [0.5 granite scale 0.1]
   }
}

Hier würde eine raue Oberfläche entstehen mit ständigem Wechsel von grober zu feiner Körnung.

Politur (finish)

Bearbeiten

Image Maps

Bearbeiten
 
Projektion auf eine Kugel im Koordinatenursprung
 
Projektion auf eine verschobene Kugel

Mittels "image_map" lassen sich beliebige Bilder auf Objekte projizieren. Allerdings sollte man bei den Projektionen bedenken, daß die Objekte u. U. im Koordinatenursprung stehen und anschließend verschoben werden sollten, um unvorhersehbare Verzerrungen zu vermeiden.

sphere {
  <0, 0, 0>, 2
  texture {
    pigment {
      image_map {
	jpeg  // Welcher Dateityp: gif, iff, jpeg,  pgm, png, ppm, sys, tga, tiff
              // (sys je nach Betriebssystem, für Windows erzeugt 'sys' bmp)
        "/tmp/jigsaw.jpg"
	map_type 1 // Abbildungstyp: 0:planar, 1:spherical, 2:cylindrical, 3/3: reserviert 5:torus
	interpolate 2 // 0:none, 1:linear, 2:bilinear,
      }
      translate <1,2,0>
    }
  }
}

Bump Map

Bearbeiten

bump_map ist Anteil von normal und beschreibt die Oberflächenbeschaffenheit einer Textur anhand einer Bilddatei, der sog. Bump Map. Tatsächlich wird beim Bumpmapping nicht die Oberfläche eines Körpers verändert. Vielmehr werden einer Textur Schattenflächen hinzugefügt. Diese Schattenflächen vermitteln den Eindruck einer unplanen Oberfläche.

Aus den Farbwerten der Bump Map - Bilddatei werden theoretische Vertiefungen in der Oberfläche des texturierten Objektes berechnet. Weiß erzeugt keine Vertiefung, Schwarz die maximale Vertiefung. Der Faktor der Vertiefung kann über bump_size eingestellt werden. Bei indizierten Bump Map - Bilddateien kann anstelle des Farbwertes mit use_index auch der Index der Farbwerte verwendet werden.

Als Bump Map - Bilddateien können tga,gif,png,jpeg und tiff-Dateien verwendet werden. Bevorzugt sollten nahlos - kachelbare Texturen als Bumpmaps verwendet werden.

Die Schattenflächen errechnen sich aus dem Blickwinkel auf das Objekt, dem Lichteinfall und den theoretischen Vertiefungen in der Oberfläche des Objektes.

Bumpmapping erreicht seinen grössten Effekt bei einem steilen Winkel von Kamera zur Objektoberfläche und stark seitlichem Lichteinfall. Bei Lichtenfall senkrecht zur Objektoberfläche oder bei einem Blickwinkel der Kamera parallel zur Objektoberfläche verliert Bumpmapping seine Wirkung. Der Effekt ist vergleichbar mit dem Blick auf ein Lochblech, dessen Löcher von der flachen Seite aus betrachtet, nicht zu sehen sind.


Schatten/Reflexion...

Bearbeiten

Stehen für reine Farben als auch für Texturen zur Verfügung. Sie werden immer mit der finish-Anweisung eingeleitet, in die man dann die einzelnen Werte eingibt. Es stehen die folgenden Optionen zur Verfügung:

  finish {
    ambient 0.1          // Umgebungsfarbe  [0.1]
    // (---diffuse lighting---)
    diffuse 0.6          // amount [0.6]
    brilliance 1.0       // tightness of diffuse illumination [1.0]
    // (---phong highlight---)
    //phong 0.5          // amount [0.0]
    //phong_size 40      // (1.0..250+) (dull->highly polished) [40]
    // (---specular highlight---)
    //specular 0.5       // amount [0.0]
    //roughness 0.05     // (~1.0..0.0005) (dull->highly polished) [0.05]
    // (---phong and specular---)
    //metallic [Amount]  // give highlight color of surface
    // (---reflection---)
    /*
    reflection {
      //0.0                      // minimal reflection value (for variable reflection)
      1.0                        // reflection amount (maximum for variable reflection)
      //fresnel on               // realistic variable reflection
      //falloff 1.0              // falloff exponent for variable reflection
      //exponent 1.0             // influence surface reflection characteristic
      //metallic 1.0             // tint reflection in surface color
    }*/
    //conserve_energy            // more realistic
    // (---others---)
    //crand 0.2                  // randomly speckle the surface [0.0]
    /*
    irid {               // Iridescence (Newton's thin film interference)
      0.25               // intensity
      //thickness 0.0    // film's thickness [0.0]
      //turbulence 0.3   // film's thickness turbulence
    }*/
  } // finish

Helligkeit/Kontrast

Bearbeiten

Um den durch indirekte Beleuchtung entstehenden Schatten darzustellen verwendet man die "ambient"-Anweisung. Es folgt eine Zahl zwischen 0 und 1. Bei null ist die Stelle ganz schwarz, bei 1 weiß. Für die Helligkeit der direkt beleuchteten Stellen verwendet man "diffuse". Ählich wie bei ambient wird ein Wert zwischen 0 und 1 angegeben. Bei diffuse 0 ist das Objekt schwarz, bei diffuse 1 ist es weiß. Ein Beispiel:

sphere{<0,5,0>,1
 texture{
  finish{ambient 0.15 diffuse 0.85}
 }