VectorCopy( trace->normal, normal );
/* check if the normal is aligned to the world-up */
- if( normal[ 0 ] == 0.0f && normal[ 1 ] == 0.0f )
+ if( normal[ 0 ] == 0.0f && normal[ 1 ] == 0.0f && ( normal[ 2 ] == 1.0f || normal[ 2 ] == -1.0f ) )
{
if( normal[ 2 ] == 1.0f )
{
rawLightmap_t *lm;
surfaceInfo_t *info;
trace_t trace;
-
+ qboolean noDirty;
+
/* bail if this number exceeds the number of raw lightmaps */
if( rawLightmapNum >= numRawLightmaps )
break;
}
}
+
+ noDirty = qfalse;
+ for( i = 0; i < trace.numSurfaces; i++ )
+ {
+ /* get surface */
+ info = &surfaceInfos[ trace.surfaces[ i ] ];
+
+ /* check twosidedness */
+ if( info->si->noDirty )
+ {
+ noDirty = qtrue;
+ break;
+ }
+ }
/* gather dirt */
for( y = 0; y < lm->sh; y++ )
/* only look at mapped luxels */
if( *cluster < 0 )
continue;
+
+ /* don't apply dirty on this surface */
+ if( noDirty )
+ {
+ *dirt = 1.0f;
+ continue;
+ }
/* copy to trace */
trace.cluster = *cluster;
/* sample light */
LightContributionToSample( trace );
+ if(trace->forceSubsampling > 1.0f)
+ {
+ /* alphashadow: we subsample as deep as we can */
+ ++lighted;
+ ++mapped;
+ ++mapped;
+ }
/* add to totals (fixme: make contrast function) */
VectorCopy( trace->color, luxel[ b ] );
{
if( cluster[ b ] < 0 )
continue;
- SubsampleRawLuxel_r( lm, trace, origin[ b ], x, y, (bias * 0.25f), luxel[ b ] );
+ SubsampleRawLuxel_r( lm, trace, origin[ b ], x, y, (bias * 0.5f), luxel[ b ] );
}
}
qboolean filterColor, filterDir;
float brightness;
float *origin, *normal, *dirt, *luxel, *luxel2, *deluxel, *deluxel2;
+ unsigned char *flag;
float *lightLuxels, *lightLuxel, samples, filterRadius, weight;
vec3_t color, averageColor, averageDir, total, temp, temp2;
float tests[ 4 ][ 2 ] = { { 0.0f, 0 }, { 1, 0 }, { 0, 1 }, { 1, 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;
memset( lightLuxels, 0, llSize );
totalLighted = 0;
+ /* determine filter radius */
+ filterRadius = lm->filterRadius > trace.light->filterRadius
+ ? lm->filterRadius
+ : trace.light->filterRadius;
+ if( filterRadius < 0.0f )
+ filterRadius = 0.0f;
+
+ /* set luxel filter radius */
+ luxelFilterRadius = superSample * filterRadius / lm->sampleSize;
+ if( luxelFilterRadius == 0 && (filterRadius > 0.0f || filter) )
+ luxelFilterRadius = 1;
+
+ /* allocate sampling flags storage */
+ if(lightSamples > 1 && luxelFilterRadius == 0)
+ {
+ size = lm->sw * lm->sh * SUPER_LUXEL_SIZE * sizeof( unsigned char );
+ if(lm->superFlags == NULL)
+ lm->superFlags = safe_malloc( size );
+ memset( (void *) lm->superFlags, 0, size );
+ }
+
/* initial pass, one sample per luxel */
for( y = 0; y < lm->sh; y++ )
{
deluxel = SUPER_DELUXEL( x, y );
origin = SUPER_ORIGIN( x, y );
normal = SUPER_NORMAL( x, y );
+ flag = SUPER_FLAG( x, y );
#if 0
////////// 27's temp hack for testing edge clipping ////
LightContributionToSample( &trace );
VectorCopy( trace.color, lightLuxel );
- /* 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
+ /* add the contribution to the deluxemap */
+ if( deluxemap )
+ VectorAdd( deluxel, trace.directionContribution, deluxel );
+
+ /* check for evilness */
+ if(trace.forceSubsampling > 1.0f && lightSamples > 1 && luxelFilterRadius == 0)
{
- /* 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 );
+ totalLighted++;
+ *flag |= FLAG_FORCE_SUBSAMPLING; /* force */
}
+ /* add to count */
+ else if( trace.color[ 0 ] || trace.color[ 1 ] || trace.color[ 2 ] )
+ totalLighted++;
}
}
}
if( totalLighted == 0 )
continue;
- /* determine filter radius */
- filterRadius = lm->filterRadius > trace.light->filterRadius
- ? lm->filterRadius
- : trace.light->filterRadius;
- if( filterRadius < 0.0f )
- filterRadius = 0.0f;
-
- /* set luxel filter radius */
- luxelFilterRadius = superSample * filterRadius / lm->sampleSize;
- if( luxelFilterRadius == 0 && (filterRadius > 0.0f || filter) )
- luxelFilterRadius = 1;
-
/* secondary pass, adaptive supersampling (fixme: use a contrast function to determine if subsampling is necessary) */
/* 2003-09-27: changed it so filtering disamples supersampling, as it would waste time */
if( lightSamples > 1 && luxelFilterRadius == 0 )
mapped++;
/* get luxel */
+ flag = SUPER_FLAG( sx, sy );
+ if(*flag & FLAG_FORCE_SUBSAMPLING)
+ {
+ /* force a lighted/mapped discrepancy so we subsample */
+ ++lighted;
+ ++mapped;
+ ++mapped;
+ }
lightLuxel = LIGHT_LUXEL( sx, sy );
VectorAdd( total, lightLuxel, total );
if( (lightLuxel[ 0 ] + lightLuxel[ 1 ] + lightLuxel[ 2 ]) > 0.0f )
cluster = SUPER_CLUSTER( sx, sy );
if( *cluster < 0 )
continue;
+ flag = SUPER_FLAG( sx, sy );
+ if(*flag & FLAG_ALREADY_SUBSAMPLED) // already subsampled
+ continue;
lightLuxel = LIGHT_LUXEL( sx, sy );
origin = SUPER_ORIGIN( sx, sy );
//% continue;
/* subsample it */
- SubsampleRawLuxel_r( lm, &trace, origin, sx, sy, 0.25f, lightLuxel );
+ SubsampleRawLuxel_r( lm, &trace, origin, sx, sy, 0.25f * lightSamplesSearchBoxSize, lightLuxel );
+
+ *flag |= FLAG_ALREADY_SUBSAMPLED;
/* debug code to colorize subsampled areas to yellow */
//% luxel = SUPER_LUXEL( lightmapNum, sx, sy );
lm->superLuxels[ lightmapNum ] = safe_malloc( size );
memset( lm->superLuxels[ lightmapNum ], 0, size );
}
-
+
/* set style */
if( lightmapNum > 0 )
{
FreeTraceLights( &trace );
/* floodlight pass */
- FloodlightIlluminateLightmap(lm);
+ if( floodlighty )
+ FloodlightIlluminateLightmap(lm);
if (debugnormals)
{
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;
rawLightmap_t *lm;
bspDrawVert_t *verts;
trace_t trace;
+ float floodLightAmount;
+ vec3_t floodColor;
/* get surface, info, and raw lightmap */
VectorCopy( verts[ i ].normal, trace.normal );
/* r7 dirt */
- if( dirty )
+ if( dirty && !bouncing )
dirt = DirtForSample( &trace );
else
dirt = 1.0f;
+ /* jal: floodlight */
+ floodLightAmount = 0.0f;
+ VectorClear( floodColor );
+ if( floodlighty && !bouncing )
+ {
+ floodLightAmount = floodlightIntensity * FloodLightForSample( &trace, floodlightDistance, floodlight_lowquality );
+ VectorScale( floodlightRGB, floodLightAmount, floodColor );
+ }
+
/* trace */
LightingAtSample( &trace, ds->vertexStyles, colors );
{
/* r7 dirt */
VectorScale( colors[ lightmapNum ], dirt, colors[ lightmapNum ] );
+
+ /* jal: floodlight */
+ VectorAdd( colors[ lightmapNum ], floodColor, colors[ lightmapNum ] );
/* store */
radVertLuxel = RAD_VERTEX_LUXEL( lightmapNum, ds->firstVert + i );
{
/* r7 dirt */
VectorScale( colors[ lightmapNum ], dirt, colors[ lightmapNum ] );
+
+ /* jal: floodlight */
+ VectorAdd( colors[ lightmapNum ], floodColor, colors[ lightmapNum ] );
/* store */
radVertLuxel = RAD_VERTEX_LUXEL( lightmapNum, ds->firstVert + i );
VectorCopy( trace->normal, normal );
/* check if the normal is aligned to the world-up */
- if( normal[ 0 ] == 0.0f && normal[ 1 ] == 0.0f )
+ if( normal[ 0 ] == 0.0f && normal[ 1 ] == 0.0f && ( normal[ 2 ] == 1.0f || normal[ 2 ] == -1.0f ) )
{
if( normal[ 2 ] == 1.0f )
{
/* global pass */
if (floodlighty && floodlightIntensity)
- FloodLightRawLightmapPass(lm, floodlightRGB, floodlightIntensity, floodlightDistance, floodlight_lowquality, 0);
+ FloodLightRawLightmapPass(lm, floodlightRGB, floodlightIntensity, floodlightDistance, floodlight_lowquality, 1.0f);
/* custom pass */
if (lm->floodlightIntensity)
float *luxel, *floodlight, *deluxel, *normal;
int *cluster;
float brightness;
- vec3_t lightvector;
int x, y, lightmapNum;
/* walk lightmaps */
/* add to deluxemap */
if (deluxemap && floodlight[3] > 0)
{
+ 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)
+ brightness = 0.00390625f;
+
VectorScale( normal, brightness, lightvector );
VectorAdd( deluxel, lightvector, deluxel );
}