Software renderer Matrix trouble

Started by
0 comments, last by kSquared 19 years, 3 months ago
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]
Advertisement
Use the tags, not <code>.
- k2"Choose a job you love, and you'll never have to work a day in your life." — Confucius"Logic will get you from A to B. Imagination will get you everywhere." — Albert Einstein"Money is the most egalitarian force in society. It confers power on whoever holds it." — Roger Starr{General Programming Forum FAQ} | {Blog/Journal} | {[email=kkaitan at gmail dot com]e-mail me[/email]} | {excellent webhosting}

This topic is closed to new replies.

Advertisement