HomeMapIndexSearchNewsArchivesLinksAbout LF
[Top Bar]
[Bottom Bar]

von:Antonio Castro

Inhalt:
Die Bilder des Artikels
Grundlagen des Renderns
Die sieben Fehler
Die Skriptsprache von Povray
Grundlegende Konzepte der Animation
POV Ver 2.0
3D-Ansichten
Position
Verschiebung
Drehung
Skalierung
Licht
Kamera

Allgemeine Grundlagen von Povray

Zusammenfassung: Dies ist der zweite Artikel der Serie �ber Povray. Im Moment erkl�ren wir ein paar allgemeine Begriffe und beginnen mit einigen grundlegenden Elementen der Sprache.


Worst seen with Explorer. Try Netscape instead. 

Die Bilder des Artikels.

In diesem Artikel sieht man die Bilder mit verkleinerter Auflösung und im JPG-Format.  Wenn Sie auf das Bild klicken, sehen Sie ein größeres Bild im GIF-Format mit wesentlich besserer Qualität. 

Die Animationen werden mit kleiner Auflösung aufgebaut und nur 15 Phasen im JPEG-Format gezeigt. 
Das wurde so gemacht, um nicht exzessiv Festplattenplatz zu belegen und um das Laden des Artikels zu beschleunigen. 
Auf jeden Fall werden wir wie immer die Quellen anpassen und es steht uns das Skript 'pov' zur Verfügung, welches wir schon im vorigen Artikel vorgestellt haben, damit jeder mit der Auflösung, die er will, rendern kann, oder die Quellen ändern und die Skriptsprache von Povray lernen kann. 

Wenn Sie Povray noch nicht auf ihrem Rechner installiert haben, können Sie das nach der Anleitung im vorigen Artikel tun, mit dem wir die Serie über Povray begannen. Ich empfehle Ihnen, das zu tun. 

Grundlagen des Renderns.

Im vorigen Kapitel erwähnten wir beiläufig die Idee des Raytracens und werden unser Wissen darüber jetzt vertiefen. 
Das Rendern ist die vollständigste Technik, um ein künstliches Bild zu erzeugen. 
Um das zu erreichen, versucht es, auf die realistischste und auf möglichst wenig aufwendige Weise das Verhalten des Lichtes und seine visuellen Effekte in der Realität zu simulieren.

In unserem vorigen Artikel erwähnten wir, daß das Rendern die Anzahl der Lichtstrahlen berechnet, aber merkwürdigerweise verhält sich in diesem Modell die Lichtquelle wie ein "Gully" für die Strahlen und die Kamera wäre der Punkt von dem alle Strahlen ausgehen. Der Grund dafür ist, daß wenn wir das umgekehrt machen, die meisten Strahlen vermutlich unnütz berechnet werden und nur einige wenige die Kamera erreichen! Auf dem umgekehrten Weg erhalten wir jeden einzelnen Punkt des Bildes den wir erreichen wollen. Jeder einzelne Punkt des zukünftigen Bildes entspricht einem Punkt auf dem imaginären Film unserer virtuellen Kamera. Auf diese Weise berechnen wir jeden einzelnen dieser Punkte getrennt. Wir haben Povray so konfiguriert, daß ein Bild berechnet und anschliessend von einem externen Anzeigeprogramm angezeigt wird. Wenn wir Povray für SVGA konfiguriert hätten, hätten wir gezeigt, wie es möglich ist, ein Bild darzustellen, je nachdem wir es berechnen. Das geschieht von Pixel zu Pixel, von links nach rechts und von oben nach unten. Die Reihenfolge ist nicht zufällig. Das übliche Ausgabeformat für Povray ist das 24-bit TGA, und das baut sich genauso auf.  

Wenn Ihnen jemand rät, Povray für SVGA zu konfigurieren (Ich habe das nicht gemacht), werden Sie sehen, daß die Geschwindigkeit des Raytracing davon abhängt, ob wir an einer komplizierten oder objektarmen Stelle des Bildes sind.  
Wir können beobachten, daß die Bereiche im Bild mit vielen Objekten in der Berechnung mehr Zeit brauchen als die, die nur ein Objekt haben oder gar keines. Aus jedem einzelnen Treffer der Strahlen auf die Objekte berechnet sich der entsprechende Lichteffekt unter Überprüfung der Position der Lichtquelle, der Ausrichtung der Oberfläche des Objekts relativ zur Lichtquelle und auch seiner Beschaffenheit in Bezug auf Farbe, Textur und andere im Objekt definierte Eigenschaften. Das Resultat dieser Analyse drückt sich in drei RGB-Werten aus, die die Farbe und die Leuchtkraft dieses Bildpunktes definieren. 

Ein Exkurs 

Das 24bit TGA Format braucht zwar viel Platz, ist aber leicht zu erzeugen und zu bearbeiten. 

Jedes Pixel braucht 8 bits, um seine Farbe in RGB zu kodieren. 
8bits *3 = 24 bits; 2^24 = 16777216 (16 Millionen Farben) 

Um Höhe und Breite zu ermitteln:  

int w, h, i; 
fseek(fi, 12L, SEEK_SET); 
fread(&w, 2L, 1L, fi); /** pos 12 **/ 
fread(&h, 2L, 1L, fi); /** pos 14 **/ 

Das erste Pixel einlesen: 

fseek(fi, 16L, SEEK_SET); /** pos 16 **/ 
Blue=fgetc(fi); 
Green=fgetc(fi); 
Red=fgetc(fi); 

 
 

Es wäre schon einfach mit dieser Information möglich, irgendwelche Bilder zu bearbeiten, um bestimmte Effekte zu erreichen. 
Wenn Sie geschickt im Programmieren sind, schlagen wir Ihnen die folgenden Übungen vor: 

1) Ein Bild aufhellen/verdunkeln  (Die weissen Pixel haben  255,255,255, und die Schwarzen 0,0,0) 
2) Ein Bild mit schwarzem Hintergrund vor eines legen, das Schwarz als transparent behandelt.
3) Die Bilder zu einem Durchschnitt verschmelzen 
4)  Eine Farbe hervorheben/abschwächen
5) Das Farbhistogramm eines Bildes erstellen (Liste der Farben und ihrer Häufigkeiten). 

Die Sachen kann man normalerweise mit einem Hilfsprogramm machen, aber es könnte sein, daß wir einmal eine einfache Bearbeitung machen wollen, aber trotzdem kein Werkzeug finden, das sie macht.
Das 24 bit TGA-Format ist da sehr gut zu handhaben . 

Exkurs Ende 

Wir wollen einen Aspekt dieses Prozesses hervorheben. Die Strahlen verlassen einen Punkt des photosensiblen Films unserer virtuellen Kamera, aber um die resultierende Farbe zu berechnen, müssen wir vergleichen, ob eines der defiinierten Objekte des Szenarios den Strahl abfängt. Im Fall daß das zutrifft, fährt Povray fort, indem er die Eigenschaften der vom Strahl getroffenen Stelle des Objekts analysiert. Es gibt eine sehr effektive Optimierungstechnik, wenn Sie komplexe Objekte entwerfen. Sie besteht in der Definition eines unsichtbaren und sehr einfachen Objekts mit der Form des  ganzen komplexen Objekts in seinem Inneren. Üblicherweise werden Kugeln oder Quader als einfache Objekte verwendet. Die Idee dahinter ist, daß dieses Objekt dazu dient anzuzeigen, ob ein Strahl auf dieses Objekt (und damit auf das komplexe in seinem Inneren) trifft. Das erspart viel Rechenarbeit. Das einfache Objekt heißt "bounced_by", und ich  habe es deshalb jetzt erwähnt, weil es sehr gut zeigt, wie ein Raytracer arbeitet. Wir werden ein Beispiel weiter unten in diesem Artikel behandeln, wenn wir über zusammengesetzte Figuren sprechen. 

Es ist interessant zu sehen, daß die Dinge in einem Raytracer nicht immer so sind, wie sie erscheinen. 

Die sieben Fehler.

Um das bisher gesagte zu veranschaulichen, werden wir ein Bild zeigen, bei dem verschiedene Techniken verwendet wurden, wobei der angewandte Trick offenbar wird. 

Dem Bild habe ich den Titel „Die 7 Fehler“ gegeben. 

LF2-7errores.gif 

7errores

Wenn wir aufmerksam hinschauen, sehen wir, daß das Bild in einigen Aspekten nicht normal erscheint. 

  1. Es gibt eine einzige intensive Lichtquelle, die sich im Zentrum eine Ringes befindet, aber obwohl man fast direkt auf diesen Punkt schaut, kann man ihn nicht sehen. 
  2. Wir haben ein Stück hinter dieser Lichtquelle eine weiße Kugel gesetzt, die einen Schatten auf den Himmel projiziert. Aufgrund dessen erkennen wir, daß wir anstelle eines Himmels eine billige Dekoration haben, denn der Schatten zeigt uns die Anwesenheit einer soliden Himmelskuppel an. 
  3. Das Meer hat Wellen, aber es besteht aus einer feinen, total ebenen Oberfläche. Um es erkennen zu können haben wir das Meer abgeschnitten und wir sehen, daß der Schnitt ganz gerade ist (ohne Wellen). 
  4. Auf einer nahegelegenen Ebene befinden sich drei Quader. Wir sehen, daß der mittlere keinen Schatten wirft. 
  5. Wenn man die drei Quader zusammen betrachtet, ergibt sich eine seltsame Situation. Welche Art der Beleuchtung liegt wirklich vor? Ein direkter Lichtstrahl, der harte Schatten erzeugt, oder diffuses, indirektes Licht, welches weiche Schatten bewirkt? Anscheinend ist das umgebende Licht für jeden Quader verschieden. 
  6. Die Glaskugel erscheint auf der linken Seite massiv, aber wir haben auch rechts ein wenig abgeschnitten und ein Objekt von dieser Seite eingeführt, um deutlich zu machen, daß sie auch hohl ist. 
  7. Der siebte Fehler wird deutlich, wenn man das Bild in seiner Gesamtheit betrachtet. Es enthält keine atmosphärischen Effekte und die Luft ist zu transparent. Die Farbe des Meeres müßte ein wenig bläulicher sein und sich in den Hintergrund verlaufen. Die weiße Kugel erzeugt einen Schattenkegel, welcher nicht die geringste Spur in der Luft hinterläßt.
An dieser Stelle können wir nicht auf die Details der vielen angewandten Techniken eingehen. Ich wollte nur zeigen, daß Raytracer Techniken verwenden, die einfach die natürlichen Phänomäne imitieren, allerdings nicht immer realitätstreu, denn der Preis, den man zahlt, ist die Prozessorzeit. Einige Techniken dienen nur dazu, die Fehler, die durch andere Techniken entstehen, zu verstecken. Wichtig ist, daß das Endergebnis ohne übermäßige Rechenarbeit gut wird. 

Lassen wir dies alles wie eine Ansammlung von Rätseln stehen, die der Fortgeschrittene nach und nach auf der Suche nach der infografischen Perfektion lösen wird. Wenn er sie einmal erreicht hat, wird er sich als Meister des virtuellen Universums sehen. 
Und wenn Sie dieser herrliche Beweis nicht überzeugt, macht das auch nichts, denn ich werde jetzt nichts mehr über das kleine Beispiel der sieben Fehler erzählen. 

Die Skriptsprache von Povray.

Noch einmal weisen wir darauf hin, daß diese Artikel über Povray nur einige Themen auf oberflächliche Weise behandeln können. Die Sprache von Povray ist zu umfangreich, um sie ausführlich zu beschreiben. Das einzige, was wir an dieser Stelle tun können, ist in wenigen Zeilen das Wesentliche der Sprache hervorzuheben. 
In Povray gibt es häufig verschiedene grammatikalische Varianten, um das gleiche Ergebnis zu erhalten. Das kommt daher, daß die aktuelle Syntax das Ergebnis von wesentlichen Änderungen zwischen den einzelnen Povray-Versionen ist. Die aktuelle Syntax ist viel besser und wird in Zukunft wohl weniger Veränderungen unterzogen sein. Aus Kompatibilitätsgründen werden alte syntaktische Formen oder ähnliche beibehalten. Ein Beispiel für diese Flexibilität in der Syntax sind die Drehungen, die wir weiter unten sehen werden. 

Es gibt eine Anweisung zur Komplierung, die es erlaubt, Quelltexte von alten Povray-Versionen zu verwenden. 

Beispiel: 
 
Um in demselben Quelltext die Syntax von Version 1, 2, und 3 zu benutzen:  

#version 1.0 
....... 
#version 2.0 
....... 
#version 3.0 
....... 

 
 
 

Dies ermöglicht es, in einem Quelltext die drei Formen der Syntax zu kombinieren, welche den Hauptnummern der Povray-Versionen entsprechen. 

Es wird nicht beabsichtigt, die Syntax komplett durchzugehen. Es gibt dafür eine sehr gute man-page, und dies hier soll kein zweites Handbuch sein.  Wir wollen uns kurz fassen und nur das Wichtigste anschneiden. Wir werden nun einige Fragen in Bezug auf die Sprache ansprechen. 

Kommentare, Deklarationen, include-Dateien. 

Die Kommentare sind wie in C++. 
 

Beispiel: 
 
Setzen von Kommentaren: 

// Dieser Kommentar endet mit dem Zeilenende 
/* Dieser Kommentar endet mit Sternchen-Schrägstrich*/ 
 

 
 

Die Sprachelemente,die mit '#' anfangen, heißen Anweisungen der Sprache (Language Directives). 
Die gebräuchlichsten sind '#declare' und '#include'. 
 

 
Die sogenannten Deklarationen haben folgende Form:  

#declare IDENTIFIER = ITEM 

 
 

Beispiel: 
 
Zur Deklaration von verschiedenen Arten von Elementen:  

#declare Rows = 5 
#declare Count = Count+1 
#declare Here = <1,2,3> 
#declare White = rgb <1,1,1> 
#declare Cyan = color blue 1.0 green 1.0 
#declare Font_Name = "ariel.ttf" 
#declare Ring = torus {5,1} 
#declare Checks = pigment { checker White, Cyan } 

 
 

Der Ausdruck '#declare' erlaubt, eine Vielfalt an Elementen festzuhalten, wie z. B. eine Drehung, ein Muster, eine Farbe, ein Objekt, einen Zahlenwert, usw... 

Ein anderes unverzichtbares Element ist der Verweis auf include-Dateien. 

Sie erlauben, Segmente aus anderen Quellen in den Quelltext zu integrieren. 

Defaultmäßig sucht include im aktuellen Verzeichnis, ansonsten im Library_Path. 
Wir verwenden zwei Stellen: 

Library_Path=${POVRAY}/include // Hier die Povray-includes 
Library_Path=${HOMEPOV}/include // Hier die includes des Anwenders 

So haben wir es in unserer neuen Version von 'pov'  definiert, damit die korrekte Initialisierungsdatei erzeugt wird. Wir werden weiter unten davon sprechen. 

Es gibt eine Anzahl von include-Dateien, die man kennen sollte, um möglichst viel aus Povray herauszuholen. Es ist eine Sammlung von Hilfsmitteln, die nicht nur dazu dienen, integriert zu werden, sondern auch dazu, nach unserem Geschmack veränderte Kopien zu erhalten. 
 
Einige häufig gebrauchte includes: 

#include "colors.inc" 
#include "textures.inc" 
#include "shapes.inc" 
#include "finish.inc" 
#include "glass.inc" 
#include "metals.inc" 
#include "stones.inc" 
#include "woods.inc" 
#include "atmos.inc" 

 

Einige andere Anweisungen der Sprache gestatten das Einfügen von Schleifen und bedingten Verzweigungen. In den ersten Versionen von Povray gab es weder Schleifen noch Bedingungen. Dies und die Tatsache, daß die Beschreibungen der Bildelemente in beliebiger Reihenfolge erscheinen konnten, setzte gegenüber einer tradionellen Programmiersprache eine Veränderung in der Denkweise voraus. 
Die Reihenfolge, in der die Bildelemente aufgeführt werden, ist immer noch gleichgültig, aber die Schleifen ersparen uns, viele ähnliche Zeilen schreiben zu müssen, und die konditionalen Befehle erlauben uns, ein Bild auf verschiedene Weise zu definieren, z. B. als Funktion des Wertes von 'clock', wie es bei Animationen angewandt wird. Wir werden ein Beispiel für eine bedingte Verzweigung in einem späteren Artikel darstellen, wenn wir zusammengesetzte Figuren besprechen. 

Es existieren viel mehr Anweisungen (welche mit '#' beginnen), aber es sei betont, daß die beiden, die wir gerade erwähnt haben, '#declare' und '#include', bei weitem die gebräuchlichsten sind. 
 
Nicht besprechen werden wir Dinge, die in anderen Sprachen ähnlich sind, wie arithmetische Ausdrücke, verschiede Typen von Konstanten, logische und vergleichende Operatoren und solche für Vektoren, vordefinierte Funktionen und vieles mehr.

Wenn Sie eine Variable deklarieren müssen, ist es am günstigsten, einen Großbuchstaben zu verwenden, denn die von der Sprache reservierten Wörter bestehen nur aus Kleinbuchstaben (siehe man-Text).  Wenn Sie in einem Quelltext ein Wort mit einem Großbuchstaben finden, handelt es sich um eine Variable, die irgendwo deklariert ist. Dadurch läßt sich leicht erkennen, ob man in den man-Seiten oder in den includes suchen muß.

Grundlegende Konzepte der Animation.

Dieses Thema so früh zu behandeln, bedarf einer Erklärung. 
Man sagt immer, ein Bild sage mehr als tausend Worte. Das gilt besonders, wenn wir versuchen, die Arbeitsweise eines Raytracers zu erklären. Wir werden versuchen, jedes Konzept ausführlich zu illustrieren, denn ansonsten müßte der interessierte Leser die Erklärungen anhand von eigenen Beispielen nachvollziehen, um sie besser zu verstehen. Indem wir reichlich grafisches Material benutzen, erhalten wir nicht nur einen ansprechenderen und leichter zu lesenden Text, sondern auch einen wirklich nützlichen Ratgeber. Denn oft erspart wir uns durch die Betrachtung der Bilder, daß wir die Erklärungen noch einmal lesen müssen. Ein Bild hat die positive Eigenschaft, das Gedächtnis rasch wieder aufzufrischen. Manchmal reicht ein Bild nicht aus, sondern es bedarf einer ganzen Folge, um bestimmte Effekte durch den Vergleich der Bilder zu erkennen, und hierin liegt der Grund, dieses Thema so früh anzusprechen. 
Povray beschränkt sich im Grunde darauf, die Bildsequenz zu erzeugen und sie separat auf der Festplatte zu speichern. 
Im Moment wollen wir nur auf einfache Weise beschreiben, wie dies erreicht werden kann. Povray wird mehrere Male aufgerufen, wobei ihm jedes Mal ein anderer Wert übergeben, der von der Nummer des Bildes abhängt, welche im Quellcode dafür vorgesehen ist, ein unterschiedliches Bild zu produzieren. Um Povray mehrere Male aufzurufen, können bestimmte Optionen in der *.ini-Datei genutzt werden, die dazu gedacht sind, Animationen zu erzeugen. 
 
 
Beispiel für eine *.ini-Datei: 

Initial_Clock = 0.0 
Final_Clock = 2.0 
Initial_Frame = 1 
Final_Frame = 200 
Subset_Start_Frame = 51 
Subset_End_Frame = 75

 
 

Um die *.ini-Datei zu erzeugen, schlugen wir im vorangehenden Artikel ein einfaches Skript vor, das uns den einfachen und bequemen Gebrauch von Povray erlaubte. Wir werden es nun aktualisieren, damit wir es zur Erzeugung von Animationen nutzen können. 

Noch eine Änderung. Wir haben ein include-Verzeichnis eingerichtet, welches sich mehrere Projekte teilen können: 
'$HOME/dat/pov/include'  Wenn Sie sich ihre eigene includes-Library erstellen wollen, wäre das ein guter Ort, sie unterzubringen. 
 

Pov ver 2.0

Beispiel für eine *.ini-Datei: 
-----------------------------------------------8<-----------------

#!/bin/bash
#####################################################################
#  Autor: Antonio Castro Snurmacher  (Feb-1998)
#
#       pov (ver 2.0)
#
#       Esta versión esta dedicada a su inclusión en la
#       revista LinuxFocus   (freeware)
#
#  Esta version (2.0) incorpora posibilidad de generar animaciones
#
#  Requiere 'xv' e 'imagemagick (convert,animate) '
# 
#  Este programa puede ser utilizado, distribuido, y modificado
#  libremente pero siempre se deberá respetar la propiedad
#  intelectual de su autor. Esta cabecera debe ser conservada 
#  tal cual en todas las modificaciones. 
#
#  En caso de traduccion deberá conservarse el texto original de
#  esta cabecera y añadirse la traducción a continuación de ella.
#
#  El autor renuncia a todo tipo de beneficio económico y no se hace 
#  responsable de los posibles perjuicios derivados del uso del mismo. 
# 
#  E-mail ([email protected])
# 
#####################################################################
# Autor: Antonio Castro Snurmacher (Feb-1998)
#
# pov (ver 2.0)
#
# Diese Version wird in der Zeitschrift LinuxFocus (freeware)
# veröffentlicht.
# 
# Diese Version (2.0) bietet die Möglichkeit, Animationen zu erzeugen
#
# 'xv' und 'imagemagick (convert,animate) ' werden vorausgesetzt.
#
# Dieses Programm kann frei genutzt, verteilt und verändert werden,
# jedoch muß das geistige Eigentum des Autors respektiert werden.
# Dieser Kopf muß bei allen Veränderungen in dieser Form erhalten bleiben.
#
# Im Falle einer Übersetzung muß der Originaltext dieses Kopfes
# beibehalten und die Übersetzung im Anschluß an diesen eingefügt werden.
#
# Der Autor verzichtet auf jede Art finanziellen Gewinns und verweigert
# jede Verantwortung für Schäden, die durch den Gebrauch des Programms
# entstehen.
#
# E-mail ([email protected])
#
#####################################################################
uso(){
   echo "Uso: pov <proyect> <size=0..6> <quality=1..11> "
   echo "    [ <Initial_Frame> <Final_Frame> <Initial_Clock> <Final_Clock>"
   echo "      [ <Subset_Start_Frame> <Subset_End_Frame> ] ]"
   echo
   echo "0) 40x30     (STD/20) No backup"
   echo "1) 80x60     (STD/10) No backup"
   echo "2) 100x75    (STD/8)  No backup"
   echo "3) 200x150   (STD/4)"
   echo "4) 266x200   (STD/3)"
   echo "5) 320x200 *"
   echo "6) 400x300   (STD/2)"
   echo "7) 640x480 *"
   echo "8) 800x600 *   (STD)"
   echo "9) 1024x768 *"
   echo
echo ""Die Projekte müssen sich in einem Verzeichnis in"
 echo "${HOMEPOV} befinden und man verwende für das Verzeichnis"
 echo "denselben Namen wie für die Hauptquelldatei *.pov"
 echo "(STD) ist die Auflösung die als Standardreferenz gewählt wird."
 echo
 exit 1
}

newversion(){
mv ${PREFIX}.pov.8.gz ${PREFIX}.pov.9.gz 2> /dev/null
mv ${PREFIX}.pov.7.gz ${PREFIX}.pov.8.gz 2> /dev/null
mv ${PREFIX}.pov.6.gz ${PREFIX}.pov.7.gz 2> /dev/null
mv ${PREFIX}.pov.5.gz ${PREFIX}.pov.6.gz 2> /dev/null
mv ${PREFIX}.pov.4.gz ${PREFIX}.pov.5.gz 2> /dev/null
mv ${PREFIX}.pov.3 ${PREFIX}.pov.4 2> /dev/null
mv ${PREFIX}.pov.2 ${PREFIX}.pov.3 2> /dev/null
mv ${PREFIX}.pov.1 ${PREFIX}.pov.2 2> /dev/null
cp ${PREFIX}.pov   ${PREFIX}.pov.1 
gzip ${PREFIX}.pov.4 2> /dev/null
}

#################################################
size(){
   export SAVE="yes"
   case  $1 in
      0) Width=40 ; Height=30; SAVE="no" ;;
      1) Width=80 ; Height=60  SAVE="no" ;;
      2) Width=100; Height=75  SAVE="no" ;;
      3) Width=200; Height=150;;
      4) Width=266; Height=200;;
      5) Width=320; Height=200;;
      6) Width=400 ;Height=300;;
      7) Width=640 ;Height=480;;
      8) Width=800 ;Height=600;;
      9) Width=1024;Height=768;;
      *) uso
   esac
}

quality(){
   case $1 in
   1) ;;
   2) ;;
   3) ;;
   4) ;;
   5) ;;
   6) ;;
   7) ;;
   8) ;;
   9) ;;
   10) ;;
   11) ;;
       *) uso
   esac
   export Quality=$1
}

#############################################################
Single(){ 
cat <<-FIN >> ${PREFIX}.ini
   Output_File_Name=${PREFIX}.tga
   Post_Scene_Command=xv ${PREFIX}.tga
FIN
}

#############################################################
SubSet(){
cat <<-FIN>> ${PREFIX}.ini
   Subset_Start_Frame=$Subset_Start_Frame
   Subset_End_Frame=$Subset_End_Frame
FIN
}

#############################################################
Animation(){
cat <<-FIN>> ${PREFIX}.ini
   Output_File_Name=${PREFIX}.tga
   Initial_Frame=$Initial_Frame
   Final_Frame=$Final_Frame
   Initial_Clock=$Initial_Clock
   Final_Clock=$Final_Clock
FIN
if [ $NumParm == 9 ]
   then 
      SubSet
fi
cat <<-FIN >> ${PREFIX}.ini
   Pre_Scene_Command=rm -f \`ls --color=none ${PREFIX}*.tga.gif\`   
   Pre_Frame_Command=rm -f \`ls --color=none ${PREFIX}*.tga\`   
   Post_Frame_Command=convert %o %o.gif
   Post_Scene_Command=animate -delay $DELAY  \`ls -tr --color=none ${PREFIX}*.tga.gif\` 
FIN
}

####################### main ##############################
export HOMEPOV=${HOME}/dat/pov
export PROYECT=$1
export PREFIX=${HOMEPOV}/${PROYECT}/${PROYECT}
if [ $# != 3 ] && [ $# != 7 ] && [ $# != 9 ]
   then uso
fi
NumParm=$#
if [ $NumParm -le 3 ] && [ grep Clock ${PREFIX}.pov > /dev/null 2>&1 ]
   then 
      echo "Identifier Clock nicht in Quellcode gefunden"
      uso
fi
export POVRAY=/usr/local/apli/povray/povray3
size $2
quality $3
Initial_Frame=$4
Final_Frame=$5
Initial_Clock=$6
Final_Clock=$7
Subset_Start_Frame=$8
Subset_End_Frame=$9

NumClocks=`expr $Final_Clock - $Initial_Clock`
if [ $NumClocks -gt 0 ]
   then if [ $NumClocks -le 40 ]
           then export DELAY=`expr 4000 / $NumClocks`
           else export DELAY=100
        fi
   else export DELAY=4000
fi

if [ $SAVE == "yes" ]
   then newversion
fi
cat <<-FIN>> ${PREFIX}.ini
   Width=$Width
   Height=$Height
   Quality=$Quality
   Library_Path=${POVRAY}/include
   Library_Path=${HOMEPOV}/include
   Input_File_Name=${PREFIX}.pov
   Output_to_File=on
   Output_File_Type=t
   verbose=on
FIN
if [ $NumParm == 3 ]
   then ## Single image
       Single
   else ## Animation
      Animation
fi
#montage ${PREFIX}.tga.* ; animate ${PREFIX}.

#   Output_File_Type=t
## Others hight performace options ##
#   Antialias_Depth=3
#   Antialias=On
#   Antialias_Threshold=0.1
#   Jitter_Amount=0.5
#   Jitter=On

# Niedere Priorität, damit andere Prozesse auch Rechenzeit abbekommen.
nice -20 x-povray ${PREFIX}.ini
 

if [ $SAVE != "yes" ]
    then echo "!! Warnung! Es gibt keine Sicherheitskopie dieser Version!"
fi

---------------------------8<-----------------------------------
 
 

Gelegentlich werden wir Programme verwenden, die nicht Bestandteil von Povray sind. 

Um die Animation darstellen zu können, bedienen wir uns der Tools animate und convert von imagemagick. 

Exkurs  

Ich fragte Enrique Zanardi, der das Povray-Paket für Debian unterhält, ob für Povray ein Modeller (also ein Szenen-Editor, Anm.d.Ü.) existiert. 

E.Zanardi schrieb 

> Ich habe ScEd benutzt (auch für Debian erhältlich). Wenn du den Trick einmal raus hast, ist es sehr komfortabel. 
> Außerdem hast du die Möglichkeit, mit einem Interpreter mit integriertem Scheme zu kompilieren, so daß du dir 
> deine eigenen Befehle definieren kannst, du baust es aus, ganz wie du willst. 
> Ac3D ist auch sehr dafür zu empfehlen, aber ich glaube, es ist nicht frei. 
 

Exkurs Ende  

Wir werden im nächsten Kapitel ein Beispiel einer Animation sehen, welches veranschaulicht, auf welche Weise Drehungen und Verschiebungen definiert werden. 

Wir werden nun kurz eine andere Möglichkeit zeigen, wie man Animationen erzeugen kann. Diese wurde in den ersten Povray-Versionen angewandt, ist aber immer noch gültig. 

Sie besteht darin, daß man ein externes Programm benutzt, welches eine Schleife beeinhaltet, um Povray mehrere Male hintereinander aufzurufen. Bei jeder Iteration wird mittels einer '#include'-Zeile im Quellcode eine Datei angefügt, welche die Definitionen enthält, die sich abhängig von der Zeit verändern. 

Wenn man das in C macht, sieht es etwa so aus: 

 
----------------------8<---------------------------------------------- 
for(Frame=1; Frame < UltimoFrame; Frame++){
   fi=fopen("pajaro.inc", "w");
   fprintf(fi, "#declare PosX_pajaro1 = %d\n", FuncionPosX_pajaro1(Frame));
   fprintf(fi, "#declare PosY_pajaro1 = %d\n", FuncionPosY_pajaro1(Frame));
   fprintf(fi, "#declare AnguloAlas_p1 = %d\n", FuncionAngAlas_p1(Frame));
   fclose(fi);
   sprintf(comando, "povray -ipajaro.pov -opajaro%04d.tga", Frame);
   system(comando);
}
----------------------8<---------------------------------------------- 
 

3D-Ansichten 

Es gibt eine Reihe von 3D-Operationen, die man an einem Objekt anwenden kann. 

Außerdem kann man Objekte gruppieren und mit dem zusammengesetzten Objekt globale Operationen durchführen, wie z. B. verschieben, drehen oder skalieren. 

Position 

Die Position eines Objektes wird durch seine Koordinaten  <x,y,z> festgelegt. Noch besser ist es, ein eigenes Koordinatensystem zu erstellen, um sich leichter in seinen Zeichnungen zu orientieren. 
Ich selbst plaziere das Objekt immer wenn es geht ins Zentrum der Koordinaten. 

Jeder Punkt kann an eine bestimmte Stelle gesetzt werden, indem seine  <x,y,z> Koordinaten angegeben werden. Die Daten, die auf diese Weise angegeben werden, heißen Vektoren. Sie werden in Povray häufig gebraucht. Eine Kurzform für Vektoren, bei denen alle Komponenten gleich sind, ist eine Zahl in spitzen Klammern:
<24, 24, 24>  = <24>  
Eine andere Kurzform ist, einen Skalar mit einem Vektor zu multiplizieren. Es gibt drei vordefinierte Vektoren:
x=<1,0,0>, y=<0,1,0> und z=<0,0,1>. Deshalb sind folgende Vektoren äquivalent.  3*y = <0,3,0>  -2*x = <-2,0,0>

Oft ist es notwendig, mit Papier und Bleistift zu arbeiten, um die Objekte korrekt zu plazieren. 

Eine andere Möglichkeit ist, sie näherungsweise anzuordnen und die exakte Position dann mittels try and error zu ermitteln. Für diese Versuche ist es ratsam, eine geringe Auflösung und eine geringe Bildqualität zu wählen, um schnell Resultate zu erhalten.

 

Es gibt eine Reihe von Vektor-Umwandlungen, nämlich:

  rotate <VECTOR>
  scale <VECTOR>
  translate <VECTOR>

Die Verschiebungsbewegungen und Drehungen sind nützlich bei Animationen, aber auch für die bequeme Positionierung der Komponenten eines Objektes. 
 

Verschiebung 

Jedes beliebige Objekt kann durch Addition eines Verschiebungsvektors an einen anderen Punkt verschoben werden. 
Das heißt die neue Position wird die Summe der aktuellen Positionsvektoren und des Verschiebungsvektors sein.
Beispiel:

sphere { <2, 2, 2>, 10
    pigment { White }
    translate <-3>                  //  zur Erinnerung: <-3> = <-3, -3, -3>
  }

Das Resultat wäre eine Kugel mit Radius 10 mit dem Zentrum bei  <-1,-1,-1>

 

Drehung 

Jedes Objekt kann man drehen und die Drehungen werden in Bezug auf den Koordinatenursprung durchgeführt. 
Die Objekte, die bei der Drehung auf sich selbst abgebildet werden, werden normalerweise so definiert, daß sie im Zentrum des Koordinatensystems liegen, denn man muß sie zuerst drehen und dann verschieben. Wenn wir sie um eine Achse drehen wollen, positionieren wir diese in der entprechenden Distanz und dann drehen wir. 
Um ein Objekt zu drehen, definieren wir eine Achse und einen Drehwinkel bezüglich dieser Achse. 

Der Drehsinn richtet sich nach der Linke-Faust-Regel. 
Stellen Sie sich vor, Sie nehmen die Achse mit Ihrer linken Hand und strecken den Daumen in die positive Richtung der Achse. Die positive Drehrichtung wird dann durch die übrigen gekrümmten Finger angezeigt. 

Es gibt syntaktisch zwei Möglichkeiten, eine Drehung zu definieren. 
„Achse * Grad“ oder drei Zahlen  <n,n,n>  die jeweils die Drehung um die Achsen X, Y und Z bezeichnen. 
Hier einige Beispiele: 

rotate x * 45 = rotate <45, 0, 0> 
rotate <45, -30, 20> = rotate x*45 rotate y*-30 rotate z*20 
rotate 20*z = rotate z*20 
rotate y*90 x*90 = rotate <0, 90, 0> rotate <90, 0, 0> 
rotate y*90 x*90 != rotate <90, 90, 0> 

Das letzte Beispiel stellt keine Äquivalenz dar und sorgt vielleicht für Verwirrung. Die Reihenfolge, in der die Drehungen durchgeführt werden, ist wichtig. Wenn wir die Schreibweise <n,n,n> benutzen, werden die Drehungen immer in der Reihenfolge X, Y, Z gemacht, und wenn man die Reihenfolge ändern will, muß man sie in mehrere Anweisungen unterschiedlicher Rotationen aufschlüsseln. 
Wir benutzen bevorzugt die Schreibweise „Achse * Grad“ ( oder auch „Grad * Achse“). Wenn Sie das Bogenmaß bevorzugen, können Sie die Funktion radians benutzen. 
Es gibt viele aritmethischen Funktionen in Povray, die die Berechnungen erleichtern. Besonders nützlich die trigonometrischen Funktionen, aber wir werden dieses Thema nicht vertiefen. 
 

Skalierung 

Die Größe der Objekte kann variiert werden. 
Durch Multiplizieren der drei Dimensionen x, y und z mit je einem geeigneten Faktor können Objekte vergrößert, verkleinert, gestreckt und abgeflacht werden. 
 Folgendes dient dazu, aus einer Kugel ein Elipsoid zu machen.
 
sphere { <0,0,0>, 10
    pigment { White }
    scale <1,4,10>
  }
 

Abschließende Beobachtungen über 3D-Operationen.

Verschiebungs- und Skalierungsoperationen lassen sich in jeder beliebigen Reihenfolge durchführen, aber wenn eine oder mehrere Drehungen dazukommen, unterscheiden sich die Ergebnisse für gewöhnlich total, je nach der Reihenfolge der Operationen. Wir werden uns ein einfaches Beispiel ansehen, damit der Leser einschätzen kann, in welcher Reihenfolge die Operationen durchgeführt werden müssen. Es handelt sich um einen kugelförmigen blauen Körper, der sich um die eigene Achse und um einen anderen Punkt dreht. Die Eigendrehachse ist leicht geneigt gegenüber der Senkrechten der Kreisbahnebene.  (Diese Beispiel erinnert mich an irgend etwas, aber mir fällt es nicht ein.) 
 
 

----------------------------------8<------------------------------ 
#include "colors.inc" 
#include "textures.inc" 
//##### zu empfehlen ist ###### 
//# pov LF2-PlanetBue 4 9 1 100 1 360 # 
//############################### 
#declare RY1 = clock * 5 
#declare RZ1 = 25 
#declare T1 = <5 ,0 ,0 > 
#declare RY2 = clock 

camera { 
    location < -5, 5, 15> 
    look_at < 0, -2, 0> 

light_source { <-15, 15, 15> color White} 

sphere { <0, 0, 0> 4 
    texture { Shadow_Clouds } 
    rotate y * RY1 
    rotate z * RZ1 
    translate T1 rotate y * RY2 

----------------------------------8<------------------------------ 

Um die Animation zu erhalten, rufen wir es auf gemäß der Empfehlung im Quelltext. Wir verwenden unsere neue Version des Skriptes 'pov'.  Wir wenden folgenden Befehl an: 

pov LF2-PlanetBue 4 9 1 100 1 360 

Die Bedeutung der verwendeten Parameter ist: 
 

  1. Als Quelltext nehmen wir $HOME/dat/pov/LF2-PlanetBue/LF2-PlanetBue.pov 
  2. Größe 4 = (266x200) 
  3. Qualität 9 (die höchste) 
  4. Anfangsbild = 1 
  5. Endbild = 100 
  6. Anfangswert von clock = 1 
  7. Endwert von clock = 360 
Wir zeigen einige wenige Einzelbilder, um eine Vorstellung vom Resultat zu bekommen. 
Wir sehen eine blaue Kugel, die sich in einer Kreisbahn bewegt und sich um die eigene Achse dreht, welche um 25 Grad geneigt ist. 

Als reelles Modell des Planeten Erde reicht es nicht aus, höchstens als Metapher. 

Beispiel ../../common/May1998/planetblue.jpg 
 

Planeta Azul

Licht

Das Licht wird definiert als ein Punkt im Raum. 
Es handelt sich um einen unsichtbaren Punkt, das heißt eine Kamera, die diesen Punkt fokussiert, kann ihn nicht erkennen. Ein Lichtstrahl wird nur wahrgenommen durch seine Wirkung auf das Objekt, das er beleuchtet. 
In der Voreinstellung strahlt dieser Punkt Licht in alle Richtungen aus, obwohl Lichtkegel definiert werden können. 
Außerdem wird von weißem Licht ausgegangen, aber es kann auch gefärbt und in der Intentsität gedämpft sein. 

Es kann mehr als eine Lichtquelle definiert werden, um bestimmte Licht- und Schatteneffekte zu erzielen. 

Man muß bedenken, daß eine Erhöhung der Anzahl der Lichtquellen sich proportional auf die Rechenzeit auswirkt, die gebraucht wird, um das Bild zu erzeugen. 

Das Licht kann über seine Position und seine Farbe definiert werden, aber es gibt auch fortgeschrittenere Optionen, um Lichtquellen in der Art von Scheinwerfern zu benutzen. 
Im Moment begnügen wir uns mit den häufigsten Varianten. In allen unseren Beispielen verwenden wir mindestens eine Lichtquelle und eine Kamera. 

Kamera

Die Kamera kann so ausgerichtet werden, daß sie auf ein bestimmtes Objekt zielt. Der Blickwinkel der Kamera kann definiert werden, und man kann sie in jede beliebige Richtung drehen. 
Es gibt unterschiedliche Möglichkeiten, eine Kamera zu definieren, aber diejenige, die wir hier anwenden, ist sehr flexibel und einfach zu benutzen. Nicht alle Formen, eine Kamera zu definieren, sind gleich nützlich. Andere weniger intuitive Möglichkeiten werden aus Gründen der Verträglichkeit mit früheren Versionen verwendet. 
Der Öffnungswinkel der Kamera beeinflußt die Perspektive auf das Bild. 
Verzeihen Sie, wenn es manchmal wie eine Seifenoper klingt, aber wir werden Beispiele von verschiedenen Perspektiven auf ein Objekt im nächsten Artikel sehen. 
Bleiben Sie dran. 
 


Quelltexte der Programme zu diesem Artikel (3342 bytes)
Webpages maintained by Miguel Ángel Sepúlveda
© Antonio Castro 1998
Übersetzt von:Thomas Kappes, Bernd Haug
LinuxFocus 1998