OpenArena Message Boards

OpenArena Contributions => Development => Topic started by: revanic on February 22, 2013, 01:42:46 PM



Title: Mostly corrected dynamic light projection
Post by: revanic on February 22, 2013, 01:42:46 PM
Well, I was working on trying to fix up dynamic lighting for my own Id Tech 3 based game, and I managed to figure out this much. This code is not 100% perfect, and can bug up on some surfaces, usually curves. I can't really figure out how to completely perfect it, but its good enough for now, I guess.

Code:
for ( i = 0 ; i < input->numVertexes ; i++, texCoords += 2, colors += 4) {
vec3_t dist;
vec3_t projectionAxis[3];
float attenuation;
float texCoordScale;
int clip;

backEnd.pc.c_dlightVertexes++;

//Corrected projection
VectorSubtract(input->xyz[i], origin, dist);
VectorNormalize2( input->normal[i], projectionAxis[0] );
MakeNormalVectors( input->normal[i], projectionAxis[1], projectionAxis[2] );

attenuation = DotProduct(dist, projectionAxis[0]);
attenuation = Q_fabs(attenuation);

texCoordScale = 0.5 * scale;

texCoords[0] = 0.5f + (DotProduct(dist, projectionAxis[1])*texCoordScale);
texCoords[1] = 0.5f + (DotProduct(dist, projectionAxis[2])*texCoordScale);

... skippin thru code...

                       
Code:
// modulate the strength based on the distance and color

if ( attenuation > radius ) {
clip |= 16;
modulate = 0.0f;
} else {
modulate = 1.0f  * (radius - attenuation) * scale;

if(modulate > 1.0f)
modulate = 1.0f;

if(modulate <= 0){
modulate = 0.0f;
clip |= 32;
}
}

as I said its not completely perfect, if you can find a way to perfect it, it would be a great help. Obviously you can use this :P
ALSO it can be used in the environment map code to correct the projection there as well.

OH, ALMOST FORGOT
in tr_world.c, r_recursiveworldnode

/
Code:
/ determine which dlights are needed
newDlights[0] = 0;
newDlights[1] = 0;
if ( dlightBits ) {
int i;

for ( i = 0 ; i < tr.refdef.num_dlights ; i++ ) {
dlight_t *dl;
float dist;

if ( dlightBits & ( 1 << i ) ) {
dl = &tr.refdef.dlights[i];
dist = DotProduct( dl->origin, node->plane->normal ) - node->plane->dist;

if ( dist > -dl->radius ) {
newDlights[0] |= ( 1 << i );
}
if ( dist < dl->radius ) {
newDlights[1] |= ( 1 << i );
}
}
}
}
This code here just bugs up and causes dynamic lights to flicker on surfaces, or just not light them sometimes. So comment it out or remove it. I believe I discovered this through RtcW's code.

edit: and I forgot to mention that q3's dynamic lights are actualy 2x bigger than what they seem, this new code brings the edge of the dynamic light right to the edge of the radius which is why they seem so much bigger with this code.


Title: Re: Mostly corrected dynamic light projection
Post by: GrosBedo on February 24, 2013, 12:09:56 PM
One cake for this great work!


Title: Re: Mostly corrected dynamic light projection
Post by: revanic on February 24, 2013, 08:13:49 PM
You're welcome :). Also I forgot to mention that if you use similar code for the environment maps, be sure to make it specifically affect only world brush models, 3d models with env maps will look VERY weird with this current code.