# Calculating normals for terrain?

This topic is 2405 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## 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 GL_Terrain , as you can see, something is not quite right!

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 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 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 on other sites
Thanks for the responses,

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.

This link may help : [color="#284b72"]http://www.flipcode....ight_Maps.shtml 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 .

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 on other sites

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 on other sites
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?

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 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 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 on other sites
Turns out it was the lighting mode giving me themost porblems, i had glLightModelfv GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE when it needed to be turned off after i had drawn my sky sphere.

Here's how i have it looking now : GL_terrain_2 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?

'######################################################################################################################## 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 '########################################################################################################################

Thanks again folks,

John