vbo update from heightmap

Started by
12 comments, last by sprite_hound 16 years ago
Ok well this is the 'raw' glsl vertex shader that I used for transforming the vertex of a sphere so it won't immediately fit your needs:
varying vec3 lightDir,normal;uniform float time;uniform sampler2D myTexture;void main(){	gl_TexCoord[0] = gl_MultiTexCoord0;		lightDir = normalize(vec3(gl_LightSource[0].position));	normal = gl_NormalMatrix * gl_Normal;	vec4 color = texture2D(myTexture, vec2(gl_TexCoord[0]));	vec3 pos = gl_Vertex + (gl_Normal * color.z);	vec4 pos4 = vec4(pos.x, pos.y, pos.z, 1.0);	gl_Position = vec4(gl_ModelViewProjectionMatrix * pos4);} 


In this version I've cut down a bit and removed everything except the vertex modification.
uniform sampler2D myTexture;void main(){	// getting the texture coords for the sampler	gl_TexCoord[0] = gl_MultiTexCoord0;	// In this case my source image "heightmap" is RGBA -	// - and height is only 8-bits in the alpha channel.	// This is a bit rubbish but yours could be a full float format.	vec4 heightColour = texture2D(myTexture, gl_TexCoord[0].st);	// up is the direction we want to move the vertex, this was called	// "normal" in the version above.	const vec3 up = vec3(0.0, 1.0, 0.0);	// now we modify the position of the gl_Vertex	// this last section is a bit messy and could be improved, a lot!!!	vec3 pos = gl_Vertex + (up * heightColour.a);	vec4 pos4 = vec4(pos.x, pos.y, pos.z, 1.0);	gl_Position = vec4(gl_ModelViewProjectionMatrix * pos4);} 


There nothing too it.

All I'm really doing is writing the height value into a texture, and then sampling it in the vertex shader. I use it to scale a vector called "normal" in the original shader, or "up" in the second listing. This gives me a scaled vector that I can add to the gl_Vertex that we're currently dealing with and set the gl_Position using it.

As you can see from the comments I've added the version I've given you is not an ideal situation. For a start I'm only using 8-bits of the 32-bit format from my texture. I don't need the extra precision so I save one texture channel but you will probably want to use a floating point texture format, or encode your height into the full texture.

You'll want to add a pre-generated normal map to the above and write your own fragment shader but this should get you started. It only took me a few of hours to learn how to do this the first time and if you can write a fft water simulation I'm sure you're up to it!

Andy

"Ars longa, vita brevis, occasio praeceps, experimentum periculosum, iudicium difficile"

"Life is short, [the] craft long, opportunity fleeting, experiment treacherous, judgement difficult."

Advertisement
Quote:Original post by sprite_hound
@MARS_999: Enh... I suspect I'm just being dense. If I use GL_TRIANGLES with the indices set up like a strip then I get a nice pattern of disconnected triangles facing forwards and backwards.


Chances are you setup your index data wrong then.

Given a set of vertices in triangle strip order {(0,0), (0, 1), (1,0), (1,1)} two triangles can be draw using the following index setup { 0,1,2,2,1,3 }.

This is a triangle list in strip order with indices.

The advntage of this is there is no need for connecting strips of triangles between sections, you can simply start a new triangle wherever you need to. The strip access pattern allows you to make use of the post-T&L cache and all it cost are indices, which are often a small over head (16bit per index).
@NineYearCycle: Ah. Cool. Yeah, that's far simpler than I was imagining it to be.

I wonder how that compares speed-wise. I'll stick something together to test it.

@Phantom: Thanks. I'll fiddle with my indices.
Well, I changed the indices, and tried out using textures for the height and normal data.

No noticeable change in performance (though this is fine, 'cos it's fast enough for now).

I think I'm gonna stick with the vertex attributes for no particularly good reason.

This topic is closed to new replies.

Advertisement