VRML97 (ISO/IEC 14772-1:1997) defines the text form of a VRML world, which the
Web3D Consortium publishes. This page follows its concepts and field type clauses. It
covers VRML 2.0 and VRML97, which are the same language; VRML 1.0 files, with the
header #VRML V1.0 ascii, use a different, Open Inventor-like syntax and
node set that is not described here. The file extension is .wrl and the
media type model/vrml (browsers also accept the older
x-world/x-vrml).
Header line
The first line is #VRML V2.0 utf8, with exactly one space between the
three parts. It ends with a line break, or with spaces or tabs and a comment, which a
reader may ignore. The text is UTF-8.
Comments, separators and names
#starts a comment to the end of the line, except inside a quoted string.- Spaces, tabs, line feeds, carriage returns and commas are all
separators:
1, 2, 3and1 2 3are the same. - A name (of a node, field, event or prototype) may use any Unicode character
except control characters, space,
" ' # , . [ ] \ { }and delete, and may not start with a digit,+or-. Names are case-sensitive. - Reserved words:
DEF,EXTERNPROTO,FALSE,IS,NULL,PROTO,ROUTE,TO,TRUE,USE,eventIn,eventOut,exposedField,field.
Statements
| Statement | Form | Meaning |
|---|---|---|
| node | [DEF name] Type { fields } | a node and its field values; the body may also hold IS, ROUTE, PROTO and EXTERNPROTO statements |
| field | name value or name [ values ] | a value for one field; unset fields keep their defaults |
USE | USE name | the same node again, not a copy: it gains a second parent; the nearest earlier DEF of the name counts |
ROUTE | ROUTE a.out TO b.in | sends an eventOut of one node to an eventIn of another of exactly the same type; both nodes must be defined earlier |
PROTO | PROTO Name [ interface ] { body } | defines a new node type built from other nodes |
EXTERNPROTO | EXTERNPROTO Name [ interface ] "url" or [ urls ] | a prototype defined in another file; url#Name picks one by name, otherwise the file’s first PROTO |
IS | field IS interfaceField | inside a prototype body, ties a field or event to the prototype’s own |
A prototype interface declares eventIn type name,
eventOut type name, field type name value and
exposedField type name value; an EXTERNPROTO leaves out the
values. An exposedField zzz also acts as an eventIn
set_zzz and an eventOut zzz_changed, and a ROUTE
may use either name. Names given with DEF are local to their file or
prototype.
Field types
Each single-valued type (SF) has a multiple-valued form
(MF), written as values in square brackets; a single value may be written
without the brackets, and [] is empty.
| Type | Value | Example |
|---|---|---|
SFBool | TRUE or FALSE | solid FALSE |
SFColor, MFColor | red, green, blue, each 0 to 1 | diffuseColor 0 0.5 1 |
SFFloat, MFFloat | a single-precision number, with optional exponent | radius 2.5e-1 |
SFImage | width, height, components (1 grey, 2 grey and alpha, 3 RGB, 4 RGBA), then width × height pixels, each one integer holding all components, often in hexadecimal; pixels run from the bottom left, row by row | image 2 1 3 0xFF0000 0x00FF00 |
SFInt32, MFInt32 | a 32-bit integer, decimal or hexadecimal with 0x | whichChoice 0 |
SFNode, MFNode | a node statement, USE, or NULL | material Material { } |
SFRotation, MFRotation | an axis x, y, z (normalised) and an angle in radians | rotation 0 1 0 1.5708 |
SFString, MFString | UTF-8 text in double quotes; \" and \\ are the only escapes | url [ "a.png" "b.png" ] |
SFTime, MFTime | a double-precision number of seconds since 1 January 1970 GMT | startTime 0 |
SFVec2f, MFVec2f | two numbers | scale 1 1 |
SFVec3f, MFVec3f | three numbers | point [ 0 0 0, 1 0 0 ] |
There is no MFBool or MFImage in VRML97.
Units and coordinates
Lengths are in metres, angles in radians, times in seconds and colours from 0 to 1. The coordinate system is right-handed, with +Y up; the default viewpoint looks along −Z.
Example
#VRML V2.0 utf8
DEF Spinner Transform {
children Shape {
appearance Appearance { material Material { diffuseColor 1 0 0 } }
geometry Box { size 1 1 1 }
}
}
DEF Clock TimeSensor { cycleInterval 4 loop TRUE }
DEF Turn OrientationInterpolator {
key [ 0, 0.5, 1 ]
keyValue [ 0 1 0 0, 0 1 0 3.14159, 0 1 0 6.28318 ]
}
ROUTE Clock.fraction_changed TO Turn.set_fraction
ROUTE Turn.value_changed TO Spinner.set_rotation