Increase the influence of directional lights on the deluxemap by a)Ignoring angle attenuation for directional contribution and b)Scaling down by 1/4 the contribution of radiosity (deeper explanation in a comment at LightContributionToSample).

This commit is contained in:
jal 2010-04-30 11:32:11 +02:00
parent 36e9024e86
commit be4e243888
6 changed files with 123 additions and 36 deletions

View File

@ -77,6 +77,8 @@ extern const vec3_t g_vec3_axis_z;
#define FLOAT_SNAP(f,snap) ( (float)( floor( (f) / (snap) + 0.5 ) * (snap) ) )
#define FLOAT_TO_INTEGER(f) ( (float)( floor( (f) + 0.5 ) ) )
#define RGBTOGRAY(x) ( (x)[0] * 0.2989f + (x)[1] * 0.5870f + (x)[2] * 0.1140f )
#define Q_rint(in) ((vec_t)floor(in+0.5))
qboolean VectorCompare (const vec3_t v1, const vec3_t v2);

View File

@ -749,7 +749,9 @@ int LightContributionToSample( trace_t *trace )
float angle;
float add;
float dist;
float addDeluxe = 0.0f, addDeluxeBounceScale = 0.25f;
qboolean angledDeluxe = qfalse;
float colorBrightness;
/* get light */
light = trace->light;
@ -757,6 +759,9 @@ int LightContributionToSample( trace_t *trace )
/* clear color */
VectorClear( trace->color );
VectorClear( trace->colorNoShadow );
VectorClear( trace->directionContribution );
colorBrightness = RGBTOGRAY( light->color ) * ( 1.0f/255.0f );
/* ydnar: early out */
if( !(light->flags & LIGHT_SURFACES) || light->envelope <= 0.0f )
@ -796,7 +801,7 @@ int LightContributionToSample( trace_t *trace )
}
/* nudge the point so that it is clearly forward of the light */
/* so that surfaces meeting a light emiter don't get black edges */
/* so that surfaces meeting a light emitter don't get black edges */
if( d > -8.0f && d < 8.0f )
VectorMA( trace->origin, (8.0f - d), light->normal, pushedOrigin );
else
@ -832,6 +837,14 @@ int LightContributionToSample( trace_t *trace )
dist = 16.0f;
add = light->photons / (dist * dist) * angle;
if( deluxemap )
{
if( angledDeluxe )
addDeluxe = light->photons / (dist * dist) * angle;
else
addDeluxe = light->photons / (dist * dist);
}
}
else
{
@ -858,6 +871,9 @@ int LightContributionToSample( trace_t *trace )
/* ydnar: moved to here */
add = factor * light->add;
if( deluxemap )
addDeluxe = add;
}
}
@ -916,9 +932,35 @@ int LightContributionToSample( trace_t *trace )
add = angle * light->photons * linearScale - (dist * light->fade);
if( add < 0.0f )
add = 0.0f;
if( deluxemap )
{
if( angledDeluxe )
addDeluxe = angle * light->photons * linearScale - (dist * light->fade);
else
addDeluxe = light->photons * linearScale - (dist * light->fade);
if( addDeluxe < 0.0f )
addDeluxe = 0.0f;
}
}
else
{
add = (light->photons / (dist * dist)) * angle;
if( add < 0.0f )
add = 0.0f;
if( deluxemap )
{
if( angledDeluxe )
addDeluxe = (light->photons / (dist * dist)) * angle;
else
addDeluxe = (light->photons / (dist * dist));
}
if( addDeluxe < 0.0f )
addDeluxe = 0.0f;
}
/* handle spotlights */
if( light->type == EMIT_SPOT )
@ -941,7 +983,16 @@ int LightContributionToSample( trace_t *trace )
/* attenuate */
if( sampleRadius > (radiusAtDist - 32.0f) )
{
add *= ((radiusAtDist - sampleRadius) / 32.0f);
if( add < 0.0f )
add = 0.0f;
addDeluxe *= ((radiusAtDist - sampleRadius) / 32.0f);
if( addDeluxe < 0.0f )
addDeluxe = 0.0f;
}
}
}
@ -982,12 +1033,35 @@ int LightContributionToSample( trace_t *trace )
/* attenuate */
add = light->photons * angle;
if( deluxemap )
{
if( angledDeluxe )
addDeluxe = light->photons * angle;
else
addDeluxe = light->photons;
if( addDeluxe < 0.0f )
addDeluxe = 0.0f;
}
if( add <= 0.0f )
return 0;
/* VorteX: set noShadow color */
VectorScale(light->color, add, trace->colorNoShadow);
addDeluxe *= colorBrightness;
if( bouncing )
{
addDeluxe *= addDeluxeBounceScale;
if( addDeluxe < 0.00390625f )
addDeluxe = 0.00390625f;
}
VectorScale( trace->direction, addDeluxe, trace->directionContribution );
/* setup trace */
trace->testAll = qtrue;
VectorScale( light->color, add, trace->color );
@ -1000,6 +1074,8 @@ int LightContributionToSample( trace_t *trace )
if( !(trace->compileFlags & C_SKY) || trace->opaque )
{
VectorClear( trace->color );
VectorClear( trace->directionContribution );
return -1;
}
}
@ -1015,6 +1091,29 @@ int LightContributionToSample( trace_t *trace )
if( add <= 0.0f || (add <= light->falloffTolerance && (light->flags & LIGHT_FAST_ACTUAL)) )
return 0;
addDeluxe *= colorBrightness;
/* hack land: scale down the radiosity contribution to light directionality.
Deluxemaps fusion many light directions into one. In a rtl process all lights
would contribute individually to the bump map, so several light sources together
would make it more directional (example: a yellow and red lights received from
opposing sides would light one side in red and the other in blue, adding
the effect of 2 directions applied. In the deluxemapping case, this 2 lights would
neutralize each other making it look like having no direction.
Same thing happens with radiosity. In deluxemapping case the radiosity contribution
is modifying the direction applied from directional lights, making it go closer and closer
to the surface normal the bigger is the amount of radiosity received.
So, for preserving the directional lights contributions, we scale down the radiosity
contribution. It's a hack, but there's a reason behind it */
if( bouncing )
{
addDeluxe *= addDeluxeBounceScale;
if( addDeluxe < 0.00390625f )
addDeluxe = 0.00390625f;
}
VectorScale( trace->direction, addDeluxe, trace->directionContribution );
/* setup trace */
trace->testAll = qfalse;
VectorScale( light->color, add, trace->color );
@ -1024,6 +1123,8 @@ int LightContributionToSample( trace_t *trace )
if( trace->passSolid || trace->opaque )
{
VectorClear( trace->color );
VectorClear( trace->directionContribution );
return -1;
}

View File

@ -2006,11 +2006,12 @@ void IlluminateRawLightmap( int rawLightmapNum )
VectorCopy( ambientColor, luxel );
if( deluxemap )
{
brightness = ambientColor[ 0 ] * 0.3f + ambientColor[ 1 ] * 0.59f + ambientColor[ 2 ] * 0.11f;
brightness *= (1.0 / 255.0);
brightness = RGBTOGRAY( ambientColor ) * ( 1.0f/255.0f );
// use AT LEAST this amount of contribution from ambient for the deluxemap, fixes points that receive ZERO light
if(brightness < 0.00390625f)
brightness = 0.00390625f;
VectorScale( normal, brightness, deluxel );
}
luxel[ 3 ] = 1.0f;
@ -2094,23 +2095,14 @@ void IlluminateRawLightmap( int rawLightmapNum )
LightContributionToSample( &trace );
VectorCopy( trace.color, lightLuxel );
/* add the contribution to the deluxemap */
if( deluxemap )
VectorAdd( deluxel, trace.directionContribution, deluxel );
/* add to count */
if( trace.color[ 0 ] || trace.color[ 1 ] || trace.color[ 2 ] )
totalLighted++;
}
/* add to light direction map (fixme: use luxel normal as starting point for deluxel?) */
if( deluxemap )
{
if(DotProduct(normal, trace.direction) > 0) // do not take light from the back side
{
/* color to grayscale (photoshop rgb weighting) */
brightness = trace.colorNoShadow[ 0 ] * 0.3f + trace.colorNoShadow[ 1 ] * 0.59f + trace.colorNoShadow[ 2 ] * 0.11f;
brightness *= (1.0 / 255.0);
VectorScale( trace.direction, brightness, trace.direction );
VectorAdd( deluxel, trace.direction, deluxel );
}
}
}
}
@ -2442,6 +2434,7 @@ void IlluminateRawLightmap( int rawLightmapNum )
if( *cluster < 0 ||
(lm->splotchFix && (luxel[ 0 ] <= ambientColor[ 0 ] || luxel[ 1 ] <= ambientColor[ 1 ] || luxel[ 2 ] <= ambientColor[ 2 ])) )
filterColor = qtrue;
if( deluxemap && lightmapNum == 0 && (*cluster < 0 || filter) )
filterDir = qtrue;
@ -4194,8 +4187,7 @@ void FloodlightIlluminateLightmap( rawLightmap_t *lm )
vec3_t lightvector;
normal = SUPER_NORMAL( x, y );
brightness = floodlight[ 0 ] * 0.3f + floodlight[ 1 ] * 0.59f + floodlight[ 2 ] * 0.11f;
brightness *= ( 1.0f / 255.0f ) * floodlight[3];
brightness = RGBTOGRAY( floodlight ) * ( 1.0f/255.0f ) * floodlight[3];
// use AT LEAST this amount of contribution from ambient for the deluxemap, fixes points that receive ZERO light
if(brightness < 0.00390625f)

View File

@ -1921,7 +1921,7 @@ for a given surface lightmap, find output lightmap pages and positions for it
#define LIGHTMAP_RESERVE_COUNT 1
static void FindOutLightmaps( rawLightmap_t *lm )
{
int i, j, k, lightmapNum, xMax, yMax, x, y, sx, sy, ox, oy, offset, temp;
int i, j, k, lightmapNum, xMax, yMax, x, y, sx, sy, ox, oy, offset;
outLightmap_t *olm;
surfaceInfo_t *info;
float *luxel, *deluxel;
@ -2193,21 +2193,12 @@ static void FindOutLightmaps( rawLightmap_t *lm )
if( deluxemap )
{
/* normalize average light direction */
if( VectorNormalize( deluxel, direction ) )
{
/* encode [-1,1] in [0,255] */
pixel = olm->bspDirBytes + (((oy * olm->customWidth) + ox) * 3);
VectorScale( deluxel, 1000.0f, direction );
VectorNormalize( direction, direction );
VectorScale( direction, 127.5f, direction );
for( i = 0; i < 3; i++ )
{
temp = (direction[ i ] + 1.0f) * 127.5f;
if( temp < 0 )
pixel[ i ] = 0;
else if( temp > 255 )
pixel[ i ] = 255;
else
pixel[ i ] = temp;
}
}
pixel[ i ] = (byte)( 127.5f + direction[ i ] );
}
}
}

View File

@ -401,7 +401,7 @@ void InsertModel( char *name, int frame, m4x4_t transform, remap_t *remap, shade
dv->color[ j ][ 0 ] = 255.0f;
dv->color[ j ][ 1 ] = 255.0f;
dv->color[ j ][ 2 ] = 255.0f;
dv->color[ j ][ 3 ] = color[ 0 ] * 0.3f + color[ 1 ] * 0.59f + color[ 2 ] * 0.11f;
dv->color[ j ][ 3 ] = RGBTOGRAY( color );
}
else
{

View File

@ -1351,6 +1351,7 @@ typedef struct
/* input and output */
vec3_t color; /* starts out at full color, may be reduced if transparent surfaces are crossed */
vec3_t colorNoShadow; /* result color with no shadow casting */
vec3_t directionContribution; /* result contribution to the deluxe map */
/* output */
vec3_t hit;