Forum

Fun with anorms and anorm_dots

Discuss programming topics for the various GPL'd game engine sources.

Moderator: InsideQC Admins

Fun with anorms and anorm_dots

Postby mh » Mon Feb 14, 2011 7:49 pm

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:
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
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby Spike » Mon Feb 14, 2011 9:15 pm

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.
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Postby mh » Mon Feb 14, 2011 10:45 pm

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. :? :?:
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
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby Spike » Tue Feb 15, 2011 1:33 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
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Postby mh » Tue Feb 15, 2011 2:03 pm

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
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby mh » Wed Aug 31, 2011 7:32 pm

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;
   }


:D :D :D

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
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am


Return to Engine Programming

Who is online

Users browsing this forum: No registered users and 1 guest