Skip to main content
GameDev.net gamedev.net
🔒 Locked

Problem with Smooth Shading

Started by Gammastrahler Aug 2, 2002 at 12:40 PM 2 replies 750+ views
Original Post
Gammastrahler
Gammastrahler
hi, i have coded a simple demo that animates a triangle mesh. my normals are calculated per vertex. the problem is, that even with a mesh resolution of 64x64 cells, the smooth shading looks aliased. the following screenshot shows a part of my mesh. if you look at the screenshot, the left picture reveals that there are dark borders around each cell, so you can still see each individual patch. although, the specular highlights are not looking convincing. i use glShadeModel(GL_SMOOTH). i can post some source code, if that would help, but i´m sure that my normals are correct. can someone tell me what i´m doing wrong here? or it is still the problem of per-vertex lighting of opengl? but even with a mesh of 128x128, i noticed this ugly effect. any help would be welcome!! thanks Gammastrahler [edited by - Gammastrahler on August 2, 2002 1:42:22 PM]
CodeSmith
CodeSmith
well this could be an issue depending on how you are calculating your vertex normals... I assume you are having 3 vertex normal per triangle. Well although there is an much more overhead, if you are worried about aesthetics, try averaging ajacent normals. You see when two triangles intersect, the normal from one triangle is different from the normal for a different triangle even though there is the shared vertex. (I hope you can visualize this) This creates a ''gap'' where no light is calculated. Imagine a 2x4 cut in half, and then bent at 30 degress- the ''v'' cut out of the center is why there is the dark area.

::wipes brow:: Hope that helps.

-Chris Smith
CodeSmith the Pixel PusherCodeSmith Webpage
Fluid FX
Fluid FX
ehm i have not learned this kinda stuff yet but i must say although you see the "wires"

it looks AWSOME

;-)

Greets
Gammastrahler
Gammastrahler
quote:

it looks AWSOME


thanks Fluid FX


quote:

try averaging ajacent normals



that´s exactly the problem, since i already average my normals as you described.
for each vertex, check if i´s adjacent to others.
if so, add the triangle´s face normal to my current vertex normal. if i´m done with this vertex, i first average by dividing it by the number of adjacent vertices. then i normalize this vertex normal.

here is the source code for computing my normals:


        
void ComputeNormals(void)
{
int i, j, k;
int normalIndex = 0, centerIndex = 0;
int nShared = 0;
vec3f av, v[6];

/******************
First, compute face normals for each triangle
*******************/

for (i = 0; i < gMeshRes-1; i++)
for (j = 0; j < gMeshRes-1; j++)
{
// first triangle of cell
v[0] = gVerts[i * gMeshRes + j].pos;
v[1] = gVerts[i * gMeshRes + j + gMeshRes].pos;
v[2] = gVerts[i * gMeshRes + j + 1].pos;


v[0].Subtract(v[1]); v[1].Subtract(v[2]);
gNormals[normalIndex++].Cross(v[0], v[1]);
gNormals[normalIndex].Normalize();

// second triangle of cell
v[3] = gVerts[i * gMeshRes + j + gMeshRes].pos;
v[4] = gVerts[i * gMeshRes + j + gMeshRes + 1].pos;
v[5] = gVerts[i * gMeshRes + j + 1].pos;

v[3].Subtract(v[4]); v[4].Subtract(v[5]);
gNormals[normalIndex++].Cross(v[3], v[4]);
gNormals[normalIndex].Normalize();
}

/***************************
Now, calculate vertex normals from
face normals
****************************/


for (k = 0; k < gVertexCount; k++)
{
normalIndex = 0;
gVerts[k].normal.Clear();
nShared = 0;
for (i = 0; i < gMeshRes-1; i++)
for (j = 0; j < gMeshRes-1; j++)
{
// first triangle of cell

if (gVerts[k].pos.Equal(gVerts[i * gMeshRes + j].pos) ||
gVerts[k].pos.Equal(gVerts[i * gMeshRes + j + gMeshRes].pos) ||
gVerts[k].pos.Equal(gVerts[i * gMeshRes + j + 1].pos))
{
gVerts[k].normal.Add(gNormals[normalIndex]);
nShared++;
}
normalIndex++;

// second triangle of cell

if (gVerts[k].pos.Equal(gVerts[i * gMeshRes + j + gMeshRes].pos) ||
gVerts[k].pos.Equal(gVerts[i * gMeshRes + j + gMeshRes + 1].pos) ||
gVerts[k].pos.Equal(gVerts[i * gMeshRes + j + 1].pos))
{
gVerts[k].normal.Add(gNormals[normalIndex]);
nShared++;
}
normalIndex++;
}
// average by dividing


if (nShared) gVerts[k].normal.Divide((float)nShared);
// renormalize

gVerts[k].normal.Normalize();
}
}


[edited by - Gammastrahler on August 2, 2002 2:38:15 PM]

[edited by - Gammastrahler on August 2, 2002 2:40:29 PM]

[edited by - Gammastrahler on August 2, 2002 2:42:26 PM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.