Fun with anorms and anorm_dots
Moderator: InsideQC Admins
6 posts
• Page 1 of 1
Fun with anorms and anorm_dots
Trying to figure out how the vertex normals table relates to the precomputed dot products table. I know that the dot products table is precomputed from the DotProduct of the vertex normal and another vector, but what is that vector and how is it derived?
So far a dive into the software Quake code gives me this:
Which is all fine and dandy, but when I take the next step of DotProduct (r_avertexnormals[verts->lightnormalindex], r_plightvec) (again taken from software Quake) the end result is nothing like what's contained in the anorm_dots table!
Now, I know that software Quake uses a different lighting model for MDLs than GLQuake, but there must be a relationship between the two tables here. What gives?
So far a dive into the software Quake code gives me this:
- Code: Select all
float alias_forward[3], alias_right[3], alias_up[3];
float r_plightvec[3], lightvec[3] = {-1, 0, 0};
ent->angles[0] = -ent->angles[0];
AngleVectors (ent->angles, alias_forward, alias_right, alias_up);
ent->angles[0] = -ent->angles[0];
// rotate the lighting vector into the model's frame of reference
r_plightvec[0] = DotProduct (lightvec, alias_forward);
r_plightvec[1] = -DotProduct (lightvec, alias_right);
r_plightvec[2] = DotProduct (lightvec, alias_up);
Which is all fine and dandy, but when I take the next step of DotProduct (r_avertexnormals[verts->lightnormalindex], r_plightvec) (again taken from software Quake) the end result is nothing like what's contained in the anorm_dots table!
Now, I know that software Quake uses a different lighting model for MDLs than GLQuake, but there must be a relationship between the two tables here. What gives?
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
We knew the words, we knew the score, we knew what we were fighting for
-

mh - Posts: 2292
- Joined: Sat Jan 12, 2008 1:38 am
software quake clamps to ambient light. gl doesn't.
the angle is the light direction, which I assume to be anglevectors(0, -angles_y, 0, lightdir, dontcare dontcare).
16 different precomputed angles for nice low res sudden changes.
fuhquake has 32 graduations instead. you might find a hint there. I don't really remember much more.
the angle is the light direction, which I assume to be anglevectors(0, -angles_y, 0, lightdir, dontcare dontcare).
16 different precomputed angles for nice low res sudden changes.
fuhquake has 32 graduations instead. you might find a hint there. I don't really remember much more.
- Spike
- Posts: 2892
- Joined: Fri Nov 05, 2004 3:12 am
- Location: UK
I went up to 256 in an earlier incarnation of my code, but right now I'm looking to replicate software Quake lighting using shaders. Think I've got most of the algorithm down OK, it's not coming out exact but it's quite close. 1D texture lookups are good for avoiding branching.
Don't need to reconstruct the dots table any more, but it's still technically interesting how they arrived at it.

Don't need to reconstruct the dots table any more, but it's still technically interesting how they arrived at it.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
We knew the words, we knew the score, we knew what we were fighting for
-

mh - Posts: 2292
- Joined: Sat Jan 12, 2008 1:38 am
yeah, creating a duplicate of the dots table isn't useful, nor does it quite match software rendering.
the way I see it, its never going to be exact unless its paletted, which is kinda overkill, most people are more familiar with glquake anyway.
also, a single conditional move instruction isn't a branch anyway, and is likely faster than a memory lookup, though I do wonder which is actually faster and how much by. probably not enough to ever be noticable, lol
the way I see it, its never going to be exact unless its paletted, which is kinda overkill, most people are more familiar with glquake anyway.
also, a single conditional move instruction isn't a branch anyway, and is likely faster than a memory lookup, though I do wonder which is actually faster and how much by. probably not enough to ever be noticable, lol
- Spike
- Posts: 2892
- Joined: Fri Nov 05, 2004 3:12 am
- Location: UK
Spike wrote:yeah, creating a duplicate of the dots table isn't useful, nor does it quite match software rendering.
the way I see it, its never going to be exact unless its paletted, which is kinda overkill, most people are more familiar with glquake anyway.
also, a single conditional move instruction isn't a branch anyway, and is likely faster than a memory lookup, though I do wonder which is actually faster and how much by. probably not enough to ever be noticable, lol
Probably not, it's more about compatibility really.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
We knew the words, we knew the score, we knew what we were fighting for
-

mh - Posts: 2292
- Joined: Sat Jan 12, 2008 1:38 am
- Code: Select all
an = ent->angles[1] / 180 * M_PI;
shadevector[0] = cos (-an);
shadevector[1] = sin (-an);
shadevector[2] = 1;
VectorNormalize (shadevector);
for (i = 0; i < NUMVERTEXNORMALS; i++)
{
float dot = DotProduct (r_avertexnormals[i], shadevector);
// wtf - this reproduces anorm_dots within as reasonable a degree of tolerance as the >= 0 case
if (dot < 0)
lightdots[i] = 1.0f + dot * (13.0f / 44.0f);
else lightdots[i] = 1.0f + dot;
}
Don't ask me about that 13/44 (0.2954545...) - I just played with numbers until I found one that works and got quite a shock when it came out like that.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
We knew the words, we knew the score, we knew what we were fighting for
-

mh - Posts: 2292
- Joined: Sat Jan 12, 2008 1:38 am
6 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 1 guest