Lighting and Normal Calculations

OK, so now ive got my water texture rendering properly and i’ve fixed a few other issues, Im trying to enable lighting on my scene.

Ive successfully enabled it, and set some default light properties which arent great (but should be ok for now).

So first thing is im trying to create some normals for my heightmap, at the moment ive calcualted one normal for one iteration of my triangle strip loop. Im getting some ugly effects

This is probably becuase Im only doing one normal when i need 3 or 4 for my 3 triangle strips.

heres my heightmap rendering code so far:

for (int mapZ = 1; mapZ < MapHeight; mapZ+=averageSmoother)
            {
                if (mapX>1 & mapZ>=1 & mapX<=MapWidth-5 & mapZ<=MapHeight-5)
                {
                    gl.glBegin(gl.GL_TRIANGLE_STRIP);
                    vertexHeight = BMPHeightMapStore[mapX][mapZ];
    
                    //Vector A
                    vectA.x=mapX-mapX;
                    vectA.y=vertexHeight-(BMPHeightMapStore[mapX][mapZ+averageSmoother]); //current v height - next v height
                    vectA.z=mapZ-(mapZ+averageSmoother);
                    //Vector B
                    vectB.x=mapX-mapX;
                    vectB.y=(BMPHeightMapStore[mapX][mapZ+averageSmoother])-(BMPHeightMapStore[mapX+averageSmoother][mapZ]);
                    vectB.z=(float) mapZ+averageSmoother-mapZ;
                    //Calculate normal vector from cross product of A & B
                    Vector3f.cross(vectNormal, vectA, vectB);


                    gl.glNormal3f(vectNormal.x, vectNormal.y, vectNormal.z);
                    
                    gl.glTexCoord2f((float)mapX / MapWidth, (float)mapZ / MapHeight);
                    gl.glVertex3f((float)mapX,vertexHeight,(float)mapZ);

                    vertexHeight = BMPHeightMapStore[mapX][mapZ+averageSmoother];
                    gl.glTexCoord2f((float)mapX / MapWidth, (float)(mapZ+averageSmoother) / MapHeight);
                    gl.glVertex3f((float) mapX,vertexHeight,(float) mapZ+averageSmoother);

                    vertexHeight = BMPHeightMapStore[mapX+averageSmoother][mapZ];
                    gl.glTexCoord2f((float)(mapX+averageSmoother) / MapWidth, (float)mapZ / MapHeight);
                    gl.glVertex3f((float) mapX+averageSmoother,vertexHeight,(float)mapZ);

                    vertexHeight = BMPHeightMapStore[mapX+averageSmoother][mapZ+averageSmoother];
                    gl.glTexCoord2f((float)(mapX+averageSmoother) / MapWidth, (float)(mapZ+averageSmoother) / MapHeight);
                    gl.glVertex3f((float)mapX+averageSmoother,vertexHeight,(float)mapZ+averageSmoother);
                    gl.glEnd();
//                    gl.glPushAttrib(GL.GL_COLOR_BUFFER_BIT);
//                    gl.glColor3f(0.0f, 1.0f, 0.0f);
//                    gl.glBegin(GL.GL_LINES);
//                    gl.glVertex3f(vectNormal.x, vectNormal.y, vectNormal.z);
//                    gl.glVertex3f((vectNormal.x)+2, (vectNormal.y)+2, (vectNormal.z)+2);
//                    gl.glEnd();
//                    gl.glPopAttrib();
                }
            }
        }

As you can see I was also trying to draw a line along the normal so I could see if they were pointing in the correct direction, however this didnt work (no visible lines :()

What I really want to know now is :

a) Is my code for calculating one normal ok?

b1) If I create normals for all verticies will the ugly square shading sort itsself out - or am I stuck with it because of the resolution of my mesh?

b2) If it will help - To create normals for the other 3(?) verticities i assume I can just use the next 2 verticies listed (i.e instead of vertex 0 and 1, i can use 1 and 2, and then 2 and 3?) is this correct?

Normals do my brain in!

Thanks in advance :slight_smile:

Regards

Wills

Well ive tried to do the normals for all my verticies. Gone wrong somewhere though:

Whoops!

Without reading the code, there is something you seem to do wrong on both cases : to have a smooth shading, you should only need 1 normal per vertex, even if the vertex is shared among 6 triangles.

Doing this for the first image would already give a better result, as it would approximate the normal at one vertex from the normal of one of the adjacent triangles. A more correct way to find the normal at one vertex, is to take in account all adjacent triangles, average their normals (even better : with a weight depending on the surface of each, not so useful for a regular heightmap grid), and renormalize the result.

Hum, ok maybe I got the wrong end of the stick as I was under the impression that to get the best results each vertex needed a normal.
Here is what I have code wise:

 int vertexHeight;
        for (int mapX = 1; mapX < MapWidth; mapX +=averageSmoother)
        {
            for (int mapZ = 1; mapZ < MapHeight; mapZ+=averageSmoother)
            {
                if (mapX>1 & mapZ>=1 & mapX<=MapWidth-5 & mapZ<=MapHeight-5)
                {
                    // VERTEX 1
                    gl.glBegin(gl.GL_TRIANGLE_STRIP);
                    vertexHeight = BMPHeightMapStore[mapX][mapZ];
                        //previous vert 4 - current 1
                        //Vector A
                        vectA.x= mapX - mapX;
                        vectA.y=(BMPHeightMapStore[mapX][mapZ+averageSmoother])-vertexHeight;
                        vectA.z=(mapZ+averageSmoother)-(mapZ);
                        //current vert 2 - current 1
                        //Vector B
                        vectB.x=mapX-(mapX+averageSmoother);
                        vectB.y=(vertexHeight)-(BMPHeightMapStore[mapX+averageSmoother][mapZ]);
                        vectB.z=(mapZ)-(mapZ);

                        //Calculate normal vector from cross product of A & B
                        Vector3f.cross(vectNormal, vectA, vectB);

                    gl.glNormal3f(vectNormal.x, vectNormal.y, vectNormal.z);
                    gl.glTexCoord2f((float)mapX / MapWidth, (float)mapZ / MapHeight);
                    gl.glVertex3f((float)mapX,vertexHeight,(float)mapZ);

                    // VERTEX 2
                    vertexHeight = BMPHeightMapStore[mapX][mapZ+averageSmoother];

                        //Vector A
                        vectA.x=(mapX)-(mapX);
                        vectA.y=(BMPHeightMapStore[mapX][mapZ])-(vertexHeight);
                        vectA.z=(mapZ)-(mapZ+averageSmoother);
                        //Vector B
                        vectB.x=mapX-(mapX+averageSmoother);
                        vectB.y=(vertexHeight)-(BMPHeightMapStore[mapX+averageSmoother][mapZ]);
                        vectB.z=(mapZ+averageSmoother)-(float)mapZ;

                        //Calculate normal vector from cross product of A & B
                        Vector3f.cross(vectNormal, vectA, vectB);
                        gl.glNormal3f(vectNormal.x, vectNormal.y, vectNormal.z);

                    gl.glTexCoord2f((float)mapX / MapWidth, (float)(mapZ+averageSmoother) / MapHeight);
                    gl.glVertex3f((float) mapX,vertexHeight,(float) mapZ+averageSmoother);

                    // VERTEX 3
                    vertexHeight = BMPHeightMapStore[mapX+averageSmoother][mapZ];

                        //Vector A
                        vectA.x=(mapX+averageSmoother)-(mapX+averageSmoother);
                        vectA.y=(vertexHeight) - (BMPHeightMapStore[mapX+averageSmoother][mapZ+averageSmoother]);
                        vectA.z=(mapZ) - (mapZ+averageSmoother);
                        //Vector B
                        vectB.x=((mapZ+averageSmoother) - (mapX+1));
                        vectB.y=(BMPHeightMapStore[(mapX+1)][mapZ])-(BMPHeightMapStore[mapX+averageSmoother][mapZ+averageSmoother]); //z+1
                        vectB.z=(mapZ - (mapZ+averageSmoother)); //z + 1?

                        //Calculate normal vector from cross product of A & B
                        Vector3f.cross(vectNormal, vectA, vectB);
                        gl.glNormal3f(vectNormal.x, vectNormal.y, vectNormal.z);



                    gl.glTexCoord2f((float)(mapX+averageSmoother) / MapWidth, (float)mapZ / MapHeight);
                    gl.glVertex3f((float) mapX+averageSmoother,vertexHeight,(float)mapZ);

                    // VERTEX 4
                    vertexHeight = BMPHeightMapStore[mapX+averageSmoother][mapZ+averageSmoother];


                        //Vector A
                        vectA.x= (mapX+averageSmoother) - (mapX+1);
                        vectA.y= vertexHeight - (BMPHeightMapStore[mapX+averageSmoother][mapZ+averageSmoother]);
                        vectA.z= ((mapZ+averageSmoother)-(mapZ+averageSmoother));
                        //Vector B
                        vectB.x=((mapX+1) - (mapX+1));
                        vectB.y=((BMPHeightMapStore[mapX+averageSmoother][mapZ+averageSmoother])-(BMPHeightMapStore[mapX+1][mapZ+averageSmoother]));//z+1?
                        vectB.z=((mapZ+averageSmoother) - (mapZ+averageSmoother)); //z+1?

                        //Calculate normal vector from cross product of A & B
                        Vector3f.cross(vectNormal, vectA, vectB);
                        gl.glNormal3f(vectNormal.x, vectNormal.y, vectNormal.z);



                    gl.glTexCoord2f((float)(mapX+averageSmoother) / MapWidth, (float)(mapZ+averageSmoother) / MapHeight);
                    gl.glVertex3f((float)mapX+averageSmoother,vertexHeight,(float)mapZ+averageSmoother);
                    gl.glEnd();
//                    gl.glPushAttrib(GL.GL_COLOR_BUFFER_BIT);
//                    gl.glColor3f(0.0f, 1.0f, 0.0f);
//                    gl.glBegin(GL.GL_LINES);
//                    gl.glVertex3f(vectNormal.x, vectNormal.y, vectNormal.z);
//                    gl.glVertex3f((vectNormal.x)+2, (vectNormal.y)+2, (vectNormal.z)+2);
//                    gl.glEnd();
//                    gl.glPopAttrib();
                }
            }
        }

Im sure im getting some of the calculations the wrong way around, hence the grid type effect. Just struggling to visualise adjacent verticies within the loop. Where do I go from here :frowning:

Thanks for the reply by the way, much appreciated :slight_smile:
Regards
Wills

Your code is very hard to read, use functions. The idea for computing normals at each vertex for smooth shading is:

  1. compute all triangle normals
  2. For one vertex, look for all triangles that use this vertex and store its normal
  3. Compute vertices normals averaging the normals of all triangles that use them.

For 1), do not forget to normalize all computed normals before going to 2).

If you already comply with all these rules it must be something in your code. You might try to clean, simplify it to better see errors. If you don’t understand something about normals computation don’t hesite to ask more questions.

I aggree with you, its very hard to read - probably why I’m having so many issues.

What ive tried to do in the code above, is for each vertex added, use 2 other verticies next to the current one to calcualte the normal. Because of the way the verticies are created in a triangle strip loop, im not quite sure how to check the neighbouring verticies.

Ive tried to do 1) as above, but not 2 or 3 (and I have no idea where to start :(.)

Ill have another look and try to clean stuff up.
Tricky stuff!

Thanks for the reply, much appreciated :).

Regards
Wills

Okay so ive tried again, I thought I had it this time - Aparently not :frowning:

Here’s what ive got:

Custom datatype for vectors:

class Vector3f
{
    public float x, y, z;
    public Vector3f(float newX,float newY,float newZ)
    {
        x = newX;
        y = newY;
        z = newZ;
    }
}

Compute Normals function:


public Vector3f computeNormals(Vector3f vertexA,Vector3f vertexB,Vector3f vertexC)
    {
        float vectDistance;
        Vector3f vectorAB = new Vector3f(0.0f,0.0f,0.0f),
                 vectorAC = new Vector3f(0.0f,0.0f,0.0f),
                 normalVector = new Vector3f(0.0f,0.0f,0.0f);
        // Calculate the length of vectors 1,2 and 3
        // Vector ab
            vectorAB.x=(vertexB.x-vertexA.x);
            vectorAB.y=(vertexB.y-vertexA.y);
            vectorAB.z=(vertexB.z-vertexA.z);
        // Vector ac
            vectorAC.x=(vertexC.x-vertexA.x);
            vectorAC.y=(vertexC.y-vertexA.y);
            vectorAC.z=(vertexC.z-vertexA.z);
        // Calculate normal vector using dot product
            normalVector.x = ((vectorAB.y * vectorAC.z)-(vectorAB.z * vectorAC.y));
            normalVector.y = ((vectorAB.z * vectorAC.x)-(vectorAB.x * vectorAC.z));
            normalVector.z = ((vectorAB.x * vectorAC.y)-(vectorAB.y * vectorAC.x));
        // Normalise out vector by finding each length and dividing to get a unit value
            vectDistance = (float) Math.sqrt((normalVector.x*normalVector.x)+(normalVector.y*normalVector.y)+(normalVector.z*normalVector.z));
            normalVector.x = normalVector.x / vectDistance;
            normalVector.y = normalVector.y / vectDistance;
            normalVector.z = normalVector.z / vectDistance;
        // Return the normalised normal vector.
        return normalVector;
    }


Code for looping through heightfield and rendering heightmap:



int vertexHeight;
        for (int mapX = 1; mapX < MapWidth; mapX +=averageSmoother)
        {
            for (int mapZ = 1; mapZ < MapHeight; mapZ+=averageSmoother)
            {
                if (mapX>1 & mapZ>=1 & mapX<=MapWidth-5 & mapZ<=MapHeight-5)
                {
                    float vertexHeightA = BMPHeightMapStore[mapX][mapZ];
                    float vertexHeightB = BMPHeightMapStore[mapX][mapZ+averageSmoother];
                    float vertexHeightC = BMPHeightMapStore[mapX+averageSmoother][mapZ];
                    float vertexHeightD = BMPHeightMapStore[mapX+averageSmoother][mapZ+averageSmoother];

                    gl.glBegin(gl.GL_TRIANGLE_STRIP);

                    // VERTEX 1                    
                    vertexHeight = BMPHeightMapStore[mapX][mapZ];


                    // New Vertex 1

                    tempVect1.x=mapX;
                    tempVect1.y=vertexHeightA;
                    tempVect1.z=mapZ;

                    tempVect2.x=mapX+averageSmoother;
                    tempVect2.y=vertexHeightC;
                    tempVect2.z=mapZ;

                    tempVect3.x=mapX;
                    tempVect3.y=vertexHeightB;
                    tempVect3.z=mapZ+averageSmoother;

                    tempNormal = computeNormals(tempVect1,tempVect2,tempVect3);

                    gl.glNormal3f(tempNormal.x,tempNormal.y,tempNormal.z);
                    gl.glTexCoord2f((float)mapX / MapWidth, (float)mapZ / MapHeight);
                    gl.glVertex3f((float)mapX,vertexHeight,(float)mapZ);

                    // VERTEX 2
                    vertexHeight = BMPHeightMapStore[mapX][mapZ+averageSmoother];

                    // New Vertex 2

                    tempVect1.x=mapX;
                    tempVect1.y=vertexHeightB;
                    tempVect1.z=mapZ+averageSmoother;

                    tempVect2.x=mapX;
                    tempVect2.y=vertexHeightA;
                    tempVect2.z=mapZ;

                    tempVect3.x=mapX+averageSmoother;
                    tempVect3.y=vertexHeightD;
                    tempVect3.z=mapZ+averageSmoother;

                    tempNormal = computeNormals(tempVect1,tempVect2,tempVect3);

                    gl.glNormal3f(tempNormal.x,tempNormal.y,tempNormal.z);
                    gl.glTexCoord2f((float)mapX / MapWidth, (float)(mapZ+averageSmoother) / MapHeight);
                    gl.glVertex3f((float) mapX,vertexHeight,(float) mapZ+averageSmoother);

                    // VERTEX 3
                    vertexHeight = BMPHeightMapStore[mapX+averageSmoother][mapZ];

                  // New Vertex 3

                    tempVect1.x=mapX+averageSmoother;
                    tempVect1.y=vertexHeightC;
                    tempVect1.z=mapZ;

                    tempVect2.x=mapX+averageSmoother;
                    tempVect2.y=vertexHeightD;
                    tempVect2.z=mapZ+averageSmoother;

                    tempVect3.x=mapX;
                    tempVect3.y=vertexHeightA;
                    tempVect3.z=mapZ;

                    tempNormal = computeNormals(tempVect1,tempVect2,tempVect3);

                    gl.glNormal3f(tempNormal.x,tempNormal.y,tempNormal.z);
                    gl.glTexCoord2f((float)(mapX+averageSmoother) / MapWidth, (float)mapZ / MapHeight);
                    gl.glVertex3f((float) mapX+averageSmoother,vertexHeight,(float)mapZ);

                    // VERTEX 4
                    vertexHeight = BMPHeightMapStore[mapX+averageSmoother][mapZ+averageSmoother];


                    // New Vertex 4

                    tempVect1.x=mapX+averageSmoother;
                    tempVect1.y=vertexHeightD;
                    tempVect1.z=mapZ+averageSmoother;

                    tempVect2.x=mapX;
                    tempVect2.y=vertexHeightB;
                    tempVect2.z=mapZ+averageSmoother;

                    tempVect3.x=mapX+averageSmoother;
                    tempVect3.y=vertexHeightC;
                    tempVect3.z=mapZ;

                    tempNormal = computeNormals(tempVect1,tempVect2,tempVect3);

                    gl.glNormal3f(tempNormal.x,tempNormal.y,tempNormal.z);
                    gl.glTexCoord2f((float)(mapX+averageSmoother) / MapWidth, (float)(mapZ+averageSmoother) / MapHeight);
                    gl.glVertex3f((float)mapX+averageSmoother,vertexHeight,(float)mapZ+averageSmoother);
                    gl.glEnd();
                }
            }
        }


I think that im pretty close, at least I thought I’d done all that was required, however my shading is still very rough and not nice atall (especially when the light source is moving).

Please, if anyones got any ideas as to what im missing, i’d be most grateful.

Thanks
Regards
Wills.

From the screenshot, it seem very clear that you correctly interpolate along a strip. But you should also interpolate between strips.

Making your code more modular is a good step, you can continue in that direction. To avoid the mix of CPU computations and GL commands, it may be a good idea to precompute vertex positions and normals to arrays. That may help you understand better what is going on.

Ok, I have tried to compute the normals in a method which gets called once via the init method.

This method is as follows:

 private void setupNormalStore()
    {
        normalsStore = new Vector3f[tempHeightMap.getWidth()][tempHeightMap.getHeight()];
        int vertexHeight;
        for (int mapX = 1; mapX < MapWidth; mapX +=averageSmoother)
        {
            for (int mapZ = 1; mapZ < MapHeight; mapZ+=averageSmoother)
            {
                if (mapX>1 & mapZ>=1 & mapX<=MapWidth-5 & mapZ<=MapHeight-5)
                {
                    float vertexHeightA = BMPHeightMapStore[mapX][mapZ];
                    float vertexHeightB = BMPHeightMapStore[mapX][mapZ+averageSmoother];
                    float vertexHeightC = BMPHeightMapStore[mapX+averageSmoother][mapZ];
                    float vertexHeightD = BMPHeightMapStore[mapX+averageSmoother][mapZ+averageSmoother];

                    // VERTEX 1
                    vertexHeight = BMPHeightMapStore[mapX][mapZ];       

                    // New Vertex 1

                    tempVect1.x=mapX;
                    tempVect1.y=vertexHeightA;
                    tempVect1.z=mapZ;

                    tempVect2.x=mapX+averageSmoother;
                    tempVect2.y=vertexHeightC;
                    tempVect2.z=mapZ;

                    tempVect3.x=mapX;
                    tempVect3.y=vertexHeightB;
                    tempVect3.z=mapZ+averageSmoother;

                    tempNormal = computeNormals(tempVect1,tempVect2,tempVect3);
                    normalsStore[mapX][mapZ]=tempNormal;
                    
                    // VERTEX 2
                    vertexHeight = BMPHeightMapStore[mapX][mapZ+averageSmoother];

                    // New Vertex 2

                    tempVect1.x=mapX;
                    tempVect1.y=vertexHeightB;
                    tempVect1.z=mapZ+averageSmoother;

                    tempVect2.x=mapX;
                    tempVect2.y=vertexHeightA;
                    tempVect2.z=mapZ;

                    tempVect3.x=mapX+averageSmoother;
                    tempVect3.y=vertexHeightD;
                    tempVect3.z=mapZ+averageSmoother;

                    tempNormal = computeNormals(tempVect1,tempVect2,tempVect3);
                    normalsStore[mapX][mapZ+averageSmoother]=tempNormal;

                    // VERTEX 3
                    vertexHeight = BMPHeightMapStore[mapX+averageSmoother][mapZ];

                    // New Vertex 3

                    tempVect1.x=mapX+averageSmoother;
                    tempVect1.y=vertexHeightC;
                    tempVect1.z=mapZ;

                    tempVect2.x=mapX+averageSmoother;
                    tempVect2.y=vertexHeightD;
                    tempVect2.z=mapZ+averageSmoother;

                    tempVect3.x=mapX;
                    tempVect3.y=vertexHeightA;
                    tempVect3.z=mapZ;

                    tempNormal = computeNormals(tempVect1,tempVect2,tempVect3);
                    normalsStore[mapX+averageSmoother][mapZ]=tempNormal;

                    // VERTEX 4
                    vertexHeight = BMPHeightMapStore[mapX+averageSmoother][mapZ+averageSmoother];
                    // New Vertex 4

                    tempVect1.x=mapX+averageSmoother;
                    tempVect1.y=vertexHeightD;
                    tempVect1.z=mapZ+averageSmoother;

                    tempVect2.x=mapX;
                    tempVect2.y=vertexHeightB;
                    tempVect2.z=mapZ+averageSmoother;

                    tempVect3.x=mapX+averageSmoother;
                    tempVect3.y=vertexHeightC;
                    tempVect3.z=mapZ;

                    tempNormal = computeNormals(tempVect1,tempVect2,tempVect3);
                    normalsStore[mapX+averageSmoother][mapZ+averageSmoother]=tempNormal;
                }
            }
        }
        
        Vector3f tempNorm1, tempNorm2, tempNorm3, tempNorm4, finalAveragedNormal;
        float averageX,averageY,averageZ;
        for (int mapX = 1; mapX < MapWidth; mapX +=averageSmoother)
        {
            for (int mapZ = 1; mapZ < MapHeight; mapZ+=averageSmoother)
            {
                if (mapX>4 & mapZ>=4 & mapX<=MapWidth-5 & mapZ<=MapHeight-5)
                {
                    tempNorm1 = normalsStore[mapX][mapZ];
                    tempNorm2 = normalsStore[mapX+averageSmoother][mapZ];
                    tempNorm3 = normalsStore[mapX][mapZ+averageSmoother];
                    tempNorm4 = normalsStore[mapX+averageSmoother][mapZ+averageSmoother];
                    averageX = ((tempNorm1.x+tempNorm2.x+tempNorm3.x+tempNorm4.x)/4);
                    averageY = ((tempNorm1.y+tempNorm2.y+tempNorm3.y+tempNorm4.y)/4);
                    averageZ = ((tempNorm1.z+tempNorm2.z+tempNorm3.z+tempNorm4.z)/4);
                    finalAveragedNormal = new Vector3f(averageX,averageY,averageZ);
                    normalsStore[mapX][mapZ]=tempNormal;
                }
            }
        }
    }     

What I have tried to do is use a similar loop as that which draws the heightmap, I have removed all my normal calculations out of the heightMap Render function into the method above.

I have tried to compute the vector at each vertex and store the result in a 2D array. I then loop through the new array of normals and try to average the middle one with 4 surrounding ones (overwriting the value in the array for the current vertex)

In my display i then call my normal for each vertex like this:

  int vertexHeight;
        for (int mapX = 1; mapX < MapWidth; mapX +=averageSmoother)
        {
            for (int mapZ = 1; mapZ < MapHeight; mapZ+=averageSmoother)
            {
                if (mapX>1 & mapZ>=1 & mapX<=MapWidth-5 & mapZ<=MapHeight-5)
                {
                    float vertexHeightA = BMPHeightMapStore[mapX][mapZ];
                    float vertexHeightB = BMPHeightMapStore[mapX][mapZ+averageSmoother];
                    float vertexHeightC = BMPHeightMapStore[mapX+averageSmoother][mapZ];
                    float vertexHeightD = BMPHeightMapStore[mapX+averageSmoother][mapZ+averageSmoother];

                    gl.glBegin(gl.GL_TRIANGLE_STRIP);

                    // VERTEX 1                    
                    vertexHeight = BMPHeightMapStore[mapX][mapZ];


                    // New Vertex 1

                    tempVect1.x=mapX;
                    tempVect1.y=vertexHeightA;
                    tempVect1.z=mapZ;

                    tempVect2.x=mapX+averageSmoother;
                    tempVect2.y=vertexHeightC;
                    tempVect2.z=mapZ;

                    tempVect3.x=mapX;
                    tempVect3.y=vertexHeightB;
                    tempVect3.z=mapZ+averageSmoother;

                    tempNormal = computeNormals(tempVect1,tempVect2,tempVect3);
                    gl.glNormal3f(normalsStore[mapX][mapZ].x, normalsStore[mapX][mapZ].y, normalsStore[mapX][mapZ].z);
                    //gl.glNormal3f(tempNormal.x,tempNormal.y,tempNormal.z);
                    gl.glTexCoord2f((float)mapX / MapWidth, (float)mapZ / MapHeight);
                    gl.glVertex3f((float)mapX,vertexHeight,(float)mapZ);

                    // VERTEX 2
                    vertexHeight = BMPHeightMapStore[mapX][mapZ+averageSmoother];

                    // New Vertex 2

                    tempVect1.x=mapX;
                    tempVect1.y=vertexHeightB;
                    tempVect1.z=mapZ+averageSmoother;

                    tempVect2.x=mapX;
                    tempVect2.y=vertexHeightA;
                    tempVect2.z=mapZ;

                    tempVect3.x=mapX+averageSmoother;
                    tempVect3.y=vertexHeightD;
                    tempVect3.z=mapZ+averageSmoother;

                    tempNormal = computeNormals(tempVect1,tempVect2,tempVect3);

//                    gl.glNormal3f(tempNormal.x,tempNormal.y,tempNormal.z);
                    gl.glNormal3f(normalsStore[mapX][mapZ].x, normalsStore[mapX][mapZ].y, normalsStore[mapX][mapZ+averageSmoother].z);
                    gl.glTexCoord2f((float)mapX / MapWidth, (float)(mapZ+averageSmoother) / MapHeight);
                    gl.glVertex3f((float) mapX,vertexHeight,(float) mapZ+averageSmoother);

                    // VERTEX 3
                    vertexHeight = BMPHeightMapStore[mapX+averageSmoother][mapZ];

                  // New Vertex 3

                    tempVect1.x=mapX+averageSmoother;
                    tempVect1.y=vertexHeightC;
                    tempVect1.z=mapZ;

                    tempVect2.x=mapX+averageSmoother;
                    tempVect2.y=vertexHeightD;
                    tempVect2.z=mapZ+averageSmoother;

                    tempVect3.x=mapX;
                    tempVect3.y=vertexHeightA;
                    tempVect3.z=mapZ;

                    tempNormal = computeNormals(tempVect1,tempVect2,tempVect3);

//                    gl.glNormal3f(tempNormal.x,tempNormal.y,tempNormal.z);
                    gl.glNormal3f(normalsStore[mapX+averageSmoother][mapZ].x, normalsStore[mapX][mapZ].y, normalsStore[mapX][mapZ].z);
                    gl.glTexCoord2f((float)(mapX+averageSmoother) / MapWidth, (float)mapZ / MapHeight);
                    gl.glVertex3f((float) mapX+averageSmoother,vertexHeight,(float)mapZ);

                    // VERTEX 4
                    vertexHeight = BMPHeightMapStore[mapX+averageSmoother][mapZ+averageSmoother];


                    // New Vertex 4

                    tempVect1.x=mapX+averageSmoother;
                    tempVect1.y=vertexHeightD;
                    tempVect1.z=mapZ+averageSmoother;

                    tempVect2.x=mapX;
                    tempVect2.y=vertexHeightB;
                    tempVect2.z=mapZ+averageSmoother;

                    tempVect3.x=mapX+averageSmoother;
                    tempVect3.y=vertexHeightC;
                    tempVect3.z=mapZ;

                    tempNormal = computeNormals(tempVect1,tempVect2,tempVect3);

//                    gl.glNormal3f(tempNormal.x,tempNormal.y,tempNormal.z);
                    gl.glNormal3f(normalsStore[mapX+averageSmoother][mapZ].x, normalsStore[mapX][mapZ].y, normalsStore[mapX][mapZ+averageSmoother].z);
                    gl.glTexCoord2f((float)(mapX+averageSmoother) / MapWidth, (float)(mapZ+averageSmoother) / MapHeight);
                    gl.glVertex3f((float)mapX+averageSmoother,vertexHeight,(float)mapZ+averageSmoother);
                    gl.glEnd();
                }
            }
        } 

Somethings not working quite right, however Ive muddled everything up in my head trying to do this and i just cant work out what to do to fix it :frowning:

Any pointers as to where ive gone wrong (I think in several places!! :frowning: )

Something that I find particularly useful is doing all the math out by hand on paper. I can draw the pictures I want, and figure out what all the steps are. I can find out what variables I need by looking at the pictures. I find the formulas, and then I write the program. Since you’ve “muddled everything up,” it might help to step back look at a picture of what’s going on.