Lighting Normals

From en64 wiki
Jump to navigation Jump to search

Ocarina of Time Lighting Normals

wareya's notes:

AT LEAST IN THE DEBUG ROM, the following is true:

Normals take the format of XX YY ZZ NN, where each digit is a nibble.

NN seems to be unused.

Each byte is a sighed 8-bit integer. 7F is maximal, 80 is minimal.

Normals are not normalized. 01 00 00 is the same thing as 7F 00 00. **

X is the east-west axis. Positive is east.

Y is the vertical axis. Positive is up.

Z is the south-east axis. Positive is south. (where the sun tilts)

Directions indicate which direction a face with a correct normal is facing, visible from, etc. For example, "up" is brighter when the sun is directly overhead. "Up" normals are used for the ground.


** This is slightly weird, can someone who can actually run a pixel-accurate graphics plugin please confirm?

The microcode instruction that controls whether normals are enabled:

D9-X ---- --YZ ----
x: bit 2 turns RGB on
Y: bit 3 makes normal mode dark?
Z: bit 2 turns normal mode on

No idea what the others do.

EDIT: Glide64 does the following

FF FFFF
0000 0000    0000 0000 0000 0000
 ||   ||           ||        | `zbuffer
 ||   `+Fuck up HLE||        `Face normals lighting (as RGB?)
 ||    |if next is |`Frontface culling
 ||    |set        `Backface culling
 ||    `Vertex normal lighting
 |`RGB lighting
 `Darken shit if Vertex Normal Lighting is set


on a transparent texture (water).

Map data basically does this:
D9FCFFFF 00000000
D9FFFFFF 00030000
D9F3FFFF 00000000
D9FFFFFF 00030400


D9F1FFFF 00000000
D9FFFFFF 00010400
D9FFFBFF 00000000
D9FFFFFF 00000400

Certain flags are of the kind that get turned on in the first half and either off or overridden in the second half. I don't really understand it.

                case 0xD9:
                    //puts("mode");
                    {
                        bool filterclear = ((0x00200000&mem32(index  )) != 0);
                        bool normalclear = ((0x00020000&mem32(index  )) != 0);
                        bool filterenset = ((0x00200000&mem32(index+4)) != 0);
                        bool normalenset = ((0x00020000&mem32(index+4)) != 0);
                        
                        filter = filterenset|(filter&filterclear);
                        normal = normalenset|(normal&normalclear);
                        
                        if(normal)
                        {
                            normalize = true;
                            glEnable(GL_LIGHTING);
                        }
                        else if(filter)
                        {
                            normalize = false;
                            glDisable(GL_LIGHTING);
                        }
                    }



"filter" and "normal" persist between displaylist jumps (DE). Don't know if they persist between core displaylists (mesh header displaylist list), but they probably don't, and if they do, nothing seems to reaalllly depend on it.

"Normal" takes precedence over "filter". "Filter" means multiply shading lighting, or in other words, RGB blending.

a normal of (0,0,0) corresponds to (0,0,-1)