Archived

This topic is now archived and is closed to further replies.

Liquidus

MD2 Models with Gourad Shading

Recommended Posts

I have a class to load and display md2 model files based on the code in OpenGL Game Programming. The problem is the code only figures surface normals so i can only get flat shading. I need it to figure the vertex normals so i can get smooth shading. I think if i spent a long time looking back through the file format I could eventually come up with code that would figure the vertex normals, but i''m sure someone else must have already done this. It seems like it would be hard to change the code to figure out the averages of the surface normals around each vertex. If any one has done this or could point me in the right direction, i would appreciate the help. Thanks, Rob Louie

Share this post


Link to post
Share on other sites
Try this:

Add a normal vector to your vertex structure.

somehow set this to [0,0,0] in the beginning

Everytime you calculate the triangle normal, just add the triangle normal to each vertice normal in the triangle.

After you are all done calculating the triangle normals, Normalize the vertex normals. (there is alot of ''normal'' in that sentence)


Hopefully I wrote that clear enough to be understood.

good luck.

Share this post


Link to post
Share on other sites
@mrrolf810p:

>>Everytime you calculate the triangle normal, just add the
>>triangle normal to each vertice normal in the triangle...
>>...After you are all done calculating the triangle normals

mmh, your way/description is not clear to me;
it seems that you are going another way than i:
i''m doing the calculation of the vertex-normals by calculating the "average normal" of all surrounding face normals, this means creating a temp-normal, adding all face-normals from all surrounding face''s, and then creating the average-normal of this, by dividing the temp normal by the number of normals, which have been added this temp-normal.
i haven''t tried out your way - is it the same ? sorry, for this dumb question, it''s really too late now, to talk over such complex things - making a vector "normalized", means in my jargon to "bring it to a length of 1.0"; but if that''s correct, than your way is another one ?! o

DJSnow
-----
this post is manually created and therefore legally valid without a signature

Share this post


Link to post
Share on other sites
Here''s the thing i thought of doing it the way where you find the average normal. The problem i have is finding, in the md2 file, all the faces around each vertex. Because it is all in the file stored a certain way, i am not sure how to get the average of all the surrounding faces for each vertex. That is why i was hoping someone had already done the coding for it. I know how to get the vertex normals, the problem is finding the surrounding faces for each vertex.

Thanks

Share this post


Link to post
Share on other sites
@DJSnow

I''m pretty sure my way and the ''averaging as you go'' technique produce the same results. The normalization at the end does all the the averaging for you. Acutally my way is probably more accurate. Since there isn''t as many divides (only one at the end when you normalize) there is less room for floating point error.

@Liquidus

If you use the way I described, you don''t have to figure out what vertices are shared with what. Here is a little sample/psuedo code to help you out.


for(i=0; i< numVert; i++)
vertList[i].normal = {0,0,0}

for(i=0; i < numTri; i++){
triList[i].normal = SomeFunctionToCalculateTriangleNormals();
triList[i].vert[0]->normal += triList[i].normal
triList[i].vert[1]->normal += triList[i].normal
triList[i].vert[2]->normal += triList[i].normal
}

for(i=0; i< numVert; i++)
vertList[i].normal.Normalize();

Share this post


Link to post
Share on other sites
@liquidus:

>>...here you find the average normal. The problem i have is
>>finding, in the md2 file, all the faces around each vertex.
>>Because it is all in the file stored a certain way...
this is no problem - but it's slow as hell; you could simply loop many times through the vertex array, to find it - BUT: better you use mrrolf810p's way, it seems that this way is really better, but as said below, i'm going to thest it within the next days. and, of course, his way would be faster.


@mrrolf810p:

perhaps we have a small "communication" problem about the word "to normalize" ? my definition of this is, to make an arbitrary vector with the length of 7.34, for example, to a length of 1.0 - is this wrong ?
i don't know, and i can't image, the difference in "real numbers", by thinking over the both different ways.
perhaps i'm going to test it.

>>there isn't as many divides (only one at the end when you
>>normalize) there is less room for floating point error.
yes, this is true, for sure.

apart from that, the lighting done with the normals calculated this way (with my way) looks nice & correct in my demo


DJSnow
-----
this post is manually created and therefore legally valid without a signature


[edited by - DJSnow on August 7, 2003 8:02:50 PM]

[edited by - DJSnow on August 7, 2003 8:03:21 PM]

Share this post


Link to post
Share on other sites
I just don''t understand how that would work. What i see is that you get the triangle surface normal and than simply assign that to each vertex? Or wait, let me see if ive got this. Since each vertex is shared with another triangle, it will add up all the normals of all the shared surfaces in the vertex. Then in the end average it out. It took me a while to get it but now i think i understand. But how do you know how to figure the average. Wouldn''t you have to keep track of how many surfaces the vertex shares. How else can you find the average if you don''t know what to devide by. Maybe if you could show me the Normalize code you use in you example. Have you actually done this, can you confirm for sure that it works? I''m going to just go ahead and try it out. Thanks alot. If this works it is MUCH easier and should be faster and more accurate.

Share this post


Link to post
Share on other sites
Forgive my stupidity, i understand now. It has been a while and i forgot exactly how vector normalization works. You don''t need to know the number because you can find the vectors magnitude from the vector itself. Then use that to normalize it. This looks good. Thanks for the help mrrolf810p

Share this post


Link to post
Share on other sites

void Vector::Normalize(){

float len;
len = (x * x) + (y * y) + (z * z);
len = sqrtf(len);
x = x / len;
y = y / len;
z = z / len;
}


I'm sure my way works. If you want I'll prove it, but I would rather not (too much like school).

Let me know when you get this way working.

[edit]
@Liquidus
No problem.
[/edit]

[edited by - mrrolf810p on August 7, 2003 9:05:03 PM]

Share this post


Link to post
Share on other sites
@luiqidus:

>>Since each vertex is shared with another triangle, it will
>>add up all the normals of all the shared surfaces in the
>>vertex. Then in the end average it out.
yes, that's the way.

>>Wouldn't you have to keep track of how many surfaces the
>>vertex shares.
yes, correct; but since you are using two encapsulated loops, you will have no problem with it.

>>How else can you find the average if you don't know what to
>>devide by.
that's the way that mrrolf810p has explained - and again: it seems that his way is much better !!! so, use his way; apart from that the time to calculate the whole stuff is much shorter with his way, than it is with my way. my way is only a simple hack, which i'm using to get this stuff running.

>>Have you actually done this, can you confirm for sure that it
>>works?
my works, for sure. if any doubts, i can send you .exe file.
and, yes; no doubts that mrrolf810p's works, too.

>>If this works it is MUCH easier and should be faster and more
>>accurate.
yes, it is much easier, much more uncomplicated and much faster.



@mrrolf810p:
>>I'm sure my way works. If you want I'll prove it, but I would
>>rather not (too much like school).
>>Let me know when you get this way working.
yes, i will prove it, within the next days.



@shadow12345:
>>I thought that just by setting the face normal at every
>>vertex you could get goroud shading
>>unless I'm a loser and I missed something
no, you get gouraud shading by supplying three different vertex normals to a triangular polygon.
yes, you missed this little detail - but this don't mean that you are a looser ??!??!



DJSnow
-----
this post is manually created and therefore legally valid without a signature


[edited by - DJSnow on August 8, 2003 11:05:15 AM]

Share this post


Link to post
Share on other sites
ehhh...i have spent the last 3 hours striaght trying to get this to work. I think it is hopeless. The problems is the way the md2 class is programmed, i can''t seem to adapt the vertex normal code to work with it. Has anyone taken the md2 class from the OpenGL Game Programming book and adapted it for gourad shading. If not it is hopeless. Maybe a different MD2 class exists somewhere, one that has smooth shading? Otherwise, i give up. It''s not worth it.

Share this post


Link to post
Share on other sites
where is the problem ?

- load the md2 file
- compute the facenormals
- compute then the vertexnormals

the md2 file format is totally easy. or don''t you come along with the md2 file class itself ? if yes, try another one.


DJSnow
-----
this post is manually created and therefore legally valid without a signature

Share this post


Link to post
Share on other sites
where is the problem ?

- load the md2 file
- compute the facenormals
- compute then the vertexnormals

the md2 file format is totally easy. or don''t you come along with the md2 file class itself ? if yes, try another one.


DJSnow
-----
this post is manually created and therefore legally valid without a signature

Share this post


Link to post
Share on other sites
quote:

no, you get gouraud shading by supplying three different vertex normals to a triangular polygon.


but isn't the normal at each vertex still just the normal of the polygon, just set at each vertex? If the face normal is (0, 1, 0) don't you get gourad shading by setting (0, 1, 0) to every vertex as the normal?

EDIT: Okay, nevermind, now I know that the normal at each vertex is the averaged normals of all of the faces that that particular vertex is a part of, i.e if vertexa is a part of 6 triangles then its normal is those face normals added together (assuming they are normalized already)

[edited by - Shadow12345 on August 10, 2003 10:34:32 AM]

Share this post


Link to post
Share on other sites
The problems is the way the class is written. I think i may have to just write my own from scratch. That shouldn''t be much of a problem, but i''d rather use what i already have. The only way i know of doing it now is if i can loop through every vertex after i load them, but before i display them. Then when i go into the display code simply sepcify normal.1 for the first vertex, normal[i].2 for the second, and normal[i].3 for the third vertex in the triangle. This should work as long as the vertices are drawn in the same order they are loaded, which i''m pretty sure they are. Since my last post i''ve kept thinking of new ideas and i think this one will work the best. Hopefully it will, or i will be rewriting the whole class.

Share this post


Link to post
Share on other sites