Sign in to follow this  

Software renderer Matrix trouble

This topic is 4716 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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[i]->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]

Share this post


Link to post
Share on other sites

This topic is 4716 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this