Controlling Shading on Coordinate-Based Geometry
Motivation
- When shaded, the faces on a shape are obvious
- To create a smooth shape you can use a large number of small faces
- Requires lots of faces, disk space, memory, and drawing time
- Instead, use smooth shading to create the illusion of a smooth shape, but with a small number of faces
Controlling shading using the crease angle
By default, faces are drawn with faceted shading.
You can enable smooth shading using the creaseAngle field for:
Selecting crease angles
A crease angle is a threshold angle between two faces:
- If face angle >= crease angle, use facet shading
- If face angle < crease angle, use smooth shading
Using normals
A normal vector indicates the direction a face is facing
- If it faces a light, the face is shaded bright
By default, normals are automatically generated by the X3D browser:
- You can specify your own normals with a Normal node
- Usually automatically generated normals are good enough
Syntax: Normal
A Normal node contains a list of normal vectors that override use of a crease angle.
XML Encoding
1
2
<Normal
vector='0.0 1.0 0.0, ...'/>
Classic VRML Encoding
1
2
3
Normal {
vector [ 0.0 1.0 0.0, ... ]
}
Normals can be given for IndexedFaceSet and ElevationGrid nodes.
Syntax: IndexedFaceSet
An IndexedFaceSet geometry node creates geometry out of faces:
- normal - list of normals
- normalIndex - selects normals from list
- normalPerVertex - control normal binding
XML Encoding
1
2
3
4
5
6
7
8
9
10
<Shape>
<Appearance><!-- ... --><Appearance>
<IndexedFaceSet
normalPerVertex='true'
normalIndex='...'
coordIndex='...'>
<Normal ... />
<Coordinate ... />
</IndexedFaceSet>
</Shape>
Classic VRML Encoding
1
2
3
4
5
6
7
8
9
10
Shape {
appearance Appearance { ... }
geometry IndexedFaceSet {
normalPerVertex TRUE
normalIndex [ ... ]
coordIndex [ ... ]
normal Normal { ... }
coord Coordinate { ... }
}
}
Controlling normal binding for face sets
The normalPerVertex field controls how normal indexes are used
- FALSE: one normal index to each face (ending at -1 coordinate indexes)
- TRUE: one normal index to each coordinate index of each face (including -1 coordinate indexes)
Syntax: ElevationGrid
An ElevationGrid geometry node creates terrains:
- normal - list of normals
- normalPerVertex - control normal binding
- Always binds one normal to each grid point or square, in order
XML Encoding
1
2
3
4
5
6
7
8
<Shape>
<Appearance><!-- ... --><Appearance>
<ElevationGrid
normalPerVertex='true'
height='...'>
<Normal ... />
</ElevationGrid>
</Shape>
Classic VRML Encoding
1
2
3
4
5
6
7
8
Shape {
appearance Appearance { ... }
geometry ElevationGrid {
normalPerVertex TRUE
normal Normal { ... }
height [ ... ]
}
}
Controlling normal binding for elevation grids
The normalPerVertex field controls how normal indexes are used (similar to face sets):
- FALSE: one normal to each grid square
- TRUE: one normal to each height for each grid square
Syntax: NormalInterpolator
A NormalInterpolator node describes a normal set:
- keys - key fractions
- keyValues - key normal lists (X,Y,Z lists)
- Interpolates lists of normals, similar to the CoordinateInterpolator
XML Encoding
1
2
3
<NormalInterpolator
key='0.0, ...'
keyValue='0.0 1.0 1.0, ...'/>
Classic VRML Encoding
1
2
3
4
NormalInterpolator {
key [ 0.0, ... ]
keyValue [ 0.0 1.0 1.0, ... ]
}
Typically route into a Normal node’s set_vector input.
Summary
- The creaseAngle field controls faceted or smooth shading
- The Normal node lists normal vectors to use for parts of a shape
- Used as the value of the normal field
- Normal indexes select normals to use
- Normals override creaseAngle value
- The normalPerVertex field selects normal per face/grid square or normal per coordinate
- The NormalInterpolator node converts times to normals