CT336/CT404Graphics & Image Processing
Section 4:
More on 3D Geometry
Visibility Algorithms
X3D - Points, Lines, Faces, Elevation Grids, Extrusion
Visibility Algs – Backface Culling, Visibility Culling,
Painter’s Algorithm, Z Buffer Algorithm, BSP Trees
More Geometry in X3D
Points, Lines and Faces
Elevation Grids
Extrusion
Points, Lines and Faces
An X3D point is a dot located in 3D space. Using sets of points in a PointSet node, you can draw scatters of points.
An X3D line is a straight line connecting two points in 3D space. Using sets of lines in an IndexedLineSet node, arbitrary polygons/ polylines can be drawn.
An X3D face is a flat polygonal surface, whose vertices are specified as a series of points. Using sets of faces in an IndexedFaceSet node, arbitrary faceted 3D objects can be built.
PointSet, IndexedLineSet, and IndexedFaceSet are all node types that are used as geometry of a Shape node
The PointSet Node
<PointSet>
<Coordinate point = '1 1 1,
2 2 2' />
</PointSet>
The point field in the Coordinate node is a list of 3D points
Commas are ignored (and therefore useful to separate the triples of numbers)
Example: PointSet
<Scene DEF='scene'>
<Shape>
<Appearance>
<Material emissiveColor='1 1 1'/>
</Appearance>
<PointSet>
<Coordinate point='-1 1 1, 1 1 1, 1 1 –1, -1 1 –1, -1 -1 1,
1 -1 1, 1 -1 –1, -1 -1 -1'/>
</PointSet>
</Shape>
</Scene>
The IndexedLineSet Node
This node also uses a Coordinate node to specify its points
These co-ordinates are linked together into a polyline
through the coordIndex field: this specifies the order in
which the 3D points are linked
To end a polyline before starting another, use the special
index number -1
Example: IndexedLineSet
<Scene DEF='scene'>
<Shape>
<Appearance>
<Material emissiveColor='1 1 1'/>
</Appearance>
<!-- The coordIndex rows are: top, bottom, vertical edges -->
<IndexedLineSet coordIndex = '0, 1, 2, 3, 0, -1,
4, 5, 6, 7, 4, -1 0, 4, -1,
1, 5, -1, 2, 6, -1,
3, 7 '>
<!-- The 1st 4 coords are the top of the cube, the 2nd 4 are the bottom -->
<Coordinate point = '-1 1 1, 1 1 1, 1 1 -1, -1 1 -1, -
1 -1 1, 1 -1 1, 1 -1 -1, -1 -1 -1' />
</IndexedLineSet>
</Shape>
</Scene>
The IndexedFaceSet Node
Very similar to the IndexedLineSet node (with a
few extra fields): the main difference is that the
last point of a polyline is automatically joined to
the first, and the resulting face is filled in.
ccw: TRUE if vertices are listed
counterclockwise (defines which is the front of a
face)
solid: TRUE if the shape is solid, and therefore
the browser can skip drawing the back of each
face
convex: FALSE if one or more faces are
concave: X3D renderer will split them into
multiple convex faces (required for fast
rendering)
creaseAngle defines the threshold angle between
adjacent faces, below which they are considered
part of the same face and they will be smoothly
shaded together.
Example: IndexedFaceSet
<Scene DEF='scene'>
<Shape>
<Appearance>
<Material diffuseColor='1 1 0'/>
</Appearance>
<!-- The coordIndex rows are: front, back, sides -->
<IndexedFaceSet coordIndex= '0, 1, 2, 3, 4, 5, 6, -1,
0, 12, 11, 10, 9, 8, 7, -1,
0, 7, 1, -1,
1, 7, 8, 2, -1,
2, 8, 9, 3, -1,
3, 9, 10, 4, -1,
4, 10, 11, 5, -1,
5, 11, 12, 6, -1,
6, 12, 0, -1'
convex = 'false' >
<!-- 1st block of point coordinates: lighting bolt tip
2nd block: front perimeter 3rd block: back perimeter -->
<Coordinate point= ' 0.0 0.0 0.0,
5.5 5.0 0.88, 4.0 5.5 0.968, 7.0 8.0 1.408, 4.0 9.0 1.584,
1.0 5.0 0.88, 2.5 4.5 0.792,
5.5 5.0 -0.88, 4.0 5.5 -0.968, 7.0 8.0 -1.408, 4.0 9.0 -1.584,
1.0 5.0 -0.88, 2.5 4.5 -0.792 ' />
</IndexedFaceSet>
</Shape>
</Scene>
The ElevationGrid Node
Elevation Grids are used to build 3D surfaces, such as
terrains, using a grid of height (y) values, which will be
evenly spaced out in the x and z directions
Polygons are generated automatically
Used as the geometry for a Shape node
< ElevationGrid
xDimension = ' '
xSpacing = ' '
zDimension = ' '
zSpacing = ' '
height = ' '
creaseAngle = ' '
/>
Example: ElevationGrid
<Scene DEF='scene'>
<Shape>
<Appearance>
<Material/>
</Appearance>
<ElevationGrid
height=' 0 0 0.5 1 0.5 0 0 0 0
0 0 0 0 2.5 0.5 0 0 0
0 0 0.5 0.5 3 1 0.5 0 1
0 0 0.5 2 4.5 2.5 1 1.5 0.5
1 2.5 3 4.5 5.5 3.5 3 1 0
0.5 2 2 2.5 3.5 4 2 0.5 0
0 0 0.5 1.5 1 2 3 1.5 0
0 0 0 0 0 0 2 1.5 0.5
0 0 0 0 0 0 0.5 0 0 '
creaseAngle='0.785'
xDimension='9'
zDimension='9' />
</Shape>
</Scene>
The Extrusion Node
Extrusion is a flexible way of defining 3D objects
The analogy is with extrusion in manufacturing industry, by which a stream of raw material is forced through a hole in a plate. A long strand of material is produced, whose cross section is defined by the shape of the hole in the plate.
Examples: aluminium mouldings, sausages...
The Extrusion node, used as the geometry for a Shape node:
the 2D (x/z) cross section
the 3D curve or spine along which the shape is swept. As the cross section sweeps along the spine, it leaves behind a group of faces that create the skin of the extruded shape
the scale of the cross section at points along the spine
the orientation of the cross section at points along the spine
The Extrusion Node
beginCap and endCap define whether the shape has 'caps' on its ends, (alternatively, it will be hollow - like a box with the lid off).
< Extrusion
crossSection = ' '
spine = ' '
scale = ' '
orientation = ' '
beginCap = ' '
endCap = ' '
creaseAngle = ' '
/>
Extrusion Example
<Scene DEF='scene'>
<Group>
<Shape>
<Appearance>
<Material diffuseColor='1 0.9 0.7'/>
</Appearance>
<Extrusion convex='FALSE'
crossSection='-0.5 1, -0.5 0.8, -1.8 0.8,
-1.8 -0.8, 1.8 -0.8, 1.8 0.8, 0.5 0.8,
0.5 1, 2 1, 2 –1, -2 –1, -2 1, -0.5 1'
spine='0 0 0, 0 2 0' />
</Shape>
</Group>
</Scene>
1: (-0.5, 1.0) 2: (-0.5, 0.8)3: (-1.8, 0.8)
4: (-1.8, -0.8)
Extrusion Example: Precomputed Complex Spine
<Shape>
<Appearance>
<Material diffuseColor='0 1 0.7'/>
</Appearance>
<!-- cross section is a half-circle -->
<!-- spine is a helix -->
<Extrusion
creaseAngle = '1.57'
endCap = 'FALSE'
beginCap = 'FALSE'
solid = 'FALSE' crossSection = '
-1.00 0.00, -0.92 -0.38, -0.71 -
0.71, -0.38 -0.92, 0.00 -1.00, 0.38 -0.92,
0.71 -0.71, 0.92 -0.38, 1.00
0.00 '
spine = ' 2.00 0.00 -0.00, 1.85 0.12 -0.77,
1.41 0.24 -1.41, 0.77 0.36 -1.85,
0.00 0.48 -2.00, -0.77 0.61 -1.85,
-1.41 0.73 -1.41, -1.85 0.85 -0.77,
-2.00 0.97 0.00, -1.85 1.09 0.77,
-1.41 1.21 1.41, -0.77 1.33 1.85,
0.00 1.45 2.00, 0.77 1.58 1.85,
1.41 1.70 1.41, 1.85 1.82 0.77,
2.00 1.94 0.00, 1.85 2.06 -0.77,
1.41 2.18 -1.41, 0.77 2.30 -1.85,
0.00 2.42 -2.00, -0.77 2.55 -1.85,
-1.41 2.67 -1.41, -1.85 2.79 -0.77,
-2.00 2.91 0.00, -1.85 3.03 0.77,
-1.41 3.15 1.41, -0.77 3.27 1.85,
0.00 3.39 2.00, 0.77 3.52 1.85,
1.41 3.64 1.41, 1.85 3.76 0.77,
2.00 3.88 0.00 '
/>
</Shape>
See next slide for Excel calculations of spine points
Generating the helical spine points in Excel
Calculations:
B2: =A2*PI()/180
C2: =2*COS(B2)
D2: =0.12*A2
E2: =-2*SIN(B2)
Exporting:
Select C2:E34
Copy
Move to new sheet
Paste Special: Values
Save As: *.csv
Extrusion Example: Scaling the Cross Section
<Scene DEF='scene'>
<Shape>
<Appearance>
<Material diffuseColor='1 0.8 0'/>
</Appearance>
<Extrusion endCap='false' solid='false' creaseAngle='1.57'
crossSection='1 0, 0.92 -0.38, 0.71 -0.71, 0.38 -0.92, 0 –1, -0.38
-0.92, -0.71 -0.71, -0.92 -0.38, -1 –0, -0.92 0.38, -0.71 0.71, -0.38 0.92,
0 1, 0.38 0.92, 0.71 0.71, 0.92 0.38, 1 0 '
scale='1.8 1.8, 1.95 1.95, 2 2, 1.95 1.95, 1.8 1.8, 1.5 1.5, 1.2 1.2,
1.05 1.05, 1 1, 1.05 1.05, 1.15 1.15'
spine='0 0 0, 0 0.4 0, 0 0.8 0, 0 1.2 0, 0 1.6 0, 0 2 0, 0 2.4 0,
0 2.8 0, 0 3.2 0, 0 3.6 0, 0 4 0'/>
</Shape>
</Scene>
vase.x3d
Extrusion Example: Rotating the Cross Section
<Scene DEF='scene'>
<Shape>
<Appearance>
<Material diffuseColor='1 0.5 0'/>
</Appearance>
<Extrusion
creaseAngle='0.785'
crossSection='-1 1 1 1 1 -1 -1 -1 -1 1'
orientation='0 1 0 0, 0 1 0 0.175, 0 1 0 0.349, 0 1 0 0.524,
0 1 0 0.698, 0 1 0 0.873, 0 1 0 1.047, 0 1 0 1.222, 0 1 0 1.396'
spine='0 0 0, 0 0.5 0, 0 1 0, 0 1.5 0, 0 2 0, 0 2.5 0, 0 3 0, 0 3.5 0,
0 4 0'/>
</Shape>
</Scene>
Cameras in 3D graphics APIs
E.g. OpenGL cameras allow you to define:
Camera location (x, y, z)
Camera facing/orientation (x rotation, y rotation,
z rotation)
Viewing Frustum
=Field of View (FOV)
+ clipping planes
FOV
Hidden Surface Removal
Removing lines or surfaces not visible to the viewer
May operate in:
object space (accurate, applied before vertices are mapped to pixels), or
image space (often faster but less accurate, applied at the level of the discrete pixel)
Common Approaches:
Back-face culling
Visibility culling
Visibility frustum
Bounding box/occlusion/portal culling
Painter’s Algorithm
Z Buffer Algorithm
Binary Space Partitioning
Surface Normals
Vectors perpendicular to a surface
Back-face Culling
Simple, fast object space technique
Limited to convex objects
May be used prior to other better (but slower) techniques
Operates by comparing the orientation (normal) of complete polygons with the view point or centre of projection (camera), and removing those that are facing “backwards” (normal facing away from camera)
Mathematically, we calculate the dot product of the surface normal and the camera orientation vector (many 3D graphics APIs will provide a dot product function)
In X3D: define objects with solid field set to TRUE
Visibility Culling
Typically operating in object space
Visibility Frustum
Render only those polygons that fall within the clipping region
Bounding Box culling
Enclose groups of objects inside bounding boxes
At render-time, check first bounding-box visibility and occlusion
E.g. Transform and Group nodes in X3D
Part of a multi-stage, coarse-to-fine process..
Portal culling:
Best for indoor scenes (for outdoor, detail culling and back-clipping
plane culling are more important)
Divide the scene into sectors, with adjacent sectors linked by plane
segments called ‘portals’ (doorways being an obvious example)
Any view between sectors which doesn’t pass through a portal is
assumed to be occluded
http://www.3dkingdoms.com/weekly/weekly.php?a=26
(bounding volume)
camera
Priority Fill/ Painter’s Algorithm
Object space technique
Calculates an ordered list of objects, allowing those further
away to be rendered first
The typical way of sorting faces is to use their average
distance from the camera
Cannot work with a pipeline renderer: polygons are
generated and sent down pipeline in an arbitrary order by the
application program
Problem:
“cyclic overlap”
Canvas Perspective Projection example expanded
This is the perspective projection demo from earlier, but with
filled polygons and priority fill, (no backface culling or
meaningful shading.. yet..)
[See separate document]
Z Buffer Algorithm
Image space technique
Uses a Z (depth) array of same pixel dimensions as graphics window, which is computed in parallel to the image bitmap itself
Each value in the Z buffer represents the depth of the pixel at that point
Each pixel is only drawn into the bitmap if it is closer than the current Z buffer value at that point
As each pixel is drawn, the Z buffer is updated
Often implemented at hardware level and automatically applied in many graphics APIs
Since it’s an image space technique, z buffers are often applied *after* the culling techniques discussed earlier (backface, portal, etc.).. it’s a multi-stage process
Binary Space Partitioning (BSP) Tree Algorithm
Good for drawing 3D scenes where the positions of objects are fixed and the user's viewing coordinate changes; good for indoor scenes (the game ‘Doom’ being a classic example)
Pre-computed
BSP trees insert all objects into a binary tree, and each object partitions (or splits) space, breaking down what is on the left and what is on the right of each object
They allow, for any viewpoint, the extraction of the correct depth-ordering of objects, for rendering
Unlike the painter’s algorithm, errors do not happen when an object cuts through another. When BSP trees are built, objects are split into sections to avoid this.
Constructing BSP Trees
1: A simple scene
involving 8 polygons
2: The front and back
lists with E as head node
3: The final tree and the split planes used to
partition the polygon lists
Runtime Use of BSP Trees
Is the viewer looking at the front or back of
node E?
Looking at E’s front => consider
everything behind E first (i.e. right branch)
The first node we find is D: are we looking at
its front or back?
Looking at D’s back => consider
everything in front of D
Moving to A, we’re looking at its front so
now move to it’s back child B. Viewing location
And direction B is a leaf so we draw it and return to A.
A has no front child so we draw A and return to D.
We draw D and then consider its back child C
We’re looking at C’s back so we need to draw everything in front of it first
No nodes are in front of C so we draw C and proceed to (and draw) F.
We then return all the way back to E: we draw it, then process its left branch.
We’re looking at the back of G so need to draw all nodes in front of it (there are none)
So we draw G, and move to H which is our last polygon to draw.
So the complete drawing order is: BADCFEGH
The Utah Teapot..
http://en.wikipedia.org/wiki/Utah_teapot
a 3D computer model built in 1975 as part of
pioneering graphics research, which has become a
standard reference object (and something of an in-joke)
in the computer graphics community.
A teapot primitive is considered the equivalent of a
"hello world" program
Currently on display at the
Computer History Museum in
Mountain View, California
teapot.x3d