Bezier patches for terrain

Started by
4 comments, last by DrGUI 18 years, 2 months ago
Hi all, I have recently started considering using bezier patches to render terrain and I am trying to figure out how this would work. I understand how in theory the bezier technique will interpolate between vertices giving a smooth curve rather than straight lines from one to the other, what I dont understand is how this translates into code? If I have vertices V0, V1 and V2 in my vertex buffer, how do I utilise Bezier patches to make this smoother? Do I use the technique with a tesselation factor of 0.5 to create an additional 2 vertices. Then place V0, V1, V2, V3 and V5 in a new vertex buffer and render that? Might be way off there but just trying to figure out how the implementation would work. Thanks
Advertisement
I'll push this over to GP&T as they might well be able to give you some more general help on how to implement bezier surfaces...

Quote:Original post by hoogie
I understand how in theory the bezier technique will interpolate between vertices giving a smooth curve rather than straight lines from one to the other, what I dont understand is how this translates into code?

You've almost got it. In applied 3D graphics (i.e. D3D and OpenGL) everything is still rasterized as triangles - there are always straight lines between the vertices.

The trick is in tesselation - you increase the number of triangles/vertices so that it appears to be a smooth curve. This is part of the reason why higher order surfaces can be a bit of a performance hit [wink]

Quote:Original post by hoogie
If I have vertices V0, V1 and V2 in my vertex buffer, how do I utilise Bezier patches to make this smoother?

You'll need to tesselate these - subdivide the triangle recursively until the curve looks good enough or the points start to converge on the surface defined by the bezier function.

Bezier curves, by virtue of their tesselation, are perfect for LOD algorithms provided you can also solve the continuity issues (ideally you want C2 continuity) between patches. If you create some code that will subdivide a mesh/triangles you can then feed it into the same bezier function. Thus you can lower the number of triangles with distance from the camera (for example) to try and reduce the processing overhead.

Are you going to be using vertex shaders for your implementation? I would highly recommend it - as you can offload the bezier function to the GPU. I wrote a simple bezier-quad vertex shader a while back, and I could dynamically change the shape of the bezier surface with no additional performance hit [grin]

It's also worth noting that you'll see some references to hardware-based "Higher Order Surface" functions. These are nice, but decent support for them is quite rare these days - they were cool around the time of the Radeon 8500, but shadow volumes sort of killed off the idea.

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Seems I still have the source code archive for my VShader based implementation. It's actually a cubic-patch rather than a bezier patch, but from an implementation stand point they're pretty similar.

It generates stuff like this:



hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

"The trick is in tesselation - you increase the number of triangles/vertices so that it appears to be a smooth curve."

So is the idea that you store a standard vertex buffer for the terrain set to the dimensions you want. You then call a Bezier function before rendering, this function will aplly the Bezier calculation to the standard vertex buffer and store the new smoothed terrain in its own vertex buffer which will be used for the rendering.

You could then alter the tesselation of the curves dependant on the distance from the camera, this would meen the bezier function will act as a real time LOD algorithm.

That more like it?
Quote:Original post by hoogie
So is the idea that you store a standard vertex buffer for the terrain set to the dimensions you want. You then call a Bezier function before rendering, this function will aplly the Bezier calculation to the standard vertex buffer and store the new smoothed terrain in its own vertex buffer which will be used for the rendering.

Hmm, almost - but not quite.

Lets try some ascii art [smile]

Lets assume that this is your basic terrain VB from the side. the dots are the vertices, and the dashes indicate the straight lines between them:

•------•------•------•------•


Increasing the tesselation would subdivide each of those straight lines by a number of times:

•--*--*--•--*--*--•--*--*--•--*--*--•


In the above example, each edge is split into 3 new ones. Now that the straight lines are shorter it's easier to fool the viewer into thinking they are actually a curve.

Thats the first step - increasing the tesslelation. The next, seperate, step is to apply a bezier function to each/every vertex. More vertices will be slower to compute but look smoother.

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

'"Higher Order Surface" functions.'
N-patches I think they were called. But why did they go and how did shadow volumes kill them? Why I say, why?

This topic is closed to new replies.

Advertisement