option -randomsamples: makes -samples use adaptive random subsampling (only subsamples near edges, uses random distribution for luxels then)

This commit is contained in:
Rudolf Polzer 2010-10-03 20:23:14 +02:00
parent 8ff9eafc50
commit 61d0c06cc6
3 changed files with 53 additions and 4 deletions

View File

@ -2245,6 +2245,12 @@ int LightMain( int argc, char **argv )
i++; i++;
} }
else if( !strcmp( argv[ i ], "-randomsamples" ) )
{
lightRandomSamples = qtrue;
Sys_Printf( "Random sampling enabled\n", lightRandomSamples );
}
else if( !strcmp( argv[ i ], "-samples" ) ) else if( !strcmp( argv[ i ], "-samples" ) )
{ {
lightSamples = atoi( argv[ i + 1 ] ); lightSamples = atoi( argv[ i + 1 ] );

View File

@ -1871,6 +1871,45 @@ static void SubsampleRawLuxel_r( rawLightmap_t *lm, trace_t *trace, vec3_t sampl
lightLuxel[ 3 ] += 1.0f; lightLuxel[ 3 ] += 1.0f;
} }
} }
static void RandomSubsampleRawLuxel( rawLightmap_t *lm, trace_t *trace, vec3_t sampleOrigin, int x, int y, float bias, float *lightLuxel )
{
int b, samples, mapped;
int cluster;
vec3_t origin, normal;
vec3_t total;
VectorClear( total );
mapped = 0;
for(b = 0; b < lightSamples; ++b)
{
/* set origin */
VectorCopy( sampleOrigin, origin );
/* calculate position */
if( !SubmapRawLuxel( lm, x, y, (bias * (2 * Random() - 1)), (bias * (2 * Random() - 1)), &cluster, origin, normal ) )
{
cluster = -1;
continue;
}
mapped++;
trace->cluster = cluster;
VectorCopy( origin, trace->origin );
VectorCopy( normal, trace->normal );
LightContributionToSample( trace );
VectorAdd( total, trace->color, total );
}
/* add to luxel */
if( mapped > 0 )
{
/* average */
lightLuxel[ 0 ] = total[ 0 ] / mapped;
lightLuxel[ 1 ] = total[ 1 ] / mapped;
lightLuxel[ 2 ] = total[ 2 ] / mapped;
}
}
@ -2099,7 +2138,7 @@ void IlluminateRawLightmap( int rawLightmapNum )
luxelFilterRadius = 1; luxelFilterRadius = 1;
/* allocate sampling flags storage */ /* allocate sampling flags storage */
if(lightSamples > 1 && luxelFilterRadius == 0) if((lightSamples > 1 || lightRandomSamples) && luxelFilterRadius == 0)
{ {
size = lm->sw * lm->sh * SUPER_LUXEL_SIZE * sizeof( unsigned char ); size = lm->sw * lm->sh * SUPER_LUXEL_SIZE * sizeof( unsigned char );
if(lm->superFlags == NULL) if(lm->superFlags == NULL)
@ -2152,7 +2191,7 @@ void IlluminateRawLightmap( int rawLightmapNum )
VectorAdd( deluxel, trace.directionContribution, deluxel ); VectorAdd( deluxel, trace.directionContribution, deluxel );
/* check for evilness */ /* check for evilness */
if(trace.forceSubsampling > 1.0f && lightSamples > 1 && luxelFilterRadius == 0) if(trace.forceSubsampling > 1.0f && (lightSamples > 1 || lightRandomSamples) && luxelFilterRadius == 0)
{ {
totalLighted++; totalLighted++;
*flag |= FLAG_FORCE_SUBSAMPLING; /* force */ *flag |= FLAG_FORCE_SUBSAMPLING; /* force */
@ -2170,7 +2209,7 @@ void IlluminateRawLightmap( int rawLightmapNum )
/* secondary pass, adaptive supersampling (fixme: use a contrast function to determine if subsampling is necessary) */ /* 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 */ /* 2003-09-27: changed it so filtering disamples supersampling, as it would waste time */
if( lightSamples > 1 && luxelFilterRadius == 0 ) if( (lightSamples > 1 || lightRandomSamples) && luxelFilterRadius == 0 )
{ {
/* walk luxels */ /* walk luxels */
for( y = 0; y < (lm->sh - 1); y++ ) for( y = 0; y < (lm->sh - 1); y++ )
@ -2238,6 +2277,9 @@ void IlluminateRawLightmap( int rawLightmapNum )
//% continue; //% continue;
/* subsample it */ /* subsample it */
if(lightRandomSamples)
RandomSubsampleRawLuxel( lm, &trace, origin, sx, sy, 0.5f, lightLuxel );
else
SubsampleRawLuxel_r( lm, &trace, origin, sx, sy, 0.25f * lightSamplesSearchBoxSize, lightLuxel ); SubsampleRawLuxel_r( lm, &trace, origin, sx, sy, 0.25f * lightSamplesSearchBoxSize, lightLuxel );
*flag |= FLAG_ALREADY_SUBSAMPLED; *flag |= FLAG_ALREADY_SUBSAMPLED;

View File

@ -2197,6 +2197,7 @@ Q_EXTERN qboolean shade Q_ASSIGN( qfalse );
Q_EXTERN float shadeAngleDegrees Q_ASSIGN( 0.0f ); Q_EXTERN float shadeAngleDegrees Q_ASSIGN( 0.0f );
Q_EXTERN int superSample Q_ASSIGN( 0 ); Q_EXTERN int superSample Q_ASSIGN( 0 );
Q_EXTERN int lightSamples Q_ASSIGN( 1 ); Q_EXTERN int lightSamples Q_ASSIGN( 1 );
Q_EXTERN qboolean lightRandomSamples Q_ASSIGN( qfalse );
Q_EXTERN int lightSamplesSearchBoxSize Q_ASSIGN( 1 ); Q_EXTERN int lightSamplesSearchBoxSize Q_ASSIGN( 1 );
Q_EXTERN qboolean filter Q_ASSIGN( qfalse ); Q_EXTERN qboolean filter Q_ASSIGN( qfalse );
Q_EXTERN qboolean dark Q_ASSIGN( qfalse ); Q_EXTERN qboolean dark Q_ASSIGN( qfalse );