Περιεχόμενα

Εισαγωγή

Shapes

Εμφάνιση

Πολύπλοκα σχήματα

Δάπεδα

Textures

Σκίαση

Lights

Φόντο

Εφέ ομίχλης

Οπτικές γωνίες

Περιήγηση

Έλεγχος Σύγκρουσης

Ήχος

Ανίχνευση εγγύτητας και ενεργειών

Χρονοκίνηση

Παρεμβολή θέσεων

Χρήση scripts






Εισαγωγή:

VRML είναι το ακρωνύμιο του Virtual Reality Modeling Language, γλώσσα προγραμματισμού για κατασκευή τρισδιάστατων γραφικών. Η συγγραφή προγραμμάτων σε VRML απαιτεί την ύπαρξη οποιουδήποτε text editor. Στην έκδοση 2 τα αρχεία αυτά έχουν κατάληξη .wrl . Οι χαρακτήρες που επιτρέπονται καθορίζονται από το UTF 8 format, του οποίου υποσύνολο είναι οι ASCII χαρακτήρες. Τα προγράμματα παρουσιάζονται σε οποιονδήποτε browser με την προϋπόθεση ότι έχει το απαιτούμενο plug in για VRML 2. Τα επίσημα τεχνικά χαρακτηριστικά της καταγράφονται στο specification ISO/IEC 14772.
Γενική Δομή:
Τα VRML αρχεία αποτελούνται από την επικεφαλίδα (header), σχόλια (comments) του προγραμματιστή, ορισμούς κόμβων (nodes), πρωτοτύπων (prototypes) και φυσικά από ονόματα, πεδία και τις αντίστοιχες τιμές τους. Με μια άλλη πιο αφαιρετική ματιά τα VRML αρχεία αποτελούνται από σύνολα κόμβων που είναι ενταγμένα σε ιεραρχίες υποσυνόλων και αλληλεπιδρούν μεταξύ τους. Τα σύνολά αυτά αποτελούν τον κόσμο (world).
Ορισμός & Ομαδοποίηση Κόμβων:
Οι κόμβοι χρησιμοποιούνται για να εκφράσουν τα κατασκευασμένα σχήματα και τις αντίστοιχες ιδιότητες τους. Κατά τον ορισμό των κόμβων απαιτείται να καθορίζεται το όνομά του, το είδος του, καθώς και ένας αριθμός προαιρετικών πεδίων με τις αντίστοιχες τιμές τους. Ως τιμές των πεδίων μπορεί να είναι μεταξύ άλλων και κάποιος άλλος κόμβος. Ο αρχικός, στην περίπτωση αυτή, ονομάζεται πατέρας (father) ενώ όλοι οι άλλοι κόμβοι που περιέχονται σε αυτόν αποκαλούνται παιδιά (children) του. Προφανώς ο πατέρας κόμβος ή αλλιώς πρόγονος των υπολοίπων μπορεί να είναι παιδί σε κάποιον άλλο πατέρα. Κατ’αυτό τον τρόπο φτάνουμε σε ένα κόμβο αρχικό από τον οποίο, τελικά, προκύπτουν όλοι οι υπόλοιποι, τον κόμβο ρίζα (root node).Ένας κόμβος μπορεί να οριστεί μια φορά και να χρησιμοποιηθεί περισσότερες χωρίς φυσικά να οριστεί. Για να γίνει αυτό χρησιμοποιούμαι τις λέξεις DEF και USE. H πρώτη καθορίζει το όνομα του κόμβου που θα χρησιμοποιείται και η δεύτερη το αναφέρει όταν τον χρησιμοποιούμε.
Ένα group ορίζεται ως εξής:
Group {
children[…]
}
Στο πεδίο children έχουμε μια λίστα των παιδιών κόμβων. Προαιρετικά μπορούν να τοποθετηθούν και άλλα πεδία, τα οποία κατά περίπτωση καθορίζουν θέματα όπως την εμφάνιση των παιδιών ή συγκεκριμένες θέσεις μέσα στην ομάδα. Η ομαδοποίηση των κόμβων είναι ιδιαίτερα χρήσιμη όταν το ζητούμενο την απαιτεί για να κατασκευαστούν είτε πιο σύνθετα σχήματα, είτε ομάδες αντικειμένων που χρειάζεται να θεωρούνται ως σύνολο λόγω κοινών χαρακτηριστιικών και προβλημάτων.Ομαδοποίηση μπορούμε να πετύχουμε και με τον κόμβο switch, ο οποίος εμφανίζει συγκεκριμένα παιδιά από την ομάδα ανάλογα με την επιλογή που κάνει ο χρήστης.
Switch {
whichChoice 0
choice [. . .]
}
Αρχή

Shapes:

Τα σχήματα προσδιορίζονται από τη γεωμετρία τους και την εμφάνισή τους. Η πρώτη καθορίζει αυτό που στην καθημερινή γλώσσα αποτελεί την απάντηση στο ερώτημα « Tι σχήμα είναι αυτό; », ενώ η δεύτερη καθορίζει παράγοντες όπως είναι το χρώμα και υφή, στο βαθμό που αυτές μπορούν να παρουσιαστούν μέσω της εικόνας. Οι δυο αυτές έννοιες καθορίζονται στον κόμβο Shape. Ειδικότερα η εμφάνιση προσδιορίζεται από τους κόμβους Appearance και Material, οι οποίοι είναι μέσα στον Shape.Οι προεπιλεγμένες τιμές των κόμβων Shape, Appearance και Material. Τα πεδία είναι προαιρετικά.
Shape {
appearance NULL
geometry NULL
}
Appearance {
material NULL
texture NULL
textureTranform NULL
}
Material {
ambientIntensity 0.2
diffuseColor 0.8 0.8 0.8
emissiveColor 0.0 0.0 0.0
shininess 0.2
specularColor 0.0 0.0 0.0
transparency
}

Box, Cone, Cylinder, Sphere Node:
Η VRML παρέχει ως βασικά σχήματα για την κατασκευή των υπόλοιπων πιο περίπλοκων σχημάτων, το κουτί (box), τον κώνο (cone), τον κύλινδρο (cylinder) και τη σφαίρα (sphere).
Οι προεπιλεγμένες τιμές για τα πεδία του σχήματος Box είναι:
Box {
size 2.0 2.0 2.0
}

Ο παραπάνω ορισμός καθορίζει την κατασκευή ενός κουτιού (κύβου) με διαστάσεις 2.0 2.0 2.0 για την κάθε ακμή του. Τονίζουμε, σε αυτό το σημείο, ότι μονάδα μέτρησης μπορεί να είναι οποιαδήποτε. Για τον node Cone έχουμε:
Cone {
bottomRadius 1.0
height 2.0
side TRUE
bottom TRUE
}

Οι λειτουργίες των δυο πρώτων πεδίων είναι προφανής. Το πεδίο side εκφράζει το αν θα έχει ή όχι πλευρές ο κόμβος, ενώ το πεδίο bottom εκφράζει το αντίστοιχο για τη βάση του κόμβου. Για τον node Cylinder έχουμε:
Cylinder {
radius 1.0
height 2.0
side TRUE
top TRUE
bottom TRUE
}
Για τον node Sphere έχουμε:
Sphere {
radius 1.0
}

Τα πεδία των παραπάνω κόμβων έχουν προφανή λειτουργία.
Συγκεντρώνοντας όλα τα παραπάνω δείχνουμε ένα παράδειγμα ενός φανταστικού διαστημικού σταθμού.
#VRML V2.0 utf8
Group {
children [
Shape {
appearance DEF White Appearance {
material Material {}
}
geometry Box {
size 10.0 10.0 10.0
}
},
Shape {
appearance USE White
geometry Sphere {
radius 7.0
}
},
Shape {
appearance USE White
geometry Cylinder {
radius 7.0
}
},
Shape {
appearance USE White
geometry Cylinder {
radius 4.0
height 20.0
}
},
Shape {
appearance USE White
geometry Cylinder {
radius 3.0
height 30.0
}
},
Shape {
appearance USE White
geometry Cylinder {
radius 1.0
height 60.0
}
}
]
}
Το αποτέλεσμα σε σμίκρυνση και ελάχιστα στραμμένο προς τα αριστερά, είναι το εξής:

i.jpg

Όπως φαίνεται και από τον κώδικα ο διαστημικός σταθμός κατασκευάζεται από έξι σχήματα κάθε ένα από τα οποία είναι πάνω σε κάποιο άλλο. Αρχικά ορίζουμε το γκρουπ των έξι αυτών σχημάτων οι οποίοι είναι τα παιδιά. Με την χρήση της εντολής DEF White Appearance καθορίζουμε μια εμφάνιση την οποία χρησιμοποιούμε και πιο κάτω με χρήση του όρου USE White. Οι ορισμοί Shape καθορίζουν κάθε ένα από τα σχήματα.
Text Shapes:
Τα κείμενα μπορούν εξίσου να παρουσιαστούν με τρισδιάστατη μορφή. Το κείμενο μπορεί να περιέχει γράμματα, σημεία στίξης ή και γραμμές. Γενικότερα κάθε χαρακτήρας μπορεί να προβληθεί. Η γραμματοσειρά ελέγχεται με αντίστοιχες τιμές για τα font, style κτλ όπως και στα γνωστά προγράμματα κειμενογράφου.
Text Nodes:
Η γεωμετρία των κειμένων καθορίζεται από τον Text Node. Υπενθυμίζουμε ότι κάθε κόμβος μπορεί να αποτελεί μια τιμή ενός πεδίου σε άλλο κόμβο, γεγονός το οποίο είναι η σύνηθης πρακτική στην περίπτωση αυτή.
Ενδεικτικός ορισμός για κόμβο Text είναι:
Text {
string . . .
fontstyle . . .
}

String είναι η συμβολοσειρά η οποία θέλουμε να παρουσιάσουμε. fontstyle είναι το πεδίο το οποίο καθορίζει το font της γραμματοσειράς. Αντίστοιχα μπορεί να υπάρξει πεδίο το οποίο δηλώνει το μήκος της συμβολοσειράς. Το fontstyle μπορεί να οριστεί πλέον και αυτό με τον αντίστοιχο κόμβο.
FontStyle {
family “SERIF”
style “BOLD”
size 1.0
spacing 1.0
}

Συγκεντρώνοντας τα μέχρι τώρα καταγεγραμμένα στοιχεία αναφορικά με τα Text Shapes παρουσιάζουμε ενδεικτικό κώδικα για τρισδιάστατο κείμενο:
Shape {
. . .
geometry Text {
string [ “Aristotle University”, “of Thessaloniki” ]
fontStyle FontStyle {
style “BOLD”
}
}
}
Η έξοδος, αν περιστραφεί προς τα δεξιά, θα είναι η ακόλουθη:
ii.jpg

[Κάντε κλικ στην εικόνα για να μπείτε στο VRML περιβάλλον]

Τοποθέτηση Σχημάτων:
Η προεπιλεγμένη θέση κάθε σχήματος είναι στο κέντρο του κόσμου (world), ή με άλλα λόγια στο κέντρο της οθόνης μας. Η λειτουργία transform μας επιτρέπει να τοποθετούμε τα αντικείμενα οπουδήποτε μέσα στον κόσμο, να τα περιστρέφουμε κατά οποιοδήποτε τρόπο, καθώς επίσης και να δίνουμε την ψευδαίσθηση του βάθους όπου εμείς επιθυμούμε. Πρωτού όμως την εξετάσουμε, ας δούμε πρώτα το σύστημα συντεταγμένων.

Σύστημα Συντεταγμένων:
Κατά την κατασκευή ενός κόσμου ο browser παρουσιάζει τα διάφορα αντικείμενα στις θέσεις εκείνες οι οποίες προορίζονται από το σύστημα συντεταγμένων του καθενός. Στη VRML μπορούμε να κατασκευάσουμε ένα πλήθος από συστήματα συντεταγμένων. Όταν κάποιο σύστημα έχει παραχθεί από κάποιο άλλο, τότε το παραγόμενο ονομάζεται child coordinate system, ενώ το πρώτο parent coordinate system. Το parent coordinate system μπορεί να είναι child coordinate system σε κάποιο άλλο σύστημα συντεταγμένων. Ο πρόγονος όλων των συστημάτων συντεταγμένων ονομάζεται root coordinate system.
Transform Node:Ένας μετασχηματισμός δημιουργεί ένα σύστημα συντεταγμένων το οποίο είναι τοποθετημένο, στραμένο και κλιμακώμενο (positioned, rotated, scaled) με βάση το πατρικό σύστημα συντεταγμένων. Τα σχήματα δε που ανήκουν σε αυτό συμπεριφέρονται ανάλογα. Για να κατασκευάσουμε το νέο σύστημα πρέπει να ορίσουμε ένα κόμβο Transform.
Transform {
translation . . .
rotation . . . .
scale . . .
children [ . . . ]
}
Οι τιμές του πεδίου translation καθορίζει την απόσταση από τον άξονα X, Y, Z αντίστοιχα του parent από το child σύστημα συντεταγμένων. Οι τιμές του πεδίου rotation καθορίζουν ως προς ποιούς άξονες γίνεται η περιστροφή καθώς και την γωνία περιστροφής. Το πεδίο scale καθορίζει την κλίμακα μέτρησης που χρησιμοποιούμε σε κάθε άξονα. Το πεδίο children καθορίζει τα παιδιά κόμβους, τα οποία είναι ενταγμένα στο σύστημα αυτό. Πέραν τούτων, υπάρχουν και άλλα πεδία τα οποία μπορεί κανείς να χρησιμοποιήσει για να καθορίσει ακόμα περισσότερες λεπτομέρειες. Όταν αυτά δεν αναφέρονται θεωρείται ότι έχουν τις προεπιλεγμένες τιμές. Πιο συγκεκριμένα έστω ότι καταγράφουμε στο αρχείο μας τα ακόλουθα:
Tranform {
translation 2.0 0.0 0.0
children [. . .]
}
Αυτό σημαίνει ότι θα πρέπει να δημιουργηθεί ένα σύστημα συντεταγμένων μετατοπισμένο κατά δύο μονάδες ως προς τον άξονα χ.

iii.jpgiv.jpg

Αριστερά βλέπουμε το αρχικό σύστημα, ενώ δεξιά το αρχικό και το νέο το οποίο δημιουργήθηκε με βάση το πρώτο.
Αντίστοιχα έχουμε και για το πεδίο rotation:
Transform {
rotation 0.0 0.0 1.0 0.52
children [. . .]
}

Οι τρείς πρώτες τιμές καθορίζουνε σε ποιόν άξονα θα γίνει η περιστροφή. Στο συγκεκριμένο παράδειγμα θα γίνει στον Ζ άξονα, κατά 0.52 ακτίνια. Οπότε το καινούριο και το παλιό σύστημα συντεταγμένων θα είναι ως εξής:
v.jpgvi.jpg

Η κλιμάκωση των αξόνων γίνεται με βάση τις τιμές του (προαιρετικού) πεδίου scale. Συγκεκριμένα μεγαλώνει ή μικραίνει την κλίμακα. Για παράδειγμα:
Transform {
scale 0.5 0.5 0.5
children [. . .]
}
Οπότε έχουμε:
vii.jpgviii.jpg

Αν συνδυάσουμε όλους τους παραπάνω μετασχηματισμούς θα έχουμε το εξής παράδειγμα με ένα υποθετικό αντικείμενο:
Transform {
translation 2.0 0.0 0.0
rotation 0.0 0.0 1.0 0.52
scale 0.5 0.5 0.5
children [ . . . ]
}
ix.jpg

[Κάντε κλικ στην εικόνα για να μπείτε στο VRML περιβάλλον]
Αξίζει να τονίσουμε ότι ο κόμβος Transform επιτελεί ουσιαστικά μια ομαδοποίηση κόμβων με βάση το σύστημα συντεταγμένων που ορίζει.

Billboard Node:
Ο κόμβος αυτός ομαδοποιεί παιδιά-κόμβους κατά τέτοιο τρόπο ώστε το σύστημα συντεταγμένων που θα σχεδιαστεί με βάση αυτό τον κόμβο να μπορεί να περιστραφεί και να «βλέπει» τον χρήστη «κατά πρόσωπο». Υπογραμμίζουμε, στο σημείο αυτό, ότι η περιστροφή αυτή γίνεται αυτόματα από το σύστημα.
Billboard {
axisOfRotation . . .
children [. . .]
}
Η τιμή του πρώτου πεδίου καθορίζει ως προς ποιόν άξονα θα γίνει η περιστροφή του συστήματος συντεταγμένων.
Αρχή

Εμφάνιση Σχημάτων:

Το χρώμα τον σχημάτων έχει ως προεπιλεγμένη τιμή το άσπρο. Αυτό φυσικά δεν είναι η μόνη επιλογή. Η VRML μας δίνει την δυνατότητα να επιλέξουμε οποιοδήποτε χρώμα κάνοντας χρήση των τριών βασικών χρωμάτων κόκκινο, πράσινο και μπλέ. Πέραν τούτου μπορούμε να καθορίσουμε την υφή του αντικειμένου όπως επίσης και την γυαλάδα του, ή το αν είναι διαφανές. Η μοντελοποίηση των διαφόρων υλικών, από τα οποία αποτελούνται τα αντικείμενα στον φυσικό κόσμο, γίνεται με χρήση του κόμβου Material.
Material Node:
Ο κόμβος αυτός ελέγχει διάφορα, προαιρετικά, πεδία ανάλογα με το βαθμό λεπτομέρειας που θέλουμε να επιτύχουμε.
Material {
diffuseColor . . .
emissiveColor . . .
transparency . . .
. . .
}
Για παράδειγμα ο ακόλουθος κώδικας κατασκευάζει παραλληλόγραμμα διαφόρων χρωμάτων.
Group {
children [
DEF Entry Viewpoint {
position 0.0 1.6 20.0
},
NavigationInfo {
type "EXAMINE"
},
#
#Slabs
#
#White slab (shaded)
Transform {
translation 0.0 2.0 4.0
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 1.0 1.0 1.0
}
}
geometry DEF Slab Box {
size 2.0 4.0 0.3
}
},
]
},
#Red slab (emissive)
Transform {
translation 0.0 2.0 0.0
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 0.0 0.0 0.0
emissiveColor 1.0 0.0 0.0
}
}
geometry DEF Slab Box {
size 2.0 4.0 0.3
}
},
]
},
#Green slab (shaded + transparent)
Transform {
translation -3.0 2.0 2.0
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 0.0 1.0 0.0
transparency 0.5
}
}
geometry USE Slab
},
]
},
#Blue slab (shaded + emissive + transparent)
Transform {
translation 4.0 2.0 -2.0
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 0.2 0.2 0.2
emissiveColor 0.0 0.0 0.8
transparency 0.25
}
}
geometry USE Slab
},
]
},
#Yellow slab (shaded + transparent)
Transform {
translation 4.5 2.0 3.0
children [
#Outer
Shape {
appearance Appearance {
material Material {
diffuseColor 1.0 1.0 0.0
transparency 0.5
}
}
geometry USE Slab
},
]
},
#Cyan slab (shaded)
Transform {
translation -3.5 2.0 -5.0
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 0.0 1.0 1.0
}
}
geometry USE Slab
},
]
},
#Magenta slab (shaded + emissive)
Transform {
translation 2.0 2.0 -6.0
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 0.5 0.0 0.0
emissiveColor 0.5 0.0 0.5
}
}
geometry USE Slab
},
]
},
]
}
Στον browser θα εμφανιστεί το ακόλουθο:
x.jpg

Προσέξτε ιδιαίτερα τη διαφάνεια στα διάφορα σχήματα.

Inline Node:
Ένα πρόγραμμα σε VRML μπορεί να είναι ιδιαίτερα μακροσκελές. Συχνή πρακτική είναι να μην ορίζονται όλα τα στοιχεία του σε ένα αρχείο. Ο κόμβος inline ουσιαστικά περιγράφει που είναι τοποθετημένα τα διάφορα στοιχεία.
Inline {
url “jet.wrl”
}

Anchor Node:
Αnchors μπορεί να είναι οποιοδήποτε σχήμα ή ομάδα σχημάτων, τα οποία όταν επιλεγούν, μεταφερόμαστε σε ένα άλλο προκαθορισμένο αρχείο VRML που προβάλεται. Λειτουργούν με τρόπο αντίστοιχο των links στην Html.
Anchor {
url "stairway.wrl"
description "Floating Stairs"
children [ . . . ]
}
Το πεδίο description παίρνει ως τιμές συμβολοσειρές και λειτουργεί βοηθητικά επεξηγώντας τον κόσμο.
Αρχή

Πολύπλοκα Σχήματα:

Μέχρι στιγμής παρουσιάσαμε ενδεικτικές δυνατότητες της VRML με χρήση των στοιχειωδών σχημάτων της Box, Cone, Cylinder και Sphere, καθώς επίσης και των δυνατοτήτων που δημιουργούνται με την ομαδοποίηση αυτών. Στα παρακάτω θα δούμε πως μπορούμε να κατασκευάσουμε πιο λεπτομερή σχήματα σχήματα χρησιμοποιώντας σημεία, γραμμές (points, lines) και faces. Με αυτή τη φιλοσοφία περιγράφουμε την τοποθεσία των σημείων, ή αλλιώς τις συντεταγμένες τους, με τον κόμβο Coordinate.
Coordinate Node:
Coordinate {
point [ 2.0 1.0 3.0, 4.0 2.5 5.3, …
]
}
Δηλαδή το πρώτο σημείο βρίσκεται στη θέση 2.0 1.0 3.0.
Μπορούμε να ομαδοποιήσουμε σημεία μέσω του κόμβου PointSet.

PointSet Node:
PointSet {
coord Coordinate {
point [ . . . ]
}
}

IndexLineSet Node:
IndexedLineSet {
coord Coordinate {
point [ . . . ]
}
coordIndex [
1, 0, 3, -1, . . .
]
}

Είναι ο κόμβος ο οποίος περιγράφει τις polylines. Μια γραμμή που ανήκει στην κατηγορία αυτή ξεκινάει εκεί που τελειώνει μια άλλη. Όλες μαζι σχηματίζουν μια «αλυσίδα» γραμμών.
Ας δούμε τα παραπάνω σε παράδειγμα:[11][12]

Αριστερά βλέπουμε το σύνολο των σημείων και δεξιά τις γραμμές οι οποίες τα ενώνουν. Ακολουθούν ο κώδικας για την πρώτη και τη δεύτερη εικόνα αντίστοιχα.
#VRML V2.0 utf8
Group {
children [
#Axes
Shape {
appearance Appearance {
material Material {
diffuseColor 1.0 1.0 1.0
}
}
geometry IndexedLineSet {
coord Coordinate {
point [
0.0 0.0 0.0, 10.0 0.0 0.0, 0.0 8.0 0.0
]
}
coordIndex [
0, 1, -1, 0, 2, -1
]
}
},
#Scatter plot with different color points
Shape {
appearance Appearance {
}
geometry PointSet {
coord Coordinate {
point [
#Green points
1.0 1.0 0.0, 2.0 4.0 0.0,
3.0 5.0 0.0, 4.0 4.0 0.0,
5.0 6.0 0.0, 6.0 7.0 0.0,
7.0 5.0 0.0, 8.0 6.0 0.0,
9.0 4.0 0.0, 10.0 3.0 0.0,
#Yellow points
1.0 3.0 0.0, 2.0 2.0 0.0,
3.0 2.0 0.0, 4.0 1.0 0.0,
5.0 2.0 0.0, 6.0 4.0 0.0,
7.0 3.0 0.0, 8.0 5.0 0.0,
9.0 5.0 0.0, 10.0 6.0 0.0,
]
}
color Color {
color [
#Green points
0.0 1.0 0.0, 0.0 1.0 0.0,
0.0 1.0 0.0, 0.0 1.0 0.0,
0.0 1.0 0.0, 0.0 1.0 0.0,
0.0 1.0 0.0, 0.0 1.0 0.0,
0.0 1.0 0.0, 0.0 1.0 0.0,
#Yellow points
1.0 1.0 0.0, 1.0 1.0 0.0,
1.0 1.0 0.0, 1.0 1.0 0.0,
1.0 1.0 0.0, 1.0 1.0 0.0,
1.0 1.0 0.0, 1.0 1.0 0.0,
1.0 1.0 0.0, 1.0 1.0 0.0,
]
}
}
}
]
}
#VRML V2.0 utf8
Group {
children [
#Axes
Shape {
appearance Appearance {
material Material {
diffuseColor 1.0 1.0 1.0
}
}
geometry IndexedLineSet {
coord Coordinate {
point [
0.0 0.0 0.0, 10.0 0.0 0.0, 0.0 8.0 0.0
]
}
coordIndex [
0, 1, -1, 0, 2, -1
]
}
},
#Line plot with different color lines
Shape {
appearance Appearance {
}
geometry IndexedLineSet {
coord Coordinate {
point [
#Green line
1.0 1.0 0.0, 2.0 4.0 0.0,
3.0 5.0 0.0, 4.0 4.0 0.0,
5.0 6.0 0.0, 6.0 7.0 0.0,
7.0 5.0 0.0, 8.0 6.0 0.0,
9.0 4.0 0.0, 10.0 3.0 0.0
#Yellow line
1.0 3.0 0.0, 2.0 2.0 0.0,
3.0 2.0 0.0, 4.0 1.0 0.0,
5.0 2.0 0.0, 6.0 4.0 0.0,
7.0 3.0 0.0, 8.0 5.0 0.0,
9.0 5.0 0.0, 10.0 6.0 0.0,
]
}
color Color {
color [
0.0 1.0 0.0, 1.0 1.0 0.0,
]
}
coordIndex
#Green line
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
  1. Yellow line
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, -1
]
colorIndex [
0, 1
]
colorPerVertex FALSE
}
},
]
}

Face Node:
IndexedFaceSet {
coord Coordinate {
point [ . . . ]
}
coordIndex [
1, 0, 3, -1, . . .
]
}
Τα Faces ζωγραφίζονται μεταξύ της περιμέτρου των σημείων.
Αρχή

Κατασκευή Δαπέδων:

Ιδιαίτερο ενδιαφέρον για τους προγραμματιστές τρισδιάστατων γραφικών έχουν τα διάφορα δάπεδα. Με χρήση αυτών μπορούμε να δώσουμε την ψευδαίσθηση των βουνών, της θάλασσας ή ακόμη και της επιφάνειας των πλανητών. Τα δάπεδα κατασκευάζονται χρησιμοποιώντας ένα αρχικό πλέγμα γραμμών και στηλών των οποίων η απόσταση και το πλήθος καθορίζεται από τον προγραμματιστή. Κατόπιν επιλέγουμε διάφορα σημεία του και αυξομειώνουμε το ύψος τους. Τα επιλεγμένα σημεία με τον ένα ή τον άλλο τρόπο προεξέχουν από τα υπόλοιπα δίνοντας έτσι την ψευδαίσθηση πχ βουνών ή κρατήρων.[13]
ElevationGrid Node:
ElevationGrid {
xDimension 3
xSpacing 1.0
zDimension 2
zSpacing 1.0
height [
0.0, -0.5, 0.0,
0.2, 4.0, 0.0
]
}
Τα πεδία xDimension και zDimension καθορίζουν το πλήθος των σημείων στους άξονες x και z αντίστοιχα. Τα πεδία xSpacing και zSpacing καθορίζουν την απόσταση μεταξύ των στηλών στον άξονα X και Z αντίστοιχα. Το πεδίο height καθορίζει μια λίστα από elevations, ένα για κάθε grid point στον άξονα Υ.
Αρχή

Textures:

Με τον όρο texture στην VRML εννοούμε την οπτική λεπτομέρεια που εμφανίζεται ανάλογα με την απόσταση από την οποία παρακολουθούμε ένα αντικείμενο. Στον πραγματικό κόσμο οι λεπτομέρειες που υπάρχουν σε ένα αντικείμενο δεν διακρίνονται όταν αυτό είναι πάρα πολύ μακριά μας. Καθώς μας προσεγγίζει τις εντοπίζουμε εκεί που πρίν δεν τις βλέπαμε. Δεδομένου ότι αυτό είναι ιδιαίτερα δύσκολο για να γίνει η VRML δίνει τη δυνατότητα να τοποθετούμε μια φωτογραφία του αντικειμένου πάνω στο σχήμα το οποίο το μοντελοποεί, λειτουργία γνωστή ως texture mapping.
ImageTexture {
url "cantop.jpg"
}
Με τον παραπάνω τρόπο ζητάμε να εντοπιστεί η φωτογραφία cantop.jpg. Η φωτογραφία αυτή θα τοποθετηθεί πάνω στο σχήμα το οποίο παρουσιάζει το παρακάτω ντενεκεδένιο κουτάκι. Πατήστε εδώ για να το δείτε.

Ο κώδικας για το παραπάνω είναι ο εξής:
#VRML V2.0 utf8
DEF SignHigh Transform {
children [
Shape { # Empty shape just used to define sign color
appearance DEF SignColor Appearance {
texture ImageTexture { url "signwood.jpg" }
}
},
#USE SignFrame,
DEF SignFrame Transform {
children [
Transform {
translation -3 1 -.1
children Shape {
geometry Box { size .2 2 .2 }
appearance USE SignColor
}
},
Transform {
translation 3 1 -.1
children Shape {
geometry Box { size .2 2 .2 }
appearance USE SignColor
}
},
Transform {
translation 0 4.25 -.1
children Shape {
geometry Box { size 8.5 4.5 .2 }
appearance USE SignColor
}
}
]
}, #end of SignFrame
Transform {
translation 0 2.25 .05
children Shape {
appearance Appearance {
texture ImageTexture { url "map.GIF" }
}
geometry IndexedFaceSet {
coord Coordinate { point [ -4. 0 0., 4. 0 0.,
4. 4 0., -4. 4 0. ]
}
coordIndex [ 0, 1, 2, 3, -1 ]
texCoord TextureCoordinate { point [ 0 0, 1 0, 1 1, 0 1 ] }
texCoordIndex [ 0, 1, 2, 3, -1 ]
solid FALSE
}
}
}
]
}

Είναι αυτονόητο ότι στην περίπτωση του texture mapping το χρώμα του texture τοποθετείται πάνω από το προηγούμενο. Ο κόμβος Appearance είναι αυτός ο οποίος αναλαμβάνει να τυλίξει την φωτογραφία γύρω από το σχήμα. Ο κόμβος ImageTexture υποστηρίζει τα format .jpeg, .png, .gif. Εκτός αυτού μπορεί να υποστηριχθούν και αρχεία βίντεο. Με την επιλογή του κόμβου στον οποίο έχει τοποθετηθεί αυτή η δυνατότητα παρουσιάζεται το αντίστοιχο βίντεο. π.χ
Appearance {
texture MovieTexture {
url "mymovie.mpg"
speed 1
loop FALSE
}
}
Στο οποίο καθορίζεται το αρχείο mymovie.mpg η ταχύτητά του και το αν θα πρέπει να πεναλμβάνεται η εκτέλεσή του. Τα format που υποστηρίζονται είναι MPEG1-Systems και MPEG1-Video.
Αρχή

Σκίαση Σχημάτων:

Η σκίαση των διαφόρων σχημάτων εξαρτάται από το αν αυτά φωτίζονται από ένα εικονικό φώς και από τις μεταξύ τους θέσεις. Για να προσδιορίσουμε «που κοιτάει» ένα αντικείμενο χρησιμοποιούμε τα normals. Τα normals είναι διανύσματα τα οποία μας δείχνουν την κατεύθυνση αυτή. Μπορούμε να παρέμβουμε στα διανύσματα αυτά αλλά είναι προτιμότερο να κρατήσουμε τα προεπιλεγμένα. Όσων αφορά τη μεταξύ τους θέση καταγράφουμε τα εξής: αν η μεταξύ τους γωνία είναι μεγαλύτερη από την creaseAngle, τότε η σκίαση είναι επίπεδη (flat). Πατήστε εδώ.

Αν η μεταξύ τους γωνία είναι μικρότερη από την creaseAngle τότε η σκίαση είναι απαλή (smooth).[17][18]
Αρχή

Lights:

Τα φώτα στην VRML λειτουργούν όπως ακρβώς και στον πραγματικό κόσμο. Υπάρχουν τριών ειδών φώτα: PointLight, DirectionalLight, SpotLight. Τα παρακάτω κοινά και στα τρία πεδία έχουν τις ακόλουθες τιμές:
on TRUE
intensity 1.0
ambientIntensity 0.0
color 1.0 1.0 1.0

PointLight Node:
Το φώς αυτό ακτινοβολεί ακτινωτά:
PointLight {
  1. Standard fields, plus:
location 0.0 0.0 0.0
radius 1.0
attenuation 1.0 0.0 0.0
}[19]

DirectionalLight Node:
Το φώς αυτό ακτινοβολεί προς μια συγκεκριμένη κατεύθυνση:
DirectionalLight {
  1. Standard fields, plus:
direction 1.0 0.0 0.0
}[20]

SpotLight Node:
To φως αυτό ακτινοβολεί σε συγκεκριμένη κατεύθυνση και εστιάζει σε κώνο:
SpotLight {
  1. Standard fields, plus:
location 0.0 0.0 0.0
direction 1.0 0.0 0.0
beamWidth 1.57
cutOffAngle 0.785
radius 1.0
attenuation 1.0 0.0 0.0
}[21]
Αρχή

Προσθέτοντας Φόντο (ο κόμβος Background)

Για να προσθέσουμε φόντο στον κόσμο μας χρησιμοποιούμε τον κόμβο Background ο οποίος έχει την εξής σύνταξη:
Background {
skyColor #exposedField MFColor
skyAngle #exposedField MFFloat
groundColor #exposedField MFColor
groundAngle #exposedField MFFloat
backUrl #exposedField MFString
bottomUrl #exposedField MFString
frontUrl #exposedField MFString
leftUrl #exposedField MFString
rightUrl #exposedField MFString
topUrl #exposedField MFString
set_bind #eventIn SFBool
bind_changed #eventOut SFBool
}

Η λογική του φόντου είναι ότι το φόντο είναι μια οντότητα σε άπειρη απόσταση από τον χρήστη, δηλαδή ο χρήστης όσο και αν κινείται δεν δείχνει να το προσεγγίζει. Εφόσον ορίζεται στον κόμβο το φόντο αποτελείται από μέχρι έξι εικόνες που καταλαμβάνουν τις αντίστοιχες εσωτερικές πλευρές ενός κύβου και ορίζονται από τα πεδία backUrl, bottomUrl, κτλ… Πίσω από αυτόν τον κύβο έχουμε μια σφαίρα που αντιπροσωπεύει το έδαφος και ορίζεται από τα πεδία groundColor και groundAngle. Αυτή η σφαίρα φαίνεται μόνο εάν δεν ορίζεται κάποια πλευρά του κύβου που αναφέραμε παραπάνω αφού ο κύβος βρίσκεται μπροστά από την σφαίρα. Το πεδίο groundColor είναι μια λίστα από χρώματα και το πεδίο groundAngle μια λίστα από γωνίες, αυτό που γίνεται είναι ότι το χρώμα που βρίσκεται στην πρώτη θέση ξεκινά από την γωνία 0 της σφαίρας (που ορίζεται σαν τον κάτω πόλο της σφαίρας) και μεταβάλλεται ομαλά ώστε να γίνει ίδιο με το χρώμα στη δεύτερη θέση όταν η γωνία της σφαίρας φτάσει την τιμή της πρώτης θέσης (δηλαδή για n χρώματα θέλουμε n-1 γωνίες), αν η τελευταία γωνία είναι μικρότερη από π ακτίνια τότε από την τελευταία γωνία και πάνω η σφαίρα γίνεται διάφανη ώστε να φανεί η σφαίρα που αντιπροσωπεύει τον ουρανό. Αυτή η σφαίρα είναι το τελευταίο επίπεδο φόντου που ορίζει ο κόμβος Background, ορίζεται παρόμοια με την σφαίρα εδάφους με μόνη διαφορά ότι οι γωνίες ξεκινούν από τον πάνω πόλο και από την τελευταία γωνία και μετά η υπόλοιπη σφαίρα χρωματίζεται με το τελευταίο χρώμα.
Το eventIn set_bind κάνει τον κόμβο το τρέχον φόντο ενώ το eventOut bind_changed ανιχνεύει την αλλαγή φόντου.
Παραδείγματα: Ένας κόσμος χωρίς φόντο.
Ο ίδιος κόσμος με φόντο με χρήση των σφαιρών εδάφους και ουρανού.
Τέλος ο κόσμος με πανοραμικό φόντο κύβου.
Αρχή

Προσθέτοντας εφε ομίχλης (ο κόμβος Fog)

Για ομίχλη χρησιμοποιούμε τον κόμβο Fog:
Fog {
color #exposedField SFColor
visibilityRange #exposedField SFFloat
fogType #exposedField SFString
set_bind #eventIn SFBool
bind_changed #eventOut SFBool
}

Το πεδίο color δίνει προφανώς το χρώμα της ομίχλης. Το visibilityRange δίνει την απόσταση στην οποία πρέπει να βρίσκεται ένα αντικείμενο για να εξαφανιστεί τελείως μέσα στην ομίχλη, μεγάλες τιμές δημιουργούν αραιή ομίχλη ενώ μικρές τιμές δημιουργούν πυκνή ομίχλη, για 0.0 απενεργοποιείται η ομίχλη. Το πεδίο fogType παίρνει δύο τιμές: “LINEAR” και “EXPONENTIAL”, που δηλώνουν το αν μεταβάλλεται η πυκνότητα της ομίχλης με την απόσταση γραμμικά ή εκθετικά. Τα δυο Events που βρίσκουμε εδώ έχουν αντίστοιχη λειτουργία με τον κόμβο Background. Παραδείγματα:
Ο κόσμος με ομίχλη την ημέρα.
Ο κόσμος με ομίχλη την νύχτα.

Έλεγχος του επιπέδου λεπτομέρειας (ο κόμβος LOD (Level Of Detail))
Για να ελαττώσουμε τον χρόνο μέχρι να ανοίξει ο κόσμος μας στον browser του χρήστη μπορούμε να μειώσουμε το επίπεδο λεπτομέρειας ώστε το απαιτούμενο μέγεθος των δεδομένων που πρέπει να μεταφερθούν στον υπολογιστή του χρήστη να είναι μικρότερο από ολόκληρο τον κόσμο.
Χρησιμοποιούμε για αυτό τον κόμβο LOD:
LOD {
center #field SFVec3f
level #exposedField MFNode
range #field MFFloat
}

Η λογική αυτού του κόμβου είναι ότι στο πεδίο range εισάγουμε έναν ή περισσότερους αριθμούς οι οποίοι αντιπροσωπεύουν την απόσταση από το σημείο center στο οποίο συντελείται αλλαγή του επιπέδου λεπτομέρειας. Το πεδίο level περιέχει n+1 κόμβους-παιδιά όπου n είναι ο αριθμός των αριθμών που υπάρχουν στο πεδίο range, αυτό που γίνεται είναι ότι όταν η απόσταση από το κέντρο είναι από 0 μέχρι τον πρώτο αριθμό του range, τότε στη θέση center εμφανίζεται το 1ο παιδί της λίστας level, αν η απόσταση είναι από τον πρώτο αριθμό μέχρι τον δεύτερο, τότε εμφανίζεται το 2ο παιδί κ.ο.κ. Παραδείγματα:
Διαφορετική λεπτομέρεια σε έναν πίνακα επιγραφής:
Τρεις δαυλοί διαφορετικής λεπτομέρειας (δεν χρησιμοποιήθηκε ο κόμβος LOD ακόμα).
Πέντε δαυλοί που αλλάζουν λεπτομέρεια ανάλογα με την απόσταση:[28]
Αρχή

Προκαθορισμένες οπτικές γωνίες (ο κόμβος Viewpoint)

Για την καλύτερη περιήγηση στον VRML κόσμο υπάρχουν προκαθορισμένες οπτικές γωνίες στις οποίες μπορεί να μεταφερθεί ο χρήστης όποτε το θελήσει. Για αυτή τη δυνατότητα χρησιμοποιούμε τον κόμβο Viewpoint:
Viewpoint {
position #exposedField SFVec3f
orientation #exposedField SFRotation
fieldOfView #exposedField SFFloat
description #field SFString
jump #exposedField SFBool
set_bind #eventIn SFBool
isBound #eventOut SFBool
bindTime #eventOut SFTime
}

Τα πεδία position (θέση), orientation (προσανατολισμός) και fieldOfView (οπτικό πεδίο) καθορίζουν πως θα βλέπει ο χρήστης τον κόσμο από αυτήν την οπτική γωνία. Το πεδίο description είναι μια περιγραφή της οπτικής γωνίας. Το πεδίο jump έχει κάπως περίπλοκη σημασία και συνοπτικά σημαίνει τα εξής: Αν μια οπτική γωνία έχει jump “TRUE” τότε μόλις επιλέξει ο χρήστης αυτήν την οπτική γωνία μεταφέρεται στον χώρο ανάλογα με τα πεδία position, orientation και fieldOfView. Αν η οπτική γωνία έχει το πεδίο jump “FALSE” και ο χρήστης επιλέξει την οπτική γωνία τότε ο χρήστης παραμένει εκεί που είναι και τα πρώτα τρία πεδία δεν έχουν καμία επίδραση πάνω του, παρ’ όλα αυτά βρίσκεται στην οπτική γωνία που επέλεξε (αυτό σημαίνει ότι αν η οπτική γωνία βρίσκεται λ.χ. σε ένα ασανσέρ και κινείται προς τα πάνω, τότε όπου και να βρίσκεται ο χρήστης θα κινείται και αυτός προς τα πάνω). Το eventIn set_bind αλλάζει την οπτική γωνία, το eventOut isBound επιστρέφει “TRUE” αν αυτή η οπτική γωνία είναι η ενεργή. Τέλος το eventOut bindTime επιστρέφει τον χρόνο που ο χρήστης χρησιμοποιεί αυτήν την οπτική γωνία. Παράδειγμα:
Διαφορετικές οπτικές γωνίες:[29]
Αρχή

Προκαθορισμένες επιλογές για την περιήγηση (ο κόμβος NavigationInfo)

Στοιχεία όπως η ταχύτητα και το είδος (περπάτημα, πτήση ή εξέταση) της περιήγησης στον εικονικό κόσμο καθορίζονται από τον κόμβο NavigationInfo:
NavigationInfo {
type #exposedField MFString
speed #exposedField SFFloat
avatarSize #exposedField MFFloat
headlight #exposedField SFBool
visibilityLimit #exposedField SFFloat
set_bind #eventIn SFBool
isBound #eventOut SFBool
}

Το πεδίο type παίρνει τιμές “WALK”, “FLY”, “EXAMINE” ή “NONE”. Το πεδίο speed καθορίζει την ταχύτητα της περιήγησης σε μονάδες ανά δευτερόλεπτο. Το πεδίο avatarSize είναι μια λίστα από τρεις τιμές που καθορίζουν τις διαστάσεις του «σώματος» που χρησιμοποιεί ο χρήστης για την περιήγηση του (αυτές οι διαστάσεις χρησιμοποιούνται π.χ. για ανίχνευση σύγκρουσης και είναι: ο πρώτος αριθμός είναι το πλάτος και μήκος του σώματος, ο δεύτερος αριθμός είναι το ύψος του σώματος και ο τρίτος αριθμός είναι το μέγιστο ύψος του εμποδίου το οποίο μπορεί ο χρήστης να ξεπεράσει περπατώντας). Το πεδίο headlight καθορίζει εάν θα ανάβει ο προβολέας ή όχι. Ο αριθμός visibilityLimit είναι το όριο όρασης του χρήστη, πέρα από αυτό δεν εμφανίζεται κανένα αντικείμενο (πέρα από το φόντο βέβαια, ενώ για 0.0 το όριο είναι στο άπειρο). Τα eventIn και eventOut set_bind και isBound αντίστοιχα έχουν τον πλέον γνωστό ρόλο να ενεργοποιούν και να επιστρέφουν την κατάσταση για αυτόν τον κόμβο.
Αρχή

Έλεγχος σύγκρουσης (ο κόμβος Collision)

Ο έλεγχος σύγκρουσης γίνεται με τον κόμβο Collision:
Collision {
children #exposedField MFNode
bboxCenter #field SfVec3f
bboxSize #field SFVec3f
collide #exposedField SFBool
proxy #field SFNode
collideTime #eventOut SFTime
addChildren #eventIn MFNode
removeChildren #eventOut MFNode
}

Το πεδίο children είναι μια λίστα από κόμβους για τους οποίους θα γίνεται η ανίχνευση σύγκρουσης. Τα δυο παρακάτω πεδία (bboxCenter και bboxSize) καθορίζουν ένα σημείο και ένα ορθογώνιο παραλληλεπίπεδο γύρω από αυτό το σημείο που περικλείει όλα τα αντικείμενα που δηλώθηκαν στο πεδίο children, όμως αν δώσουμε στο bboxSize -1.0 για μήκος, πλάτος και ύψος τότε το παραλληλεπίπεδο υπολογίζεται αυτόματα. Το πεδίο collide ενεργοποιεί και απενεργοποιεί την ανίχνευση σύγκρουσης. Το πεδίο proxy περιέχει την περιγραφή ενός αντικειμένου το οποίο θα χρησιμοποιηθεί αντί για τα αντικείμενα στο children για την ανίχνευση (το αντικείμενο proxy είναι αόρατο και θα χρησιμοποιείται μόνο για την ανίχνευση σύγκρουσης αντί για κάθε αντικείμενο του children). Τα addChildren, removeChildren και set_children (το εγγενές event του πεδίου children) events προσθέτουν, αφαιρούν ή καθορίζουν τους κόμβους που θα ανιχνεύονται για σύγκρουση. Παράδειγμα:
Συγκρουστείτε με τον κώνο και θα ακουστεί ένας ήχος:[30]

Διάθεση πληροφοριών για τον κόσμο μας (ο κόμβος WorldInfo)
Ο κόμβος WorldInfo είναι πάρα πολύ απλός:
WorldInfo {
title #field SFString
info #filed MFString
}
Το πεδίο title είναι ο τίτλος του κόσμου μας ενώ το πεδίο info είναι μια λίστα από συμβολοσειρές οι οποίες χρησιμεύουν για την περιγραφή του κόσμου μας.
Αρχή

Προσθέτοντας ήχο (οι κόμβοι AudioClip και Sound)

Για να προσθέσουμε ήχο στον κόσμο μας χρησιμοποιούμε τους κόμβους AudioClip και Sound:
AudioClip {
url #exposedField MFString
description #exposedField SFString
startTime #exposedField SFTime
stopTime #exposedField SFTime
pitch #exposedField SFFloat
loop #exposedField SFBool
isActive #eventOut SFBool
duration_changed #eventOut SFFloat
}

Το πρώτο πεδίο είναι μια λίστα από αρχεία ήχου (σε General MIDI τύπου 1 ή WAV format) με τις διευθύνσεις τους (απόλυτες ή σχετικές), αυτό γίνεται ώστε αν δεν μπορεί να ανοιχτεί το πρώτο αρχείο τότε να αναζητηθεί το δεύτερο κ.ο.κ.. Το πεδίο description χρησιμοποιείται για να εμφανίσει ο συγγραφέας του VRML κόσμου μια περιγραφή του ήχου. Τα πεδία startTime και stopTime καθορίζουν πότε θα αρχίσει και πότε θα σταματήσει να παίζεται ο ήχος, τα δυο αυτά πεδία είναι απόλυτοι χρόνοι (το 0.0 είναι τα μεσάνυχτα της 1ης Ιανουαρίου 1970). Το πεδίο pitch επιταχύνει ή επιβραδύνει τον ήχο όπου για τιμή 1.0 έχουμε την αρχική ταχύτητα. Το πεδίο loop καθορίζει αν το κομμάτι θα παίζει επαναλαμβανόμενα ή μόνο μια φορά. Το eventOut isActive επιστρέφει “TRUE” όσο ο ήχος παίζεται και το duration_changed επιστρέφει την διάρκεια του ήχου η οποία εξάγεται κατά την ανάγνωση του αρχείου.
Sound {
source #exposedField SFNode
intensity #exposedField SFFloat
location #exposedField SFVec3f
direction #exposedField SFVec3f
minFront #exposedField SFFloat
minBack #exposedField SFFloat
maxFront #exposedField SFFloat
maxBack #exposedField SFFloat
priority #exposedField SFFloat
spatialize #field SFBool
}

Ο κόμβος AudioClip από μόνος του δεν παράγει ήχο, για να λειτουργήσει χρειάζεται τον κόμβο Sound. Είναι εύκολο να φανταστούμε αυτό το σχήμα σαν το CD-Player με το ηχείο. Το πρώτο πεδίο του Sound είναι ένας κόμβος που είναι η πηγή του ήχου (μπορεί να είναι είτε ένας κόμβος AudioClip ή MovieTexture, ή NULL οπότε δεν παράγεται ήχος). Το πεδίο intensity καθορίζει την ένταση του ήχου και κυμαίνεται από 0.0 μέχρι 1.0. Τα πεδία location και direction καθορίζουν την θέση και την κατεύθυνση που θα έχει το ηχείο μας. Τα επόμενα τέσσερα πεδία (minFront, minBack, maxFront και maxBack) χρησιμοποιούνται για την ελεγχόμενη απόσβεση του ήχου όσο μεγαλώνει η απόσταση, μέσα στην εσωτερική έλλειψη η ένταση είναι ίση με το πεδίο intensity ενώ έξω από την εξωτερική έλλειψη η ένταση είναι 0: [31]
Το επόμενο πεδίο δίνει την προτεραιότητα του ήχου που παίζεται (από 0.0 μέχρι 1.0) και χρειάζεται σε περίπτωση που θέλουμε να παίξουμε παραπάνω ήχους από όσους μπορεί να παίξει σε μια στιγμή η κάρτα ήχου του χρήστη οπότε είναι για παράδειγμα σημαντικότερο να ακουστεί μια ανακοίνωση παρά η background μουσική. Τέλος το spatialize μετατρέπει τον ήχο σε μονοφωνικό και τον επεξεργάζεται δίδοντας του 3-D ακουστική, η ένταση δεν αλλάζει και παραμένει όσο προβλέπουν οι ελλείψεις. Παραδείγματα:
minFront = minBack = 200: εδώ

minFront = minBack = 10
maxFront = maxBack = 40: εδώ

minFront = minBack = 5
maxFront = maxBack = 51: εδώ

Δυναμική μετατροπή του κόσμου (μηνύματα Event, υποδοχές EventIn και EventOut, και διαδρομές Routes)
Παραπάνω στο τελευταίο παράδειγμα πρέπει να κάνετε κλικ με το ποντίκι επάνω στην σφαίρα για να ακουστεί ο ήχος. Αυτό είναι ένα τυπικό παράδειγμα χρήσης των events και routes για μεγαλύτερη αλληλεπίδραση με τον VRML κόσμο. Η λογική πίσω από τα events είναι ότι για έναν κόμβο υπάρχουν υποδοχές εισόδου και εξόδου (eventIn και eventOut), οι υποδοχές εξόδου παράγουν events (γεγονότα) και τα eventIn δέχονται γεγονότα και με βάση αυτά αλλάζουν ένα πεδίο του κόμβου. Δημιουργείται ένα route όταν συνδέουμε ένα eventIn με ένα eventOut και έτσι μια ενέργεια π.χ. το κλικ επάνω στο φως σε ένα δωμάτιο προκαλεί την ενεργοποίηση του, την αλλαγή του χρώματος του ή το άνοιγμα μιας πόρτας στο δωμάτιο ανάλογα με τα routes που δημιουργήσαμε. Πέρα από τα events που αναφέραμε για κάθε κόμβο ξεχωριστά υπάρχουν πολλά ακόμα, συγκεκριμένα για κάθε πεδίο τύπου #exposedField υπάρχουν δυο events: ένα eventIn και ένα eventOut που λέγονται set_XXXX και XXXX_changed αντίστοιχα όπου XXXX είναι το όνομα του πεδίου, το set_XXXX αλλάζει την τιμή του πεδίου αν δεχτεί ένα γεγονός ενώ το XXXX_changed παράγει ένα γεγονός όποτε αλλάξει το πεδίο.[35]Παραπάνω φαίνεται σχηματικά ένας κόμβος με ένα πεδίο τύπου #field και ένα πεδίο τύπου #exposedField το οποίο έχει εγγενώς δυο events συσχετισμένα μαζί του. Επίσης φαίνονται events που ανήκουν στον κόμβο και διαφοροποιούνται ανάλογα με τον κόμβο (αυτά είναι τα events που αναφέραμε μέχρι τώρα ρητά στην παρουσίαση κάθε κόμβου).
Για παράδειγμα για τον κόμβο Collide έχουμε:[36]
Τα routes πρέπει να διευκρινιστεί ότι δεν είναι κόμβοι. Επίσης πρέπει ο τύπος της εξόδου να είναι ακριβώς ο ίδιος με τον τύπο της εισόδου (ο τύπος του κάθε πεδίου φαίνεται στην τελευταία στήλη της παρουσίασης κάθε κόμβου). Είναι δυνατόν να συνδεθεί μια έξοδος σε πολλές εισόδους ή πολλές έξοδοι σε μια είσοδο. Για να μπορέσουμε να χρησιμοποιήσουμε έναν κόμβο σε route πρέπει να τον ονομάσουμε με χρήση της DEF. Παρακάτω φαίνεται η τυπική σύνταξη μιας διαδρομής και ένα σχήμα για αυτό το route:
ROUTE Node1.collideTime TO Node2.startTime[37]
Παράδειγμα:
Ας ξαναδούμε το παράδειγμα του κόμβου Collide:[38]
Αρχή

Ανίχνευση της εγγύτητας του χρήστη (ο κόμβος ProximitySensor (επίσης οι κόμβοι LOD, VisibilitySensor και Collision))

Για να ανιχνεύσουμε το αν ο χρήστης βρίσκεται κοντά σε κάποιο αντικείμενο υπάρχουν τρεις τρόποι: Ανιχνεύοντας αν υπάρχει ορατότητα του αντικειμένου από τον χρήστη, ανιχνεύοντας αν ο χρήστης βρίσκεται σε κάποια απόσταση από το αντικείμενο ή ανιχνεύοντας κάποια σύγκρουση. Το τελευταίο το εξηγήσαμε ήδη στον κόμβο Collide οπότε είναι περιττό να επαναλάβουμε εδώ. Η ανίχνευση μέσω του οπτικού πεδίου του χρήστη χρησιμοποιείται στον κόμβο VisibilitySensor:
VisibilitySensor {
enabled #exposedField SFBool
center #exposedField SFVec3f
Size #exposedField SFVec3f
isActive #eventOut SFBool
enterTime #eventOut SFTime
exitTime #eventOut SFTime
}

Το πεδίο enabled ενε-/απενεργοποιεί τον ανιχνευτή. Τα πεδία center και size καθορίζουν ένα ορθογώνιο παραλληλεπίπεδο μέσα στο οποίο γίνεται η ανίχνευση. Αν ανιχνευτεί οποιοδήποτε μέρος του οπτικού πεδίου του χρήστη μέσα στον χώρο όπου ενεργεί ο ανιχνευτής τότε το eventOut isActive επιστρέφει “TRUE” και το eventOut enterTime επιστρέφει τον τρέχον απόλυτο χρόνο. Αν δεν ανιχνευτεί το οπτικό πεδίο του χρήστη τότε το isActive γίνεται “FALSE” και το exitTime επιστρέφει τον τρέχον απόλυτο χρόνο.
Η ανίχνευση μέσω απόστασης πέρα από τον κόμβο LOD (τον οποίο αναφέραμε νωρίτερα) χρησιμοποιείται και στον κόμβο ProximitySensor:
ProximitySensor {
enabled #exposedField SFBool
center #exposedField SFVec3f
size #exposedField SFVec3f
isActive #eventOut SFBool
enterTime #eventOut SFTime
exitTime #eventOut SFTime
position_changed #eventOut SFVec3f
orientation_changed #eventOut SFRotation
}
Τα πεδία enabled, center και size είναι τα ίδια με εκείνα του κόμβου VisibilitySensor. Όταν ο περιηγητής εισέλθει στον χώρο ανίχνευσης το isActive επιστρέφει “TRUE” και το enterTime επιστρέφει τον τρέχον απόλυτο χρόνο. Αντίστοιχα όταν ο περιηγητής εξέλθει του χώρου ανίχνευσης το isActive επιστρέφει “FALSE” και το exitTime επιστρέφει τον τρέχον απόλυτο χρόνο. Το eventOut position_changed επιστρέφει την θέση του χρήστη όποτε αλλάξει και εκείνος βρίσκεται ακόμα στο χώρο ανίχνευσης, ανάλογα το orientation_changed επιστρέφει τον προσανατολισμό του χρήστη όποτε αλλάξει. Παράδειγμα:
Πλησιάστε τον κώνο:[39]

Ανίχνευση των ενεργειών του χρήστη (κόμβοι TouchSensor, Anchor, CylinderSensor, PlaneSensor και SphereSensor)
Οι ενέργειες που μπορεί να κάνει ο χρήστης στον VRML κόσμο πέρα από την περιήγηση είναι να μεταφέρει τον δείκτη επάνω σε ένα αντικείμενο, να πατήσει επάνω σε ένα αντικείμενο με το αριστερό πλήκτρο του ποντικιού και να το αφήσει αμέσως μετά ή να πατήσει επάνω σε ένα αντικείμενο με το αριστερό πλήκτρο του ποντικιού, να τραβήξει το ποντίκι κάπου και ύστερα να αφήσει το πλήκτρο. Για αυτές τις ενέργειες έχουμε ένα σύνολο κόμβων:
Ο κόμβος Anchor:
Anchor {
children #exposedField MFNode
bboxCenter #field SFVec3f
bboxSize #field SFVec3f
url #exposedField MFString
parameter #exposedField MFString
description #exposedField MFString
addChildren #eventIn MFNode
removeChildren #eventOut MFNode
}
Με τον κόμβο Anchor συνδέουμε τον παρόν VRML κόσμο με κάποιον άλλο επιτρέποντας στον περιηγητή να περάσει μέσω μιας πύλης (του αντικειμένου ή των αντικειμένων στο πεδίο children του Anchor) πατώντας το αριστερό πλήκτρο του ποντικιού σε έναν νέο κόσμο. Στα πεδία bboxCenter και bboxSize πρέπει να μπουν τιμές ώστε το ορθογώνιο παραλληλεπίπεδο που ορίζουν να περικλείει όλα τα αντικείμενα του πεδίου children (και πάλι για -1.0 υπολογίζεται αυτόματα). Το πεδίο url είναι η διεύθυνση του νέου VRML αρχείου, το πεδίο parameter κρατά προαιρετικές παραμέτρους για τον Web browser. Τέλος το description είναι ένα κείμενο που εμφανίζεται όταν ο δείκτης του ποντικιού βρίσκεται σε σημείο που να ενεργοποιεί το Anchor.
Ο κόμβος TouchSensor:
TouchSensor {
enabled #exposedField SFBool
isActive #eventOut SFBool
isOver #eventOut SFBool
touchtime #eventOut SFTime
hitPoint_changed #eventOut SFVec3f
hitNormal_changed #eventOut SFVec3f
hitTexCoord_changed #eventOut SFVec2f
}
Το πεδίο enabled ενεργοποιεί τον ανιχνευτή. Όσο ο χρήστης έχει τον δείκτη επάνω στο αντικείμενο που ανιχνεύεται το πεδίο isOver είναι “TRUE”, το eventOut hitPoint_changed επιστρέφει την θέση του δείκτη επάνω στο αντικείμενο, το hitNormal_changed επιστρέφει την θέση του δείκτη επάνω στο Normal διάνυσμα και το hitTexture_changed επιστρέφει την θέση του δείκτη επάνω στην υφή (θα μιλήσουμε για αυτά σε επόμενη ενότητα). Όταν ο χρήστης πατήσει το αριστερό πλήκτρο όσο ο δείκτης βρίσκεται επάνω στο αντικείμενο, τότε το πεδίο isActive γίνεται “TRUE”. Εάν ο χρήστης αφήσει το πλήκτρο όσο ο δείκτης βρίσκεται επάνω στο αντικείμενο τότε εκτός από το isActive που γίνεται πάλι “FALSE” επιστρέφεται και ο τρέχον απόλυτος χρόνος από το touchtime.
Ο κόμβος CylinderSensor επιτρέπει στον χρήστη να περιστρέψει ένα αντικείμενο γύρω από τον τοπικό Υ άξονα του αντικειμένου:
CylinderSensor {
enabled #exposedField SFBool
diskAngle #exposedField SFFloat
autoOffset #exposedField SFBool
offset #exposedField SFFloat
maxAngle #exposedField SFFloat
minAngle #exposedField SFFloat
isActive #eventOut SFBool
rotation_changed #eventOut SFRotation
trackPoint_changed #eventOut SFVec3f
}
Το πεδίο enabled είναι ίδιο με αυτό του κόμβου TouchSensor. Το πεδίο diskAngle καθορίζει ποιόν από δυο τρόπους περιστροφής θα χρησιμοποιήσει ο χρήστης (εξαρτάται από το πώς βλέπει το αντικείμενο ο χρήστης). Τα πεδία maxAngle και minAngle περιορίζουν την περιστροφή ανάμεσα σε δυο γωνίες.
Ο κόμβος PlaneSensor επιτρέπει στον χρήστη να μεταφέρει ένα αντικείμενο στο τοπικό XY επίπεδο του αντικειμένου:
PlaneSensor {
enabled #exposedField SFBool
autoOffset #exposedField SFBool
Offset #exposedField SFVec3f
maxPosition #exposedField SFVec2f
minPosition #exposedField SFVec2f
isActive #eventOut SFBool
translation_changed #eventOut SFVec3f
trackpoint_changed #eventOut SFVec3f
}
Η λειτουργία και τα πεδία του είναι παρόμοια με τον κόμβο CylinderSensor.
Ο κόμβος SphereSensor είναι το αντίστοιχο των δυο προηγούμενων για περιστροφή στις τρεις διαστάσεις.
SphereSensor {
enabled #exposedField SFBool
autoOffset #exposedField SFBool
offset #exposedField SFRotation
isActive #eventOut SFBool
rotation_changed #eventOut SFRotation
trackpoint_changed #eventOut SFVec3f
}
Παραδείγματα:
Παράδειγμα του Anchor.
Παράδειγμα του TouchSensor.
Παράδειγμα με CylindricalSensor, PlaneSensor και SphereSensor.
Αρχή

Χρήση του χρόνου για κίνηση (κόμβος TimeSensor)

Ο κόμβος TimeSensor δημιουργεί ένα ρολόι για τον έλεγχο των animations:
TimeSensor {
enabled #exposedField SFBool
startTime #exposedField SFTime
stopTime #exposedField SFTime
cycleInterval #exposedField SFTime
loop #exposedField SFBool
isActive #eventOut SFBool
time #eventOut SFTime
cycleTime #eventOut SFTime
fraction_changed #eventOut SFFloat
}

Τα πεδία enabled, startTime και stopTime είναι προφανές το τι κάνουν. Το πεδίο cycleInterval αντιστοιχεί στον κύκλο του ρολογιού (που κυλάει από 0.0 μέχρι 1.0) ένα διάστημα σε δευτερόλεπτα κάνοντας έτσι το διάστημα όσο μικρό ή μεγάλο θέλει ο συγγραφέας. Το isActive eventOut επιστρέφει μια φορά “TRUE” όταν το ρολόι ενεργοποιείται και μια φορά “FALSE” όταν απενεργοποιείται. Το eventOut time επιστρέφει συνεχώς όσο το ρολόι λειτουργεί τον τρέχον απόλυτο χρόνο. Το επόμενο eventOut cycleTime επιστρέφει τον απόλυτο χρόνο μόνο στην αρχή κάθε κύκλου και τέλος το fraction_changed επιστρέφει τον τρέχον χρόνο σε τοπικό χρόνο του ρολογιού (από 0.0 μέχρι 1.0) και όχι τον απόλυτο χρόνο. Παράδειγμα:
Μονόλιθοι.
Αρχή

Παρεμβολή (interpolation) θέσεων (κόμβος PositionInterpolator)

Για να δώσουμε κίνηση σε ένα αντικείμενο δεν χρειάζεται να αναφέρουμε κάθε θέση του αντικειμένου την κάθε χρονική στιγμή. Αρκεί να δώσουμε κάποιες σημαντικές θέσεις και τους χρόνους και ο κόμβος PositionInterpolator θα υπολογίσει γραμμικά τις ενδιάμεσες θέσεις:
PositionInterpolator {
key #exposedField MFFloat
keyValue #exposedField MFVec3f
set_fraction #eventIn SFFloat
value_changed #eventOut SFVec3f
}
Το πεδίο key είναι μια λίστα από τιμές ανάμεσα στο 0.0 και στο 1.0 οι οποίες είναι οι χρονικές στιγμές που αντιστοιχούν στις θέσεις-κλειδιά που θα δώσουμε. Το επόμενο πεδίο είναι αυτές οι θέσεις-κλειδιά. Το eventIn set_fraction είναι ο χρόνος (από 0.0 μέχρι 1.0) που εισάγεται στον PositionInterpolator κόμβο για να εξαχθεί (μέσω του value_changed eventOut) η θέση του αντικειμένου σύμφωνα με τα όσα εισάγαμε στα πεδία key και keyValue. Παραδείγματα:
Κίνηση με παρεμβολή.

Παρεμβολή άλλων χαρακτηριστικών (κόμβοι OrientationInterpolator (για περιστροφή), ColorInterpolator, CoordinateInterpolator, NormalInterpolator, ScalarInterpolator)
Αντίστοιχα με την αλλαγή θέσης (κίνηση) η γραμμική παρεμβολή χρησιμοποιείται και για περιστροφή με τον κόμβο OrientationInterpolator, για αλλαγή χρώματος με τον κόμβο ColorInterpolator, για αλλαγή συντεταγμένων και αλλαγή των διανυσμάτων Normal (σε κόμβους με βάση συντεταγμένες όπως PointSet, IndexedLineSet και IndexedFaceSet) με τους κόμβους CoordinateInterpolator και NormalInterpolator αντίστοιχα, και τέλος για γενικές περιπτώσεις όπου οι διάφορες τιμές είναι τύπου SFFloat έχουμε τον κόμβο ScalarInterpolator. Παρακάτω έχουμε τον OrientationInterpolator, οι υπόλοιποι κόμβοι διαφέρουν μόνο στον τύπο των πεδίων keyValue και value_changed:
OrientationInterpolator {
key #exposedField MFFloat
keyValue #exposedField MFRotation
set_fraction #eventIn SFFloat
value_changed #eventOut SFRotation
}
Παράδειγμα:
Χρήση των OrientationInterpolator και ScalarInterpolator κόμβων.
Αρχή

Χρήση scripts (κόμβος Script)

Οι ενσωματωμένοι sensors, interpolators, shapes, κτλ. δεν τα καταφέρνουν καλά με περίπλοκες δραστηριότητες όπως για παράδειγμα την τροχιά ενός βλήματος σε βαρυτικό πεδίο. Για αυτόν τον σκοπό υπάρχει η δυνατότητα της χρήσης scripts μέσω του Script κόμβου:
Script {
url “circle.class”
ή …
url “circle.js”
ή …
url “javascript: ...”
}
δηλαδή ο κόμβος περιέχει την διεύθυνση προς ένα java αρχείο. Επίσης στον Script κόμβο ορίζονται πεδία και events ως εξής:
Script {
field SFFloat cycles 1.0
eventIn SFFloat set_fraction
eventOut SFVec3f position_changed
}
Παράδειγμα:
Μπάλα που κινείται σε ημιτονοειδή τροχιά:Πατήστε εδώ για το πρώτο παράδειγμα και εδώ για το δεύτερο.

Δημιουργία καινούργιων τύπων κόμβων (PROTO, IS και EXTERNPROTO)
Είναι δυνατόν να δημιουργήσουμε νέους τύπους κόμβων, αυτό γίνεται όπως φαίνεται παρακάτω:
PROTO MyNode [
...
field fieldType fieldName defaultValue
exposedField fieldType fieldName defaultValue
eventIn eventInType eventInName
eventOut eventOutType eventOutName
...
] {
nodeBody
}

Στο nodeBody επιτρέπεται να γράψουμε κανονικά οτιδήποτε θα γράφαμε σε ένα VRML πρόγραμμα. Συνδέουμε τα field, exposedField, eventIn και eventOut της επικεφαλίδας με την λέξη IS ως εξής:
PROTO Cube [
Field SFVec3f cubeSize 0.0 0.0 0.0
] {
Shape {
appearance Appearance {
Material Material { }
}
geometry Box {
size IS cubeSize
}
}
}
Ο τύπος του νέου κόμβου είναι ίδιος με τον τύπο του πρώτου κόμβου στο nodeBody και ο PROTO κόμβος μπορεί να χρησιμοποιηθεί μόνο εκεί όπου του το επιτρέπει ο τύπος του, π.χ. ο Cube χρησιμοποιείται όπου μπορεί να χρησιμοποιηθεί ο Shape κόμβος.
Μπορούμε να χρησιμοποιήσουμε αρχεία αντί να γράψουμε όλους τους κόμβους στο nodeBody με την EXTERNPROTO:
PROTO MyNode [
...
field fieldType fieldName defaultValue
exposedField fieldType fieldName defaultValue
eventIn eventInType eventInName
eventOut eventOutType eventOutName
...
] {
url ή [ urlList]
}
Ορισμός & Ομαδοποίηση Κόμβων:
Οι κόμβοι χρησιμοποιούνται για να εκφράσουν τα κατασκευασμένα σχήματα και τις αντίστοιχες ιδιότητες τους. Κατά τον ορισμό των κόμβων απαιτείται να καθορίζεται το όνομά του, το είδος του, καθώς και ένας αριθμός προαιρετικών πεδίων με τις αντίστοιχες τιμές τους. Ως τιμές των πεδίων μπορεί να είναι μεταξύ άλλων και κάποιος άλλος κόμβος. Ο αρχικός, στην περίπτωση αυτή, ονομάζεται πατέρας (father) ενώ όλοι οι άλλοι κόμβοι που περιέχονται σε αυτόν αποκαλούνται παιδιά (children) του. Προφανώς ο πατέρας κόμβος ή αλλιώς πρόγονος των υπολοίπων μπορεί να είναι παιδί σε κάποιον άλλο πατέρα. Κατ’αυτό τον τρόπο φτάνουμε σε ένα κόμβο αρχικό από τον οποίο, τελικά, προκύπτουν όλοι οι υπόλοιποι, τον κόμβο ρίζα (root node).
Ένας κόμβος μπορεί να οριστεί μια φορά και να χρησιμοποιηθεί περισσότερες χωρίς φυσικά να οριστεί. Για να γίνει αυτό χρησιμοποιούμαι τις λέξεις DEF και USE. H πρώτη καθορίζει το όνομα του κόμβου που θα χρησιμοποιείται και η δεύτερη το αναφέρει όταν τον χρησιμοποιούμε.
Αρχή

Ένα group ορίζεται ως εξής:

Group {
children[…]
}


Στο πεδίο children έχουμε μια λίστα των παιδιών κόμβων. Προαιρετικά μπορούν να τοποθετηθούν και άλλα πεδία, τα οποία κατά περίπτωση καθορίζουν θέματα όπως την εμφάνιση των παιδιών ή συγκεκριμένες θέσεις μέσα στην ομάδα. Η ομαδοποίηση των κόμβων είναι ιδιαίτερα χρήσιμη όταν το ζητούμενο την απαιτεί για να κατασκευαστούν είτε πιο σύνθετα σχήματα, είτε ομάδες αντικειμένων που χρειάζεται να θεωρούνται ως σύνολο λόγω κοινών χαρακτηριστιικών και προβλημάτων.
Ομαδοποίηση μπορούμε να πετύχουμε και με τον κόμβο switch,
ο οποίος εμφανίζει συγκεκριμένα παιδιά από την ομάδα ανάλογα με την επιλογή που κάνει ο χρήστης.


Switch {
whichChoice 0
choice [. . .]
}

Shapes:

Τα σχήματα προσδιορίζονται από τη γεωμετρία τους και την εμφάνισή τους. Η πρώτη καθορίζει αυτό που στην καθημερινή γλώσσα αποτελεί την απάντηση στο ερώτημα « Tι σχήμα είναι αυτό; », ενώ η δεύτερη καθορίζει παράγοντες όπως είναι το χρώμα και υφή, στο βαθμό που αυτές μπορούν να παρουσιαστούν μέσω της εικόνας. Οι δυο αυτές έννοιες καθορίζονται στον κόμβο Shape. Ειδικότερα η εμφάνιση προσδιορίζεται από τους κόμβους Appearance και Material, οι οποίοι είναι μέσα στον Shape.


Οι προεπιλεγμένες τιμές των κόμβων Shape, Appearance και Material. Τα πεδία είναι προαιρετικά.

Shape {
appearance NULL
geometry NULL
}


Appearance {
material NULL
texture NULL
textureTranform NULL
}


Material {
ambientIntensity 0.2
diffuseColor 0.8 0.8 0.8
emissiveColor 0.0 0.0 0.0
shininess 0.2
specularColor 0.0 0.0 0.0
transparency
}


Box, Cone, Cylinder, Sphere Node:
Η VRML παρέχει ως βασικά σχήματα για την κατασκευή των υπόλοιπων πιο περίπλοκων σχημάτων, το κουτί (box), τον κώνο (cone), τον κύλινδρο (cylinder) και τη σφαίρα (sphere).

Οι προεπιλεγμένες τιμές για τα πεδία του σχήματος Box είναι:


Box {
size 2.0 2.0 2.0
}
Ο παραπάνω ορισμός καθορίζει την κατασκευή ενός κουτιού (κύβου) με διαστάσεις 2.0 2.0 2.0 για την κάθε ακμή του. Τονίζουμε, σε αυτό το σημείο, ότι μονάδα μέτρησης μπορεί να είναι οποιαδήποτε.


Για τον node Cone έχουμε:


Cone {
bottomRadius 1.0
height 2.0
side TRUE
bottom TRUE
}
Οι λειτουργίες των δυο πρώτων πεδίων είναι προφανής. Το πεδίο side εκφράζει το αν θα έχει ή όχι πλευρές ο κόμβος, ενώ το πεδίο bottom εκφράζει το αντίστοιχο για τη βάση του κόμβου.

Για τον node Cylinder έχουμε:


Cylinder {
radius 1.0
height 2.0
side TRUE
top TRUE
bottom TRUE
}

Για τον node Sphere έχουμε:


Sphere {
radius 1.0
}

Τα πεδία των παραπάνω κόμβων έχουν προφανή λειτουργία.


Συγκεντρώνοντας όλα τα παραπάνω δείχνουμε ένα παράδειγμα ενός φανταστικού διαστημικού σταθμού.


# VRML V2.0 utf8
Group {
children [
Shape {
appearance DEF White Appearance {
material Material {}
}
geometry Box {
size 10.0 10.0 10.0
}
},
Shape {
appearance USE White
geometry Sphere {
radius 7.0
}
},
Shape {
appearance USE White
geometry Cylinder {
radius 7.0
}
},
Shape {
appearance USE White
geometry Cylinder {
radius 4.0
height 20.0
}
},
Shape {
appearance USE White
geometry Cylinder {
radius 3.0
height 30.0
}
},
Shape {
appearance USE White
geometry Cylinder {
radius 1.0
height 60.0
}
}
]
}

Το αποτέλεσμα σε σμίκρυνση και ελάχιστα στραμμένο προς τα αριστερά, είναι το εξής: