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.
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
Wenn wir aufmerksam hinschauen, sehen wir, daß das Bild
in einigen Aspekten nicht normal erscheint.
-
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.
-
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.
-
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).
-
Auf einer nahegelegenen Ebene befinden sich drei Quader. Wir
sehen, daß der mittlere keinen Schatten wirft.
-
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.
-
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.
-
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:
-
Als Quelltext nehmen wir
$HOME/dat/pov/LF2-PlanetBue/LF2-PlanetBue.pov
-
Größe 4 = (266x200)
-
Qualität 9 (die höchste)
-
Anfangsbild = 1
-
Endbild = 100
-
Anfangswert von clock = 1
-
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
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)