#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);
float angle;
float add;
float dist;
-
+ float addDeluxe = 0.0f, addDeluxeBounceScale = 0.25f;\r
+ qboolean angledDeluxe = qfalse;\r
+ float colorBrightness;
/* get light */
light = trace->light;
/* clear color */
VectorClear( trace->color );
VectorClear( trace->colorNoShadow );
+ VectorClear( trace->directionContribution );\r
+\r
+ colorBrightness = RGBTOGRAY( light->color ) * ( 1.0f/255.0f );
/* ydnar: early out */
if( !(light->flags & LIGHT_SURFACES) || light->envelope <= 0.0f )
}
/* 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
dist = 16.0f;
add = light->photons / (dist * dist) * angle;
+
+ if( deluxemap )\r
+ {\r
+ if( angledDeluxe )\r
+ addDeluxe = light->photons / (dist * dist) * angle;\r
+ else\r
+ addDeluxe = light->photons / (dist * dist);\r
+ }
}
else
{
/* ydnar: moved to here */
add = factor * light->add;
+
+ if( deluxemap )\r
+ addDeluxe = add;
}
}
add = angle * light->photons * linearScale - (dist * light->fade);
if( add < 0.0f )
add = 0.0f;
+
+ if( deluxemap )\r
+ {\r
+ if( angledDeluxe )\r
+ addDeluxe = angle * light->photons * linearScale - (dist * light->fade);\r
+ else\r
+ addDeluxe = light->photons * linearScale - (dist * light->fade);\r
+\r
+ if( addDeluxe < 0.0f )\r
+ addDeluxe = 0.0f;\r
+ }
}
else
+ {
add = (light->photons / (dist * dist)) * angle;
+ if( add < 0.0f )\r
+ add = 0.0f;\r
+\r
+ if( deluxemap )\r
+ {\r
+ if( angledDeluxe )\r
+ addDeluxe = (light->photons / (dist * dist)) * angle;\r
+ else\r
+ addDeluxe = (light->photons / (dist * dist));\r
+ }\r
+\r
+ if( addDeluxe < 0.0f )\r
+ addDeluxe = 0.0f;
+ }
/* handle spotlights */
if( light->type == EMIT_SPOT )
/* attenuate */
if( sampleRadius > (radiusAtDist - 32.0f) )
+ {
add *= ((radiusAtDist - sampleRadius) / 32.0f);
+ if( add < 0.0f )\r
+ add = 0.0f;\r
+\r
+ addDeluxe *= ((radiusAtDist - sampleRadius) / 32.0f);\r
+\r
+ if( addDeluxe < 0.0f )\r
+ addDeluxe = 0.0f;
+ }
}
}
/* attenuate */
add = light->photons * angle;
+
+ if( deluxemap )\r
+ {\r
+ if( angledDeluxe )\r
+ addDeluxe = light->photons * angle;\r
+ else\r
+ addDeluxe = light->photons;\r
+\r
+ if( addDeluxe < 0.0f )\r
+ addDeluxe = 0.0f;\r
+ }
+
if( add <= 0.0f )
return 0;
/* VorteX: set noShadow color */
VectorScale(light->color, add, trace->colorNoShadow);
+
+ addDeluxe *= colorBrightness;\r
+\r
+ if( bouncing )\r
+ {\r
+ addDeluxe *= addDeluxeBounceScale;\r
+ if( addDeluxe < 0.00390625f )\r
+ addDeluxe = 0.00390625f;\r
+ }\r
+\r
+ VectorScale( trace->direction, addDeluxe, trace->directionContribution );
/* setup trace */
trace->testAll = qtrue;
if( !(trace->compileFlags & C_SKY) || trace->opaque )
{
VectorClear( trace->color );
+ VectorClear( trace->directionContribution );
+
return -1;
}
}
/* ydnar: changed to a variable number */
if( add <= 0.0f || (add <= light->falloffTolerance && (light->flags & LIGHT_FAST_ACTUAL)) )
return 0;
+
+ addDeluxe *= colorBrightness;\r
+\r
+ /* hack land: scale down the radiosity contribution to light directionality.\r
+ Deluxemaps fusion many light directions into one. In a rtl process all lights\r
+ would contribute individually to the bump map, so several light sources together\r
+ would make it more directional (example: a yellow and red lights received from\r
+ opposing sides would light one side in red and the other in blue, adding\r
+ the effect of 2 directions applied. In the deluxemapping case, this 2 lights would\r
+ neutralize each other making it look like having no direction.\r
+ Same thing happens with radiosity. In deluxemapping case the radiosity contribution\r
+ is modifying the direction applied from directional lights, making it go closer and closer\r
+ to the surface normal the bigger is the amount of radiosity received.\r
+ So, for preserving the directional lights contributions, we scale down the radiosity\r
+ contribution. It's a hack, but there's a reason behind it */\r
+ if( bouncing )\r
+ {\r
+ addDeluxe *= addDeluxeBounceScale;\r
+ if( addDeluxe < 0.00390625f )\r
+ addDeluxe = 0.00390625f;\r
+ }\r
+\r
+ VectorScale( trace->direction, addDeluxe, trace->directionContribution );
/* setup trace */
trace->testAll = qfalse;
if( trace->passSolid || trace->opaque )
{
VectorClear( trace->color );
+ VectorClear( trace->directionContribution );\r
+
return -1;
}
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;
LightContributionToSample( &trace );
VectorCopy( trace.color, lightLuxel );
+ /* add the contribution to the deluxemap */\r
+ if( deluxemap )\r
+ 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 );
- }
- }
}
}
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;
vec3_t lightvector;\r
\r
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];\r
+ brightness = RGBTOGRAY( floodlight ) * ( 1.0f/255.0f ) * floodlight[3];\r
\r
// use AT LEAST this amount of contribution from ambient for the deluxemap, fixes points that receive ZERO light\r
if(brightness < 0.00390625f)\r
#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;
if( deluxemap )
{
/* normalize average light direction */
- if( VectorNormalize( deluxel, direction ) )
- {
- /* encode [-1,1] in [0,255] */
- pixel = olm->bspDirBytes + (((oy * olm->customWidth) + ox) * 3);
- 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 = olm->bspDirBytes + (((oy * olm->customWidth) + ox) * 3);\r
+ VectorScale( deluxel, 1000.0f, direction );\r
+ VectorNormalize( direction, direction );\r
+ VectorScale( direction, 127.5f, direction );\r
+ for( i = 0; i < 3; i++ )\r
+ pixel[ i ] = (byte)( 127.5f + direction[ i ] );
}
}
}
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
{
/* 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;