Hi
Im making a small software renderer, it works fine until I implemented Gouraud shading.
I think its my normals that becomes corrupted when I rotate them.
here is a image of how it looks:
www.drx.dk/images/software/software03.jpg
(The lines are the vertex normals, as you can see the same vertex has diferent normals)
There is only one light source and its located betwen the pyramid and user.
This is how i calculate the light intensity:
float intensity = 0;
for (int i=0; i < numLights; i++)
{
Vector3 lineOfSight = lights->pos - p;
// Should precompute this length
// FIXME! normals should be normalized when they get here
float len = normal.Magnitude();
float dot = lineOfSight.Dot(normal);
if (dot > 0)
intensity += dot/(len * lineOfSight.Magnitude());
}
if (intensity > 1.0f)
intensity = 1.0f;
return intensity;
I got it from an old book i have "Black art of 3d game programmig" by Andre LaMothe, too me this calculations doesn't seem right but that might be because im thinking of a omni light source while this computes a point light source.
moving along..
I setup my pyram like this:
Color col2(255,255,255);
Vector3 v0(0,100,0);
Vector3 v1(100,-100,100);
Vector3 v2(100,-100,-100);
Vector3 v3(-100,-100,-100);
Vector3 v4(-100,-100,100);
Vector3 verts[12] = {v0, v2, v1,
v0, v3, v2,
v0, v4, v3,
v0, v1, v4};
Color colors[12] = {col, col, col,
col, col, col,
col, col, col,
col, col, col};
Vector3 n0 = (verts[0] - verts[2]).Cross( (verts[0] - verts[1]) );
Vector3 n1 = (verts[3] - verts[5]).Cross( (verts[3] - verts[4]) );
Vector3 n2 = (verts[6] - verts[8]).Cross( (verts[6] - verts[7]) );
Vector3 n3 = (verts[9] - verts[11]).Cross( (verts[9] - verts[10]) );
//--
Vector3 nv0 = (n0 + n1 + n2 + n3) / 4;
nv0.Normalize();
Vector3 nv1 = (n0 + n3) / 2;
nv1.Normalize();
Vector3 nv2 = (n0 + n1) / 2;
nv2.Normalize();
Vector3 nv3 = (n1 + n2) / 2;
nv3.Normalize();
Vector3 nv4 = (n2 + n3) / 2;
nv4.Normalize();
//--
Vector3 normals[12] = { nv0, nv2, nv1,
nv0, nv3, nv2,
nv0, nv4, nv3,
nv0, nv1, nv4};
renderer->drawTriangles(4,verts,normals,colors);
It is translated to (0,0,500) later.
now to the part where i think the problem is, the matrix.
I found this from the OGL Red book:
http://fly.cc.fer.hr/~unreal/theredbook/appendixg.html
that states that the normals are transformed with the matrix (T^-1)^* ( that is the invers of T transposed).
My matrix class looks like this:
www.drx.dk/images/software/Matrix.h && www.drx.dk/images/software/Matrix.cpp
I multiply my rotations matrices like this R = X * Y * Z
To me it feels wrong to translate normals, should i really do that ?
At the moment i don't, and then T = R and (R^-1)^* = X * Y * Z, the same as R (I think thats correct, i did a proof of it on paper).
So my drawTriangles() method looks like this:
void Renderer::drawTriangles(int numTriangles, Vector3 *verts,Vector3 *normals, const Color *colors)
{
Vector2i projVerts[3];
Vector3 transVerts[3];
Vector3 transNormals[3];
Vector3 *ptrV = verts;
Vector3 *ptrN = normals;
const Color *ptrC = colors;
for (int i=0; i < numTriangles; i++, ptrV += 3, ptrN += 3, ptrC += 3)
{
transVerts[0] = matrix * ptrV[0] + translation;
transVerts[1] = matrix * ptrV[1] + translation;
transVerts[2] = matrix * ptrV[2] + translation;
if (isTriangleVisible(transVerts))
{
transNormals[0] = matrix * ptrN[0];
transNormals[1] = matrix * ptrN[1];
transNormals[2] = matrix * ptrN[2];
projVerts[0] = projectPoint(transVerts[0]);
projVerts[1] = projectPoint(transVerts[1]);
projVerts[2] = projectPoint(transVerts[2]);
graphics->drawTriangle2D(transVerts,transNormals, ptrC, projVerts);
}
}
}
graphics->drawTriangle2D() does the actualy draving of the triangle.
I put up the main classes of my project if i didn't suply enough information:
www.drx.dk/images/software/Renderer.h && www.drx.dk/images/software/Renderer.cpp
www.drx.dk/images/software/Graphics.h && www.drx.dk/images/software/Graphics.cpp
www.drx.dk/images/software/ShaderGouraud.h
(I know virtual functions are a bit slow but it makes the code sooooo much cleaner and easier to change)
There are a lot of commented code in those files, its old/new design ideas that haven't yet been removed/implemented, i hope it doesn't make it to messy.
[Edited by - DrX on January 18, 2005 9:18:20 AM]