Billboard {
eventIn MFNode addChildren
eventIn MFNode removeChildren
exposedField SFVec3f axisOfRotation 0 1 0 # (-
,
)
exposedField MFNode children []
field SFVec3f bboxCenter 0 0 0 # (-
,
)
field SFVec3f bboxSize -1 -1 -1 # (0,
)
} # or -1,-1,-1
The Billboard node is a grouping node which modifies its coordinate
system so that the Billboard node's local Z-axis turns to point at the
viewer. The Billboard node has children which may be other children
nodes.
The axisOfRotation field specifies which axis to use to perform
the rotation. This axis is defined in the local coordinate system.
In general, the following steps described how to rotate the billboard
to face the viewer:
- Compute the vector from the Billboard node's origin to the viewer's
position. This line is called the billboard-to-viewer vector.
- Compute the plane defined by the axisOfRotation and the
billboard-to-viewer line.
- Rotate the local Z-axis of the billboard into the plane from b.,
pivoting around the axisOfRotation.
A special case of billboarding is viewer-alignment. In this
case, the object rotates to keep the billboard's local Y-axis parallel
with the viewer's up vector. This special case is distinguished by setting
the axisOfRotation to (0, 0, 0). The following steps describe
how to align the billboard's Y-axis to the viewer's up vector:
- Compute the billboard-to-viewer vector.
- Rotate the Z-axis of the billboard to be collinear with the billboard-to-viewer
vector and pointing towards the viewer's position.
- Rotate the Y-axis of the billboard to be parallel and oriented
in the same direction as the up vector of the viewer.
TIP: Screen-aligned billboards are especially useful
for labels that follow the viewer and are always readable. Typically,
a Text node or ImageTexture would be parented by a Billboard node
with axisOfRotation set to (0,0,0). See the following example. |
When the axisOfRotation and the billboard-to-viewer line are
coincident, the plane cannot be established and the resulting rotation
of the billboard is undefined. For example, if the axisOfRotation
is set to (0,1,0) (Y-axis) and the viewer flies over the billboard and
peers directly down the Y-axis, the results are undefined.
Multiple instances of Billboard nodes (DEF/USE) operate as expected:
each instance rotates in its unique coordinate system to face the viewer.
Section "2.6.5 Grouping and children nodes"
provides a description of the children, addChildren, and
removeChildren fields and eventIns.
The bboxCenter and bboxSize fields specify a bounding
box that encloses the Billboard node's children. This is a hint that
may be used for optimization purposes. If the specified bounding box
is smaller than the actual bounding box of the children at any time,
the results are undefined. A default bboxSize value, (-1, -1, -1),
implies that the bounding box is not specified and if needed must be
calculated by the browser. A description of the bboxCenter and
bboxSize fields is contained in "2.6.4
Bounding boxes."

Figure 3-4: Billboard Node
TECHNICAL
NOTE: The
Billboard node is really just a very fancy Transform node that
modifies its own rotation based on the relationship between the
Transform node and the user's view. In fact, a Billboard could
be prototyped that way by combining a Transform node, a ProximitySensor
to detect the user's view, and a Script to perform the necessary
computations. However, Billboard transformations must be updated
whenever the viewer moves, and it is much more efficient for the
Billboard functionality to be built in to VRML implementations
rather than left to Script nodes. Billboards are often used with
transparent textured rectangles to approximate 3D geometry with
a 2D "cutout," also known as a sprite. If you have images of trees
(with appropriate transparency values with the image), you might
define a sprite prototype as
PROTO Sprite [ field MFString texture [ ] ]
{
Billboard {
axisOfRotation 0 1 0 # Rotate about Y (up) axis
children Shape {
appearance Appearance {
texture ImageTexture { url IS texture }
}
geometry IndexedFaceSet {
coord Coordinate {
point [ 0 0 0 1 0 0 1 1 0 0 1 0 ]
}
texCoord TextureCoordinate {
point [ 0 0 1 0 1 1 0 1 ]
}
coordIndex [ 0 1 2 3 -1 ]
}
}
}
}
then
place several tree cutouts in your scene, like this:
Transform {
translation 13.4 0 55.0
children Sprite { texture "Oak.png" }
}
Transform {
translation -14.92 0 23
children Sprite { texture "Maple.png" }
}
Objects
defined like this may be much faster both to create and to display
than objects defined using a lot of polygons.
|
EXAMPLE
(click to run):
The following example illustrates typical use of the Billboard
node (see Figure 3-5). The first Billboard defines a tree by
specifying a four-component image texture that billboards about
its Y-axis. This is one of the most typical uses of Billboard.
The second Billboard node is almost identical to the first,
but billboards around its X-axis. The third Billboard node illustrates
the use of the screen-aligned billboard by setting the axisOfRotation
field to (0,0,0):
#VRML V2.0 utf8
Transform { children [
Transform {
translation 5 0 0
children DEF TREE Billboard { # Billboard about Y-axis
children DEF S Shape {
geometry IndexedFaceSet {
coord Coordinate {
point [ -2 0 0, 2 0 0, 2 5 0, -2 5 0 ]
}
texCoord TextureCoordinate {
point [ 0 0, 1 0, 1 1, 0 1 ]
}
coordIndex [ 0 1 2 3 ]
}
appearance Appearance {
texture ImageTexture { url "Tree.gif" }
}
}
}
}
Transform {
translation -6 0 -1
children Billboard { # Billboard about X-axis
axisOfRotation 1 0 0
children USE S
}
}
Transform { # Screen-aligned label for flag-pole
translation 0 3.3 0
children Billboard {
axisOfRotation 0 0 0
children Shape {
geometry Text {
string "Top of flag pole"
fontStyle FontStyle { size 0.5 }
}
appearance Appearance {
material Material { diffuseColor 0 0 0 }
}
}
}
}
Billboard { # Flagpole at origin
axisOfRotation 0 1 0
children Shape {
appearance DEF A Appearance { material Material {} }
geometry IndexedFaceSet {
coord Coordinate {
point [ -.1 0 -.1, 0 0 .1, .1 0 -.1,
-.1 3 -.1, 0 3 .1, .1 3 -.1,
.1 2.4 0, .1 2.9 0, -1.4 2.65 -.8 ]
}
coordIndex [ 0 1 4 3 -1 1 2 5 4 -1
2 0 3 5 -1 3 4 5 -1 6 7 8 ]
}
}
}
Shape { # Floor
appearance Appearance {
texture ImageTexture { url "marble.gif" }
}
geometry IndexedFaceSet {
coord Coordinate {
point [ -50 0 -50, -50 0 50, 50 0 50, 50 0 -50 ]
}
coordIndex [ 0 1 2 3 ]
}
}
DirectionalLight { direction 0 1 0 }
Viewpoint { position 0 1.5 10 }
Background { skyColor 1 1 1 }
]}
|