The edges appear dark but the center is bright. I believe this to be an issue with calculation of the surface normals. To test this I have disabled lighting and output the normals as color in my fragment shader. I see the same effect.

Here's the code I use to calculate the surface normals.

Vert normalizeVert(Vert old_vert) { Vert new_vert; float old_length; old_length = sqrt(pow(old_vert.xcorr, 2.0f) + pow(old_vert.ycorr, 2.0f) + pow(old_vert.zcorr, 2.0f)); new_vert.xcorr = old_vert.xcorr / old_length; new_vert.ycorr = old_vert.ycorr / old_length; new_vert.zcorr = old_vert.zcorr / old_length; return new_vert; } ; // Calculate normals for terrain. void NSheet::calculateNormals(void) { // First create an object to store all the surface normals unsigned int num_surfaceNormals = pow(sheet_size - 1, 2) * 2; Vert* surfaceNormals = new Vert[num_surfaceNormals]; Face* faces = amesh->faces; // temporary vertices used in calculation Vert vert1, vert2, vert3, temp_vert; //retrieve pointer to indices unsigned int* indices = faces->indices; // retrieve pointer to mesh data float* verts = faces->verts; // compute all surface normals for (unsigned int i = 0; i < num_surfaceNormals; i++) { vert1.xcorr = verts[indices[i * 3 + 0] * 4 + 0]; vert1.ycorr = verts[indices[i * 3 + 0] * 4 + 1]; vert1.zcorr = verts[indices[i * 3 + 0] * 4 + 2]; vert2.xcorr = verts[indices[i * 3 + 1] * 4 + 0]; vert2.ycorr = verts[indices[i * 3 + 1] * 4 + 1]; vert2.zcorr = verts[indices[i * 3 + 1] * 4 + 2]; vert3.xcorr = verts[indices[i * 3 + 2] * 4 + 0]; vert3.ycorr = verts[indices[i * 3 + 2] * 4 + 1]; vert3.zcorr = verts[indices[i * 3 + 2] * 4 + 2]; // Calculate surface normal. % overloaded to produce cross product surfaceNormals[i] = (vert2 - vert1) % (vert3 - vert1); // normalize surface normal surfaceNormals[i] = normalizeVert(surfaceNormals[i]); } // create an array to hold vertex normal data faces->num_normals = pow(sheet_size, 2) * 3; amesh->num_normals = faces->num_normals; faces->normals = new float[faces->num_normals]; // This variable represents that distance in the normal array between y units in the array of surface normals unsigned int y_step = 2 * (sheet_size - 1); // calculate the normal values for each vertex for (unsigned int i = 0; i < sheet_size; i++) for (unsigned int j = 0; j < sheet_size; j++) { // the current location in the surface normal array unsigned int displacement = i * y_step + j * 2; // the current location in the vertex normal array unsigned int vertex_displacement = (i * sheet_size + j) * 3; // blank the temp vertex temp_vert.xcorr = 0.0f; temp_vert.ycorr = 0.0f; temp_vert.zcorr = 0.0f; // average the vertices for the surrounding polygons if (i > 0 && j < sheet_size - 1) { // if has square at top right temp_vert = temp_vert + (surfaceNormals[displacement - y_step] * 2); } if (i > 0 && j > 0) { // if has square at top left temp_vert = temp_vert + surfaceNormals[displacement - y_step - 2] + surfaceNormals[displacement - y_step - 1]; } if (i < sheet_size - 1 && j < sheet_size - 1) { // if has square at bottom right temp_vert = temp_vert + surfaceNormals[displacement] + surfaceNormals[displacement + 1]; } if (i < sheet_size - 1 && j > 0) { // if square at bottom left temp_vert = temp_vert + (surfaceNormals[displacement - 1] * 2); } // normalize the temporary vertex temp_vert = normalizeVert(temp_vert); // set the normal data faces->normals[vertex_displacement] = temp_vert.xcorr; faces->normals[vertex_displacement + 1] = temp_vert.ycorr; faces->normals[vertex_displacement + 2] = temp_vert.zcorr; } amesh->has_normals = true; // set to true automatically once normals are calculated // Free memory delete[] surfaceNormals; }

It uses that standard method that I have seen where you calculate a surface normal for each polygon and then average those for the verts. My best guess is that my error is here somewhere but I can't figure out where...

Anyways thanks for taking the time to read this post.