Jump to content
  • Advertisement
Sign in to follow this  
skyfire360

Maya, Per-vertex Normals and Tangent Space

This topic is 4604 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

Heya! I'm writing an exporter for Maya, and I'm trying to wrap my head around the way it generates normals. As far as I can tell, the Maya API's MFnMesh class outputs per-polygon per-vertex normals. This wording is somewhat strange to me... is it per-vertex, or per-polygon? If we take the documentation literally, each triangle - for the sake of simplicity - will have three vertex normals. All points on a triangle will always lie on the same plane, so won't their normals all be the same anyway? Per-vertex normals (averaged of all adjacent faces) do the equivalent of GL_NORMALIZE for smoother lighting. Is there any way to get these normals from Maya, preferably indexed? Another, somewhat related question: For a specific shader I'm going to write, I will require that per-pixel calculations be done in tangent-space. Do the normals I use in these calculations need to be perpendicular to the face of the polygon? Or can tangent-space somehow be calculated for the averaged per-vertex normals instead of the per-face normals? P.S. I can understand if my post is confusing. Please let me know if I need to be clearer!

Share this post


Link to post
Share on other sites
Advertisement
About the second question I don't know: I would like to implement bump mapping and I'm looking for tangent space infos myself ;-)

For the first: you are lucky: 3ds doesn't even save normals in the 3ds file :-( In order to have smooth normals (i.e. for gouraud shading) you have to average the normals of the triangles: that is you loop throught your vertices, sum the normals of the triangles sharing them, and the divide each computed normal by 3:
I use the following function (you will need to adpt it for your needs):

bool Loader3DS::SmoothNormals(unsigned int nfaces, unsigned short int *faces, float *vertices, float* normals)
{

if(!faces || ! vertices || ! normals) return false;

//First calculate the faces normals
float* temp = new float[nfaces*3];
if(!temp) return false;
FlatNormals(nfaces, faces, vertices, temp);

//Now calculate the smoothed normals
float n[3];
int c = 0;
float len = 0.0;
for(int i = 0; i < nfaces * 3; i++)
{
c = 0;
n[0] = n[1] = n[2] = 0.0;
for(int j = 0; j < nfaces; j++)
{
if(faces[j*3] == i || faces[j*3+1] == i || faces[j*3+2] == i)
{
n[0] += temp[j*3];
n[1] += temp[j*3+1];
n[2] += temp[j*3+2];
++c;
}
}
if(c != 0) //Take the average of the normals
{
n[0] /= c;
n[1] /= c;
n[2] /= c;
len = sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);

normals[i*3] = n[0] / len;
normals[i*3+1] = n[1] / len;
normals[i*3+2] = n[2] / len;
}
}
delete temp;
return true;
}


Note that since when I call this function I don't have per face normals, I need to calculate them. Your code will be much easier than this, I suppose, but perhaps you can get something working from this.

Share this post


Link to post
Share on other sites
@cignox:
he's talking about maya..not 3dsMax.

@OP:
Quote:

All points on a triangle will always lie on the same plane, so won't their normals all be the same anyway?


i think maya needs that to be able to adjust the normal smoothness. In maya you can adjust the normal softness from 0 -180. I think with 1 normal per vertex you cannot get that.

Quote:

Is there any way to get these normals from Maya, preferably indexed?

in my exporter i was too lazy to export notmals...i calculate them at loadtime in my engine.(because it was a pain to export uvs so i didn't want to have the same chaos again with normals) But have you tried rob-the-blokes homepage? he has some really nice tutorials on how to write a maya exporter...

regards,
m4gnus

Share this post


Link to post
Share on other sites
Quote:
Original post by m4gnus
@cignox:
he's talking about maya..not 3dsMax.



Yep, I know that. I just wanted to point out that he was lucky to have the normals in the file, while with other formats these have to be computed.
Anyway, the code I posted should work with some changes: in the code I compute the normals, while the op already has them.

Share this post


Link to post
Share on other sites
In 3dsmax, a every triangle can have 3 seperate normals. To export these correctly, you have to duplicate some coordinates just like with UV's.
Here's a link that works for exporting UV's, but you can easily alter it to work for normals:
http://www.mindcontrol.org/~hplus/graphics/vertex-arrays.html

Calculating the normals at runtime isn't always a viable solution. In a modelling package, the normals can be flipped for some objects etc... So only exporting them will produce correct results.
If I remember right, the IGame exporter library for 3dsmax contains a function to generate a flat vertex array for the normals of any pologonal model.
Mind that if you want ultra-accurate results, you should export the normals using the code above in conjunction with reconstructing the normals through smooth-group traversion.

Share this post


Link to post
Share on other sites
Thanks for the replies all

Looks like I'm going to have to calculate them myself. Not a problem, really, but it'll most likely be an indexing nightmare to re-index normals, binormals and tangents...

...apparently not! As I wrote this I finally found the MFnMesh::getVertexNormal function, which apparently "calculated by Maya upon request as the average of all the per-polygon normals for the polygons adjacent to the vertex." Sweet, saves me a lot of work :)

@Cignox1

Check out this website. It's got some good info on tangent/binormal generation.

Share this post


Link to post
Share on other sites
Quote:
Original post by skyfire360
...

@Cignox1

Check out this website. It's got some good info on tangent/binormal generation.


Thank you, I already got it: in fact, I was just going to read it ;-)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!