Sign in to follow this  
Unseen Machine

Calculating normals for terrain?

Recommended Posts

Hi,

I am sure it been answered before, and I have Googled a bit. The results of the google are I reckon i need to learn how to do per-vertex shading (might be worng though), i have no idea how it is implemented when using GL_TRIANGLE_STRIP and i can't find a decent demo. Here's a picture of how my terrain looks [url="http://dl.dropbox.com/u/8822351/GDK_GL_01.PNG"]GL_Terrain[/url] , as you can see, something is not quite right!:D

The code is written in QB64 (a modern QBasic) using SFML to create the GL windows (via a C++ wrapper), i am happy to post it but it's quite large and requires a whole myriad of files, libs and QB64 to run it.

Any ideas, links, etc on how to do per vertex shading would be great.

Many thanks,

John

Share this post


Link to post
Share on other sites
How are you getting the height for the terrain? You look at the height to the right/left (call it the x axis) of a point and use that to create a vector (from left to right). You then look to the front/back (call it z axis) and use that to create another vector. Normalize those vectors. You now have a tangent and a binormal. Cross product those and you have a normal. It can be optimized quite well.

This link may help : http://www.flipcode.com/archives/Calculating_Vertex_Normals_for_Height_Maps.shtml I didn't like how It went straight to the optimized version though. I think you'll be better off working out the tangent/binormal yourself and doing it that way. you can optimize it later (using the fact that the cross product will have a few 0s in it).

Share this post


Link to post
Share on other sites
what does the underside look like? it seems to me that one normal is pointing up and the other is pointing down for each patch you render

Share this post


Link to post
Share on other sites
Thanks for the responses,

[quote]How are you getting the height for the terrain? [/quote]

The y values relate to the greyscale value of the pixel the terrain is taken from. 0 (black) = no height, 255 = heightest point, i have yet to implement a y scale option.

[quote]This link may help : [url="http://www.flipcode.com/archives/Calculating_Vertex_Normals_for_Height_Maps.shtml"][color="#284b72"]http://www.flipcode....ight_Maps.shtml[/color][/url] I didn't like how It went straight to the optimized version though[/quote]

It seems to be just what i might need, but my C/C++ is weak at best and theres code there i dont understand (Question marks and such) so i got no hope of converting it :unsure: .


[quote]what does the underside look like?[/quote]

The same as the top where there is an equal mix of light and dark triangles.

Thanks again,

John

Share this post


Link to post
Share on other sites
You're asking how to do vertex shading but the topic title is about calculating normals for a terrain. You'll have to tackle these two tasks seperated. First make your terrain use a standard passtrough vertex shader to get to know your shader api. The Api documentation should contain information on how to do this. Then after you've done this you can get started by adding normals to your terrain. You calculate that by doing crossproducts on vectors from the vertex you want the normal for to neighboring vertices. Note that the order of the cross product will change the direction in which the resulting vector points. You'd best create something to render the found normals as visual aid as to what is going wrong. It will help you a great deal when you're finalizing normal generation and applying possible optimizations to see what results it has.

Seeing you're combining the terms vertex shading and normals into seemingly 1 problem does this mean what you're trying to accomplish is actually vertex lighting?

Share this post


Link to post
Share on other sites
[quote]First make your terrain use a standard passtrough vertex shader to get to know your shader api[/quote]
Where do i find a shader API?

[quote]Seeing you're combining the terms vertex shading and normals into seemingly 1 problem does this mean what you're trying to accomplish is actually vertex lighting?[/quote]
I dunno, i just want the ground to look smooth.:( I am still a noob to most of OpenGL especially the lighting bits and my math is far from brilliant. It's a whole new world to me!

Thanks,

John

Share this post


Link to post
Share on other sites
you are using sfml for your OpenGL window so you could probably also use it to apply shaders while rendering. I'm not familiar with sfml but combining it with the word "shader" in google seems a good start. Maybe you dont have to use shaders and do lighting at all though. If all you want to accomplish is to have the ground look smooth you could just use a texture for this. There's several utilities which can generate textures for you, some can even fake light in the texture. There's concerns about texture size for example but it might be a quick and easy way to get what you need.

Share this post


Link to post
Share on other sites
I'll look into the shader thing as i can't use quick fixes as this is for an engine rather than just a game.

Many thanks for the pointers i will report back when i have it finished.

John

Share this post


Link to post
Share on other sites
Turns out it was the lighting mode giving me themost porblems, i had [code]glLightModelfv GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE[/code] when it needed to be turned off after i had drawn my sky sphere.

Here's how i have it looking now : [url="http://dl.dropbox.com/u/8822351/GL_Terrain2.PNG"]GL_terrain_2[/url] which is a vast improvement on how it was but it's till not perfect. Here's how i am doing the normals for it currently, am i doing it right?

[code]'########################################################################################################################


SUB GDK_GL_MAP_DRAW (X!, Y!, Z!, MapVert() AS VertexF, ImgH&, ImgW&)
DIM TmpTri AS Triangle, TmpTri2 AS Triangle
glTranslatef X!, Y!, Z!
FOR j& = 0 TO ImgH& - 1
glBegin GL_TRIANGLE_STRIP
FOR i& = 0 TO ImgW& - 1

TmpTri.Vertex1.X = MapVert(i&, j&).X
TmpTri.Vertex1.Y = MapVert(i&, j&).Y
TmpTri.Vertex1.Z = MapVert(i&, j&).Z
TmpTri.Vertex2.X = MapVert(i& + 1, j&).X
TmpTri.Vertex2.Y = MapVert(i& + 1, j&).Y
TmpTri.Vertex2.Z = MapVert(i& + 1, j&).Z
TmpTri.Vertex3.X = MapVert(i&, j& + 1).X
TmpTri.Vertex3.Y = MapVert(i&, j& + 1).Y
TmpTri.Vertex3.Z = MapVert(i&, j& + 1).Z
TmpTri2.Vertex1.X = MapVert(i& + 1, j&).X
TmpTri2.Vertex1.Y = MapVert(i& + 1, j&).Y
TmpTri2.Vertex1.Z = MapVert(i& + 1, j&).Z
TmpTri2.Vertex2.X = MapVert(i&, j& + 1).X
TmpTri2.Vertex2.Y = MapVert(i&, j& + 1).Y
TmpTri2.Vertex2.Z = MapVert(i&, j& + 1).Z
TmpTri2.Vertex3.X = MapVert(i& + 1, j& + 1).X
TmpTri2.Vertex3.Y = MapVert(i& + 1, j& + 1).Y
TmpTri2.Vertex3.Z = MapVert(i& + 1, j& + 1).Z
TmpTri.Normal.X = (TmpTri.Normal.X + TmpTri2.Normal.X) / 2
TmpTri.Normal.Y = (TmpTri.Normal.Y + TmpTri2.Normal.Y) / 2
TmpTri.Normal.Z = (TmpTri.Normal.Z + TmpTri2.Normal.Z) / 2

GL_Calculate_Normal TmpTri

glNormal3f TmpTri.Normal.X, TmpTri.Normal.Y, TmpTri.Normal.Z

glTexCoord2f 0.0, 0.0
glVertex3f MapVert(i&, j&).X, MapVert(i&, j&).Y, MapVert(i&, j&).Z
glTexCoord2f 1.0, 0.0
glVertex3f MapVert(i& + 1, j&).X, MapVert(i& + 1, j&).Y, MapVert(i& + 1, j&).Z
glTexCoord2f 0.0, 1.0
glVertex3f MapVert(i&, j& + 1).X, MapVert(i&, j& + 1).Y, MapVert(i&, j& + 1).Z
glTexCoord2f 1.0, 1.0
glVertex3f MapVert(i& + 1, j& + 1).X, MapVert(i& + 1, j& + 1).Y, MapVert(i& + 1, j& + 1).Z

NEXT
glEnd
NEXT
END SUB

'########################################################################################################################


SUB GDK_GL_Calculate_Normal (Tri AS Triangle)
DIM u AS VertexF, v AS VertexF
u.X = Tri.Vertex2.X - Tri.Vertex1.X
u.Y = Tri.Vertex2.Y - Tri.Vertex1.Y
u.Z = Tri.Vertex2.Z - Tri.Vertex1.Z
v.X = Tri.Vertex3.X - Tri.Vertex1.X
v.Y = Tri.Vertex3.Y - Tri.Vertex1.Y
v.Z = Tri.Vertex3.Z - Tri.Vertex1.Z
Tri.Normal.X = (u.Y * v.Z) - (u.Z * v.Y)
Tri.Normal.Y = (u.Z * v.X) - (u.X * v.Z)
Tri.Normal.Z = (u.X * v.Y) - (u.Y * v.X)
END SUB


'########################################################################################################################[/code]

Thanks again folks,

John

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this