You are on page 1of 11

Tessellating and Rendering Bezier/B-Spline/NURBS Curves and

Surfaces using Geometry Shader in GPU

CIS 665 PROJECT FINAL REPORT

5/2/07

Dongsoo Han
University of Pennsylvania

PROJECT ABSTRACT

NURBS(Non Uniform Rational B-Splines) are nearly ubiquitous for computer-aided design (CAD),
manufacturing (CAM), and 3D modelers and part of numerous industry wide 3D data exchange standards
such as IGES and STEP. With a rapidly growing hardware system, NURBS is getting more attentions in
real-time systems or 3D games. In this new trend, the biggest obstacle is that tessellating NURBS into
triangles is still slower than loading pre-triangulated data.

However NURBS can give lots of freedom to 3D application developers such as unlimited control over
LOD (Level of Detail) or high rendering quality to the curved surface.

In this project, geometry shader is used to tessellate and render curves and surfaces. The benefits of
using geometry shader are to reduce the rendering data transferring from CPU to GPU as well as
tessellate and render curves and surfaces as a parallel process.

1. INTROUDUCTION

1.1. Technology
A geometry shader can generate new primitives from existing primitives like pixels, lines and triangles. It
is executed after vertex shader and its input is the whole primitive or primitive with adjacency information.
Then it can emit zero or more primitives, which are rasterized and their fragments passed to fragment
shader.

With the input of control vertices and other information such as number of input control vertices, geometry
shader can generate line or triangle primitives to render Bezier, B-Spline or NURBS curves and surfaces.

1.2. Target Platforms


1.2.1 Hardware
1. Video card: NVidia GeForce 8800 GTX
2. Hardware Platform: x86 – Intel or AMD
3. Hard disk: approximately 10 MB

1.2.2 Software
1. Operating System: Window XP
2. Programming Tool: Visual Studio 2005 Professional

1
3. Programming Language: C/C++, Cg 2.0 (beta)
4. Major Programming Library: MFC (User Interface), Win32 API, OpenGL/GLU
5. 3rd Party Programming Library: N/A

2. PROJECT DEVELOPMENT

2.1. Technical Background

2.1.1 What is Bezier curve


Bezier curve is a weighted average of control points (vertices). These weights are Bernstein
polynomials and also called blending function.

Equation 1

where the polynomials

Equation 2

Degree three Bezier curve is most common and can be represented as below. It is usually called
Cubic Bezier curve.

Equation 3

Below is matrix form.

2
⎡ −1 3 −3 1 ⎤ ⎡t 3 ⎤
⎡ p0 x p3 x ⎤ ⎢ ⎢ ⎥
0 ⎥⎥ ⎢t 2 ⎥
p1x p2 x
⎢ 3 −6 3
B(t ) = ⎢ p0 y p1 y p2 y p3 y ⎥⎥ ⎢
⎢ −3 3 0 0⎥ ⎢ t ⎥
⎣⎢ p0 z p1z p2 z p3 z ⎦⎥ ⎢ ⎥⎢ ⎥
⎣1 0 0 0⎦ ⎣ 1 ⎦

B(t ) = G Bez B Bez T

Equation 4

In this project matrix form was used since we can take advantage of matrix vector multiplication
inside GPU. Below is the screenshot that shows Bezier curve generated by geometry shader.

Figure 1

2.1.2 What is B-Spline curve

B-Spline curve is a set of piecewise polynomial curves represented as below.

n
X (t ) = ∑P B
k =0
k k ,d (t )

Equation 5

3
⎧1 tk ≤ t ≤ tk +1
Bk ,1 ( t ) = ⎨
⎩0 otherwise

⎛ t − tk ⎞ ⎛ tk +d − t ⎞
Bk ,d ( t ) = ⎜ ⎟ Bk ,d −1 ( t ) + ⎜ ⎟ Bk +1,d −1 ( t )
⎝ tk + d −1 − tk ⎠ ⎝ tk + d − tk +1 ⎠

Equation 6

Particularly, degree three uniform B-Spline curve can be represented as matrix form as below.

⎡ −1 3 −3 1⎤ ⎡t 3 ⎤
⎢ ⎥⎢ ⎥
1 3 −6 0 4 ⎥ ⎢t 2 ⎥
x (t ) = ⎡P0 P1 P2 P3 ⎤⎦ ⎢
6⎣ ⎢ −3 3 3 1⎥ ⎢ t ⎥
⎢ ⎥⎢ ⎥
⎣1 0 0 0 ⎦ ⎢⎣ 1 ⎥⎦

Equation 7

In this project, matrix form was used to tessellate and render unform B-Spline curves and
surfaces in geometry shader.

Figure 2

4
2.1.3 What is NURBS curve

NURBS stands for Non Uniform Rational B-Splines. NURBS curve can be evaluated using Cox-
de Boor algorithm (Equation 6). With weights associated to each control point, conic sections can
be created.

2.1.4 What is NURBS surface

Equation 8

2.2. Implementation Details

CPU GPU

Input (uniform Output (Geometry


textures, parameters) Shader)
● Control Line or Triangle
Vertices(Points) primitives
● Number of CV
● LOD value

Figure 3

5
Figure 3 explains that control vertices (points) are transferred to GPU (geometry shader) along with other
uniform information such as number of cv or LOD(Level of Detail) value. The output of geometry shader is
either lines or triangles corresponding to curves and surfaces.

The nice thing of geometry shader is that it can control LOD automatically based on the distance between
camera (eye) position to the object (curve or surface). Figure 5 is B-Spline surface geometry shader
program. In Figure 6, 7 and 8, red surface is tessellated by CPU and triangle list is transferred to GPU.
On the other hand yellow surface is done by GPU. Figure 6, 7 and 8 shows different LODs which are
automatically done by geometry shader.

Figure 4

There are two projects in visual studio 2005. To compare implementation in CPU vs. GPU, Brep project
contains curve and surface CPU implementations. Cg folder in GLModeler project contains geometry
shader codes. GLModeler project also contains user interface and interaction implementations.

LINE_ADJ
TRIANGLE_OUT
void bspline_surface_txtr_gp(
AttribArray<float4> pos : POSITION,
AttribArray<float4> color : COLOR0,
uniform float4x4 modelViewProj : state.matrix.mvp,
uniform float4x4 inverseMVP :
state.matrix.mvp.inverse,
uniform int segments = 10,

uniform int numOfUCV = 8,


uniform int numOfVCV = 5,

uniform samplerRECT dataX,


uniform samplerRECT dataY,
uniform samplerRECT dataZ
)
{

6
float4 newPt = mul(inverseMVP, pos[0]);
int v = round(newPt.x);

float4 cv[4];
float4 cv1[4];
float step = 1;

// dynamic LOD based on the view distance


float3 pt;
pt.x = texRECT(dataX, float2(0, v)).r;
pt.y = texRECT(dataY, float2(0, v)).r;
pt.z = texRECT(dataZ, float2(0, v)).r;

float3 eyepos = (mul(inverseMVP, float4(0, 0, 0, 1))).xyz;

float dist = distance(eyepos, pt);


segments = ( 60 / dist );

if ( segments < 2 )
segments = 2;
else if ( segments > 13 )
segments = 13;

for ( int i = 0; i < numOfUCV - 3; i++ )


{
cv[0].x = texRECT(dataX, float2(i, v)).r;
cv[0].y = texRECT(dataY, float2(i, v)).r;
cv[0].z = texRECT(dataZ, float2(i, v)).r;

cv[1].x = texRECT(dataX, float2(i + 1, v)).r;


cv[1].y = texRECT(dataY, float2(i + 1, v)).r;
cv[1].z = texRECT(dataZ, float2(i + 1, v)).r;

cv[2].x = texRECT(dataX, float2(i + 2, v)).r;


cv[2].y = texRECT(dataY, float2(i + 2, v)).r;
cv[2].z = texRECT(dataZ, float2(i + 2, v)).r;

cv[3].x = texRECT(dataX, float2(i + 3, v)).r;


cv[3].y = texRECT(dataY, float2(i + 3, v)).r;
cv[3].z = texRECT(dataZ, float2(i + 3, v)).r;

cv1[0].x = texRECT(dataX, float2(i, v + step)).r;


cv1[0].y = texRECT(dataY, float2(i, v + step)).r;

cv1[0].z = texRECT(dataZ, float2(i, v + step)).r;

cv1[1].x = texRECT(dataX, float2(i + 1, v + step)).r;


cv1[1].y = texRECT(dataY, float2(i + 1, v + step)).r;
cv1[1].z = texRECT(dataZ, float2(i + 1, v + step)).r;

cv1[2].x = texRECT(dataX, float2(i + 2, v + step)).r;


cv1[2].y = texRECT(dataY, float2(i + 2, v + step)).r;
cv1[2].z = texRECT(dataZ, float2(i + 2, v + step)).r;

cv1[3].x = texRECT(dataX, float2(i + 3, v + step)).r;


cv1[3].y = texRECT(dataY, float2(i + 3, v + step)).r;
cv1[3].z = texRECT(dataZ, float2(i + 3, v + step)).r;

for( int j = 0; j < segments; j++ )


{
float t = j / (float) (segments-1);
float4 tvec = float4(1, t, t*t, t*t*t);

7
float4 b = mul(bSplineBasis, tvec);
float4 p = cv[0]*b.x + cv[1]*b.y + cv[2]*b.z + cv[3]*b.w;
float4 p1 = cv1[0]*b.x + cv1[1]*b.y + cv1[2]*b.z + cv1[3]*b.w;

emitVertexTransform(p, color[0], modelViewProj);


emitVertexTransform(p1, color[0], modelViewProj);
}
}
}

Figure 5

To render a full surface, each geometry shader renders only one strip. If there are mutiple strips to
tessellate and render, geometry shaders work as a parallel process and it can achieve a big performance
increase.

Figure 6

8
Figure 7

Figure 8

9
3. Conclusion

Using geometry shader to tessellate and render Bezier/B-Spline/Nurbs curves and surfaces has three
benifits:

1. The volume of transferring data to GPU is much less than using triangles. Also it is independent to the
LOD (Level of Detail). Therefore without suffering from limited bandwidth, high quality curves and
surfaces can be displayed.

2. Tessellation and rendering can be processed in parallel way.


3. LOD can be achieved easily and doesn’t cause any overload to CPU. Also adaptive tessellation can be
also achieved along with LOD.

The limitation of geometry shader:


1. The number of emit primitives are limited.
-> We can overcome this by subdividing input curves or surfaces.

2. The size of geometry shader and loop iteration are limited.


-> Sensitive coding and tuning are necessary.

4. REFERENCES

David F. Rogers 2001


An Introduction to NURBS with Historical Perspective

Gerald Farin 2002


CURVES AND SURFACES FOR CAGD A Practical Guide Fifth Edition

Les Piegl and Wayne Tiller 1996


The NURBS Book 2nd Edition

Georg Glaeser and Hellmuth Stachel 1998


Open Geometry OpenGL + Advanced Geometry

SAMUEL R. BUSS
University of California, San Diego
3-D Computer Graphics A Mathematical Introduction with OpenGL

Michael Guthe, Akos Balazs, Reinhard Klein


GPU-based trimming and tessellation of NURBS and T-Spline surfaces
http://cg.cs.uni-bonn.de/docs/publications/2005/guthe-2005-gpu-based.pdf

Hans-Friedrich Pabst, Jan P. Springer, Andr´e Schollmeyer, Robert Lenhardt, Christian Lessig, Bernd
Fr¨ohlich
http://www.sci.utah.edu/~wald/RT06/papers/hanspabst.pdf

Efficient Rendering of Trimmed NURBS


Subodh Kumar & Dinesh Manocha
Department of Computer Science
University of North Carolina
Efficient Rendering of Trimmed NURBS Surfaces

10
Thomas W. Sederberg
An Introduction to B-Spline Curves

Brian A. Barsky
Berkeley Computer Graphics Laboratory
A STUDY OF PARAMETRIC UNIFORM B-SPLINE CURVE AND SURFACE REPRESENTATIONS

Christopher K. Ingram
University of Waterloo
A Geometric B-Spline Over the Triangular Domain

Center for Visual Information Technology


Sample Geometry Shader
http://cvit.iiit.ac.in/index.php?page=resources

SIGGRAPH 2005 Course 37 Notes GPU Shading and Rendering


http://www.csee.umbc.edu/~olano/s2005c37/

Ronen Barzel
University of California, San Diego
Introduction to Computer Graphics Lecture Notes
http://graphics.ucsd.edu/courses/cse167_w06/

Jared Hoberock
Geometry Shader Hello World
https://agora.cs.uiuc.edu/display/graphics/Geometry+Shader+Hello+World

Denis Zorin
Computer Graphics Lecture Notes
http://mrl.nyu.edu/~dzorin/geom04/

NVidia
GeForce 8800 OpenGL Extensions

5. CREDITES

Some images are from Wikipedia(http://en.wikipedia.org/wiki/Wiki).

11

You might also like