so what you’re saying is that if i adjust the angle of the object by 2-5 degrees the artifacts should disappear?
Why is this so?
The normal calculations that i use:
////////////////////////////// Math Functions ////////////////////////////////*
// This computes the magnitude of a normal. (magnitude = sqrt(x^2 + y^2 + z^2)
double Mag(CVector3 Normal)
{
return (Math.sqrt(Normal.x*Normal.x + Normal.y*Normal.y + Normal.z*Normal.z));
}
// This calculates a vector between 2 points and returns the result
CVector3 Vector(CVector3 vPoint1, CVector3 vPoint2)
{
CVector3 vVector = new CVector3(); // The variable to hold the resultant vector
vVector.x = vPoint1.x - vPoint2.x; // Subtract point1 and point2 x's
vVector.y = vPoint1.y - vPoint2.y; // Subtract point1 and point2 y's
vVector.z = vPoint1.z - vPoint2.z; // Subtract point1 and point2 z's
return vVector; // Return the resultant vector
}
// This adds 2 vectors together and returns the result
CVector3 AddVector(CVector3 vVector1, CVector3 vVector2)
{
CVector3 vResult = new CVector3(); // The variable to hold the resultant vector
vResult.x = vVector2.x + vVector1.x; // Add Vector1 and Vector2 x's
vResult.y = vVector2.y + vVector1.y; // Add Vector1 and Vector2 y's
vResult.z = vVector2.z + vVector1.z; // Add Vector1 and Vector2 z's
return vResult; // Return the resultant vector
}
// This divides a vector by a single number (scalar) and returns the result
CVector3 DivideVectorByScaler(CVector3 vVector1, float Scaler)
{
CVector3 vResult = new CVector3(); // The variable to hold the resultant vector
vResult.x = vVector1.x / Scaler; // Divide Vector1's x value by the scaler
vResult.y = vVector1.y / Scaler; // Divide Vector1's y value by the scaler
vResult.z = vVector1.z / Scaler; // Divide Vector1's z value by the scaler
return vResult; // Return the resultant vector
}
// This returns the cross product between 2 vectors
CVector3 Cross(CVector3 vVector1, CVector3 vVector2)
{
CVector3 vCross = new CVector3(); // The vector to hold the cross product
// Get the X value
vCross.x = ((vVector1.y * vVector2.z) - (vVector1.z * vVector2.y));
// Get the Y value
vCross.y = ((vVector1.z * vVector2.x) - (vVector1.x * vVector2.z));
// Get the Z value
vCross.z = ((vVector1.x * vVector2.y) - (vVector1.y * vVector2.x));
return vCross; // Return the cross product
}
// This returns the normal of a vector
CVector3 Normalize(CVector3 vNormal)
{
double Magnitude; // This holds the magnitude
Magnitude = Mag(vNormal); // Get the magnitude
vNormal.x /= (float)Magnitude; // Divide the vector's X by the magnitude
vNormal.y /= (float)Magnitude; // Divide the vector's Y by the magnitude
vNormal.z /= (float)Magnitude; // Divide the vector's Z by the magnitude
return vNormal; // Return the normal
}
///////////////////////////////// COMPUTER NORMALS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This function computes the normals and vertex normals of the objects
/////
///////////////////////////////// COMPUTER NORMALS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void ComputeNormals(t3DModel pModel)
{
CVector3 vVector1 = new CVector3();
CVector3 vVector2 = new CVector3();
CVector3 vNormal = new CVector3();
CVector3[] vPoly = new CVector3[3];
// If there are no objects, we can skip this part
if(pModel.numOfObjects <= 0)
return;
// What are vertex normals? And how are they different from other normals?
// Well, if you find the normal to a triangle, you are finding a "Face Normal".
// If you give OpenGL a face normal for lighting, it will make your object look
// really flat and not very round. If we find the normal for each vertex, it makes
// the smooth lighting look. This also covers up blocky looking objects and they appear
// to have more polygons than they do. Basically, what you do is first
// calculate the face normals, then you take the average of all the normals around each
// vertex. It's just averaging. That way you get a better approximation for that vertex.
// Go through each of the objects to calculate their normals
for(int index = 0; index < pModel.numOfObjects; index++)
{
// Get the current object
t3DObject pObject = (t3DObject)pModel.pObject.get(index);
// Here we allocate all the memory we need to calculate the normals
CVector3[] pNormals = new CVector3 [pObject.numOfFaces];
CVector3[] pTempNormals = new CVector3 [pObject.numOfFaces];
pObject.pNormals = new CVector3 [pObject.numOfVerts];
// Go though all of the faces of this object
for(int i=0; i < pObject.numOfFaces; i++)
{
// To cut down LARGE code, we extract the 3 points of this face
vPoly[0] = pObject.pVerts[pObject.pFaces[i].vertIndex[0]];
vPoly[1] = pObject.pVerts[pObject.pFaces[i].vertIndex[1]];
vPoly[2] = pObject.pVerts[pObject.pFaces[i].vertIndex[2]];
// Now let's calculate the face normals (Get 2 vectors and find the cross product of those 2)
vVector1 = Vector(vPoly[0], vPoly[2]); // Get the vector of the polygon (we just need 2 sides for the normal)
vVector2 = Vector(vPoly[2], vPoly[1]); // Get a second vector of the polygon
vNormal = Cross(vVector1, vVector2); // Return the cross product of the 2 vectors (normalize vector, but not a unit vector)
pTempNormals[i] = vNormal; // Save the un-normalized normal for the vertex normals
vNormal = Normalize(vNormal); // Normalize the cross product to give us the polygons normal
pNormals[i] = vNormal; // Assign the normal to the list of normals
}
//////////////// Now Get The Vertex Normals /////////////////
CVector3 vSum = new CVector3();
CVector3 vZero = vSum;
int shared=0;
for (int i = 0; i < pObject.numOfVerts; i++) // Go through all of the vertices
{
for (int j = 0; j < pObject.numOfFaces; j++) // Go through all of the triangles
{ // Check if the vertex is shared by another face
if (pObject.pFaces[j].vertIndex[0] == i ||
pObject.pFaces[j].vertIndex[1] == i ||
pObject.pFaces[j].vertIndex[2] == i)
{
vSum = AddVector(vSum, pTempNormals[j]);// Add the un-normalized normal of the shared face
shared++; // Increase the number of shared triangles
}
}
// Get the normal by dividing the sum by the shared. We negate the shared so it has the normals pointing out.
pObject.pNormals[i] = DivideVectorByScaler(vSum, (float)(-shared));
// Normalize the normal for the final vertex normal
pObject.pNormals[i] = Normalize(pObject.pNormals[i]);
vSum = vZero; // Reset the sum
shared = 0; // Reset the shared
}
}
}
Can you see anything wrong with my normal computation?
That sudden smoothing on the far right of the object is another indent (the object is supposed to represent a network card). 
Cheers,
ribot.