Post

# 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 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 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 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 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