#123868 - 3D_geek - Sun Apr 01, 2007 12:51 am
I've just started to play with lighting for 3D graphics - and I can't get ANYTHING to work. So I looked at the trusty 'nds-examples-20070127.tar' bundle to see what the example programs do. Several of the NeHe demos and one or two of the Misc demos seem to turn on 3D light sources, they set the light attribute on the glPolyFmt call and provide normals for simple things like cubes and such - so I presume we have (at least at some stage) gotten lighting working.
However, when I run those demos - none of them seem to show any kind of 3D lighting effect at all! Well - this perhaps explains why I'm having no luck!
So - starting at the beginning - do I have good vertex normals?
Well all of the examples have things like:
...as the normals for the six faces of a simple cube. NORMAL_PACK says:
And inttov10 (and floattov10) say:
So I deduce that there are 10 bits for each component of the normal - packed into a 30 bit word...but hold on - normals are signed quantities?! According to the hardware bible: http://nocash.emubase.de/gbatek.htm#ds3dpolygondefinitionsbyvertices ...we are required to provide:
Oh - oh. That's not what libnds does!
If we take a number like 1 or 1.0f (as used in ALL of the cube examples) and hand it to inttov10 or floattov10, we'll get 0x200. But that's '-0' in the DS's sign-and-magnitude setup! On the other hand, if I hand a -1 to inttov10, it'll hand me back 0xfffffe00 - which NORMAL_PACK will chop down to 10 bits by ANDing it with 0x3FF - which leaves me with 0x200 again!!! No wonder none of these programs can light up a simple cube - all of the surface normals are (0,-0,0), (-0,0,0) or (0,0,-0)...basically...Zero!!! Since (0,0,0) is not of length 1, it's not a valid normal...who knows what the hardware does with that junk?!
So none of the example programs have good normals! They can't ever have had proper lighting working?!?
There seems to be a similar problem in the packing of texture coordinates - same deal. with sign-and-magnitude representations. The difference here is that the error is less noticable because relatively few models use negative or maximum-possible-value texture coordinates.
Has any of this stuff ever been used for real? Didn't anyone ever think to worry about why none of the lighting works in any of the stock examples?
When I fix this problem in my own code - I still don't get any 3D lighting - but since it appears that nobod tested this stuff properly - that's not really a surprise!
However, when I run those demos - none of them seem to show any kind of 3D lighting effect at all! Well - this perhaps explains why I'm having no luck!
So - starting at the beginning - do I have good vertex normals?
Well all of the examples have things like:
Code: |
NORMAL_PACK(0,inttov10(-1),0), NORMAL_PACK(0,inttov10(1),0), NORMAL_PACK(inttov10(1),0,0), NORMAL_PACK(0,0,inttov10(-1)), NORMAL_PACK(inttov10(-1),0,0), NORMAL_PACK(0,inttov10(1),0) |
...as the normals for the six faces of a simple cube. NORMAL_PACK says:
Code: |
#define NORMAL_PACK(x,y,z) (((x) & 0x3FF) | (((y) & 0x3FF) << 10) | ((z) << 20)) |
And inttov10 (and floattov10) say:
Code: |
#define inttov10(n) ((n) << 9) #define floattov10(n) ((v10)((n) * (1 << 9))) |
So I deduce that there are 10 bits for each component of the normal - packed into a 30 bit word...but hold on - normals are signed quantities?! According to the hardware bible: http://nocash.emubase.de/gbatek.htm#ds3dpolygondefinitionsbyvertices ...we are required to provide:
Quote: |
4000484h - Cmd 21h - NORMAL - Set Normal Vector (W) 0- 9 X-Component of Normal Vector (1bit sign + 9bit fractional part) 10-19 Y-Component of Normal Vector (1bit sign + 9bit fractional part) 20-29 Z-Component of Normal Vector (1bit sign + 9bit fractional part) 30-31 Not used |
Oh - oh. That's not what libnds does!
If we take a number like 1 or 1.0f (as used in ALL of the cube examples) and hand it to inttov10 or floattov10, we'll get 0x200. But that's '-0' in the DS's sign-and-magnitude setup! On the other hand, if I hand a -1 to inttov10, it'll hand me back 0xfffffe00 - which NORMAL_PACK will chop down to 10 bits by ANDing it with 0x3FF - which leaves me with 0x200 again!!! No wonder none of these programs can light up a simple cube - all of the surface normals are (0,-0,0), (-0,0,0) or (0,0,-0)...basically...Zero!!! Since (0,0,0) is not of length 1, it's not a valid normal...who knows what the hardware does with that junk?!
So none of the example programs have good normals! They can't ever have had proper lighting working?!?
There seems to be a similar problem in the packing of texture coordinates - same deal. with sign-and-magnitude representations. The difference here is that the error is less noticable because relatively few models use negative or maximum-possible-value texture coordinates.
Has any of this stuff ever been used for real? Didn't anyone ever think to worry about why none of the lighting works in any of the stock examples?
When I fix this problem in my own code - I still don't get any 3D lighting - but since it appears that nobod tested this stuff properly - that's not really a surprise!