X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=blobdiff_plain;f=tools%2Fquake3%2Fq3map2%2Flight.c;h=b6dcb1224e1c14589c00f554da66e84353d1f840;hp=dee882eed1402ed1248a80250719d7d610aa83c9;hb=98bf67071d2f878028003b14b9d1bcf8d81787f6;hpb=6661c1a8e89c733f6d0d5a2aa9689a2436b6a113 diff --git a/tools/quake3/q3map2/light.c b/tools/quake3/q3map2/light.c index dee882ee..b6dcb122 100644 --- a/tools/quake3/q3map2/light.c +++ b/tools/quake3/q3map2/light.c @@ -148,7 +148,6 @@ static void CreateSkyLights( vec3_t color, float value, int iterations, float fi int angleSteps, elevationSteps; float angle, elevation; float angleStep, elevationStep; - float step, start; sun_t sun; @@ -156,10 +155,6 @@ static void CreateSkyLights( vec3_t color, float value, int iterations, float fi if( value <= 0.0f || iterations < 2 ) return; - /* calculate some stuff */ - step = 2.0f / (iterations - 1); - start = -1.0f; - /* basic sun setup */ VectorCopy( color, sun.color ); sun.deviance = 0.0f; @@ -749,18 +744,20 @@ int LightContributionToSample( trace_t *trace ) float angle; float add; float dist; - float addDeluxe = 0.0f, addDeluxeBounceScale = 0.25f; - qboolean angledDeluxe = qfalse; + float addDeluxe = 0.0f, addDeluxeBounceScale = 0.25f; + qboolean angledDeluxe = qtrue; float colorBrightness; + qboolean doAddDeluxe = qtrue; /* get light */ light = trace->light; /* clear color */ + trace->forceSubsampling = 0.0f; /* to make sure */ VectorClear( trace->color ); VectorClear( trace->colorNoShadow ); - VectorClear( trace->directionContribution ); - + VectorClear( trace->directionContribution ); + colorBrightness = RGBTOGRAY( light->color ) * ( 1.0f/255.0f ); /* ydnar: early out */ @@ -820,8 +817,13 @@ int LightContributionToSample( trace_t *trace ) angle = DotProduct( trace->normal, trace->direction ); /* twosided lighting */ - if( trace->twoSided ) - angle = fabs( angle ); + if( trace->twoSided && angle < 0 ) + { + angle = -angle; + + /* no deluxemap contribution from "other side" light */ + doAddDeluxe = qfalse; + } /* attenuate */ angle *= -DotProduct( light->normal, trace->direction ); @@ -829,8 +831,13 @@ int LightContributionToSample( trace_t *trace ) return 0; else if( angle < 0.0f && (trace->twoSided || (light->flags & LIGHT_TWOSIDED)) ) + { angle = -angle; + /* no deluxemap contribution from "other side" light */ + doAddDeluxe = qfalse; + } + /* clamp the distance to prevent super hot spots */ dist = sqrt(dist * dist + light->extraDist * light->extraDist); if( dist < 16.0f ) @@ -838,12 +845,12 @@ int LightContributionToSample( trace_t *trace ) add = light->photons / (dist * dist) * angle; - if( deluxemap ) - { - if( angledDeluxe ) - addDeluxe = light->photons / (dist * dist) * angle; - else - addDeluxe = light->photons / (dist * dist); + if( deluxemap ) + { + if( angledDeluxe ) + addDeluxe = light->photons / (dist * dist) * angle; + else + addDeluxe = light->photons / (dist * dist); } } else @@ -864,15 +871,25 @@ int LightContributionToSample( trace_t *trace ) dist = SetupTrace( trace ); if( dist >= light->envelope ) return 0; + + /* no deluxemap contribution from "other side" light */ + doAddDeluxe = qfalse; } else return 0; } + + /* also don't deluxe if the direction is on the wrong side */ + if(DotProduct(trace->normal, trace->direction) < 0) + { + /* no deluxemap contribution from "other side" light */ + doAddDeluxe = qfalse; + } /* ydnar: moved to here */ add = factor * light->add; - if( deluxemap ) + if( deluxemap ) addDeluxe = add; } } @@ -898,8 +915,13 @@ int LightContributionToSample( trace_t *trace ) float dot = DotProduct( trace->normal, trace->direction ); /* twosided lighting */ - if( trace->twoSided ) - dot = fabs( dot ); + if( trace->twoSided && dot < 0 ) + { + dot = -dot; + + /* no deluxemap contribution from "other side" light */ + doAddDeluxe = qfalse; + } /* jal: optional half Lambert attenuation (http://developer.valvesoftware.com/wiki/Half_Lambert) */ if( lightAngleHL ) @@ -933,32 +955,32 @@ int LightContributionToSample( trace_t *trace ) 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; + 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 ) + 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; } @@ -985,12 +1007,12 @@ int LightContributionToSample( trace_t *trace ) 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 ) + if( add < 0.0f ) + add = 0.0f; + + addDeluxe *= ((radiusAtDist - sampleRadius) / 32.0f); + + if( addDeluxe < 0.0f ) addDeluxe = 0.0f; } } @@ -1010,8 +1032,13 @@ int LightContributionToSample( trace_t *trace ) float dot = DotProduct( trace->normal, trace->direction ); /* twosided lighting */ - if( trace->twoSided ) - dot = fabs( dot ); + if( trace->twoSided && dot < 0 ) + { + dot = -dot; + + /* no deluxemap contribution from "other side" light */ + doAddDeluxe = qfalse; + } /* jal: optional half Lambert attenuation (http://developer.valvesoftware.com/wiki/Half_Lambert) */ if( lightAngleHL ) @@ -1034,15 +1061,15 @@ 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( deluxemap ) + { + if( angledDeluxe ) + addDeluxe = light->photons * angle; + else + addDeluxe = light->photons; + + if( addDeluxe < 0.0f ) + addDeluxe = 0.0f; } if( add <= 0.0f ) @@ -1051,15 +1078,15 @@ int LightContributionToSample( trace_t *trace ) /* VorteX: set noShadow color */ VectorScale(light->color, add, trace->colorNoShadow); - addDeluxe *= colorBrightness; - - if( bouncing ) - { - addDeluxe *= addDeluxeBounceScale; - if( addDeluxe < 0.00390625f ) - addDeluxe = 0.00390625f; - } - + addDeluxe *= colorBrightness; + + if( bouncing ) + { + addDeluxe *= addDeluxeBounceScale; + if( addDeluxe < 0.00390625f ) + addDeluxe = 0.00390625f; + } + VectorScale( trace->direction, addDeluxe, trace->directionContribution ); /* setup trace */ @@ -1071,6 +1098,7 @@ int LightContributionToSample( trace_t *trace ) { /* trace */ TraceLine( trace ); + trace->forceSubsampling *= add; if( !(trace->compileFlags & C_SKY) || trace->opaque ) { VectorClear( trace->color ); @@ -1083,6 +1111,8 @@ int LightContributionToSample( trace_t *trace ) /* return to sender */ return 1; } + else + Error("Light of undefined type!"); /* VorteX: set noShadow color */ VectorScale(light->color, add, trace->colorNoShadow); @@ -1091,28 +1121,33 @@ 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 ); + 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; + /* better NOT increase it beyond the original value + if( addDeluxe < 0.00390625f ) + addDeluxe = 0.00390625f; + */ + } + + if(doAddDeluxe) + { + VectorScale( trace->direction, addDeluxe, trace->directionContribution ); + } /* setup trace */ trace->testAll = qfalse; @@ -1120,10 +1155,11 @@ int LightContributionToSample( trace_t *trace ) /* raytrace */ TraceLine( trace ); + trace->forceSubsampling *= add; if( trace->passSolid || trace->opaque ) { VectorClear( trace->color ); - VectorClear( trace->directionContribution ); + VectorClear( trace->directionContribution ); return -1; } @@ -1535,56 +1571,56 @@ void TraceGrid( int num ) /////// Floodlighting for point ////////////////// //do our floodlight ambient occlusion loop, and add a single contribution based on the brightest dir - if( floodlighty ) - { - int k; - float addSize, f; - vec3_t dir = { 0, 0, 1 }; - float ambientFrac = 0.25f; - - trace.testOcclusion = qtrue; - trace.forceSunlight = qfalse; - trace.inhibitRadius = DEFAULT_INHIBIT_RADIUS; - trace.testAll = qtrue; - - for( k = 0; k < 2; k++ ) - { - if( k == 0 ) // upper hemisphere - { - trace.normal[0] = 0; - trace.normal[1] = 0; - trace.normal[2] = 1; - } - else //lower hemisphere - { - trace.normal[0] = 0; - trace.normal[1] = 0; - trace.normal[2] = -1; - } - - f = FloodLightForSample( &trace, floodlightDistance, floodlight_lowquality ); - - /* add a fraction as pure ambient, half as top-down direction */ - contributions[ numCon ].color[0]= floodlightRGB[0] * floodlightIntensity * f * ( 1.0f - ambientFrac ); - contributions[ numCon ].color[1]= floodlightRGB[1] * floodlightIntensity * f * ( 1.0f - ambientFrac ); - contributions[ numCon ].color[2]= floodlightRGB[2] * floodlightIntensity * f * ( 1.0f - ambientFrac ); - - contributions[ numCon ].ambient[0]= floodlightRGB[0] * floodlightIntensity * f * ambientFrac; - contributions[ numCon ].ambient[1]= floodlightRGB[1] * floodlightIntensity * f * ambientFrac; - contributions[ numCon ].ambient[2]= floodlightRGB[2] * floodlightIntensity * f * ambientFrac; - - contributions[ numCon ].dir[0] = dir[0]; - contributions[ numCon ].dir[1] = dir[1]; - contributions[ numCon ].dir[2] = dir[2]; - - contributions[ numCon ].style = 0; - - /* push average direction around */ - addSize = VectorLength( contributions[ numCon ].color ); - VectorMA( gp->dir, addSize, dir, gp->dir ); - - numCon++; - } + if( floodlighty ) + { + int k; + float addSize, f; + vec3_t dir = { 0, 0, 1 }; + float ambientFrac = 0.25f; + + trace.testOcclusion = qtrue; + trace.forceSunlight = qfalse; + trace.inhibitRadius = DEFAULT_INHIBIT_RADIUS; + trace.testAll = qtrue; + + for( k = 0; k < 2; k++ ) + { + if( k == 0 ) // upper hemisphere + { + trace.normal[0] = 0; + trace.normal[1] = 0; + trace.normal[2] = 1; + } + else //lower hemisphere + { + trace.normal[0] = 0; + trace.normal[1] = 0; + trace.normal[2] = -1; + } + + f = FloodLightForSample( &trace, floodlightDistance, floodlight_lowquality ); + + /* add a fraction as pure ambient, half as top-down direction */ + contributions[ numCon ].color[0]= floodlightRGB[0] * floodlightIntensity * f * ( 1.0f - ambientFrac ); + contributions[ numCon ].color[1]= floodlightRGB[1] * floodlightIntensity * f * ( 1.0f - ambientFrac ); + contributions[ numCon ].color[2]= floodlightRGB[2] * floodlightIntensity * f * ( 1.0f - ambientFrac ); + + contributions[ numCon ].ambient[0]= floodlightRGB[0] * floodlightIntensity * f * ambientFrac; + contributions[ numCon ].ambient[1]= floodlightRGB[1] * floodlightIntensity * f * ambientFrac; + contributions[ numCon ].ambient[2]= floodlightRGB[2] * floodlightIntensity * f * ambientFrac; + + contributions[ numCon ].dir[0] = dir[0]; + contributions[ numCon ].dir[1] = dir[1]; + contributions[ numCon ].dir[2] = dir[2]; + + contributions[ numCon ].style = 0; + + /* push average direction around */ + addSize = VectorLength( contributions[ numCon ].color ); + VectorMA( gp->dir, addSize, dir, gp->dir ); + + numCon++; + } } ///////////////////// @@ -1791,7 +1827,7 @@ void LightWorld( void ) vec3_t color; float f; int b, bt; - qboolean minVertex, minGrid, ps; + qboolean minVertex, minGrid; const char *value; @@ -2009,6 +2045,7 @@ int LightMain( int argc, char **argv ) char mapSource[ 1024 ]; const char *value; int lightmapMergeSize = 0; + qboolean lightSamplesInsist = qfalse; /* note it */ @@ -2028,6 +2065,12 @@ int LightMain( int argc, char **argv ) lightmapGamma = game->lightmapGamma; Sys_Printf( " lightning gamma: %f\n", lightmapGamma ); + lightmapsRGB = game->lightmapsRGB; + if(lightmapsRGB) + Sys_Printf( " lightmap colorspace: sRGB\n" ); + else + Sys_Printf( " lightmap colorspace: linear\n" ); + lightmapCompensate = game->lightmapCompensate; Sys_Printf( " lightning compensation: %f\n", lightmapCompensate ); @@ -2142,20 +2185,20 @@ int LightMain( int argc, char **argv ) else if( !strcmp( argv[ i ], "-griddirectionality" ) ) { f = atof( argv[ i + 1 ] ); - if(f < 0) f = 0; - if(f > gridAmbientDirectionality) f = gridAmbientDirectionality; + if(f > 1) f = 1; + if(f < gridAmbientDirectionality) gridAmbientDirectionality = f; Sys_Printf( "Grid directionality is %f\n", f ); - gridDirectionality *= f; + gridDirectionality = f; i++; } else if( !strcmp( argv[ i ], "-gridambientdirectionality" ) ) { f = atof( argv[ i + 1 ] ); - if(f > gridDirectionality) f = gridDirectionality; - if(f > 1) f = 1; + if(f < -1) f = -1; + if(f > gridDirectionality) gridDirectionality = f; Sys_Printf( "Grid ambient directionality is %f\n", f ); - gridAmbientDirectionality *= f; + gridAmbientDirectionality = f; i++; } @@ -2167,6 +2210,18 @@ int LightMain( int argc, char **argv ) i++; } + else if( !strcmp( argv[ i ], "-sRGB" ) ) + { + lightmapsRGB = qtrue; + Sys_Printf( "Lighting is in sRGB\n" ); + } + + else if( !strcmp( argv[ i ], "-nosRGB" ) ) + { + lightmapsRGB = qfalse; + Sys_Printf( "Lighting is linear\n" ); + } + else if( !strcmp( argv[ i ], "-exposure" ) ) { f = atof( argv[ i + 1 ] ); @@ -2206,8 +2261,18 @@ int LightMain( int argc, char **argv ) i++; } + else if( !strcmp( argv[ i ], "-randomsamples" ) ) + { + lightRandomSamples = qtrue; + Sys_Printf( "Random sampling enabled\n", lightRandomSamples ); + } + else if( !strcmp( argv[ i ], "-samples" ) ) { + if(*argv[i+1] == '+') + lightSamplesInsist = qtrue; + else + lightSamplesInsist = qfalse; lightSamples = atoi( argv[ i + 1 ] ); if( lightSamples < 1 ) lightSamples = 1; @@ -2216,6 +2281,18 @@ int LightMain( int argc, char **argv ) i++; } + else if( !strcmp( argv[ i ], "-samplessearchboxsize" ) ) + { + lightSamplesSearchBoxSize = atoi( argv[ i + 1 ] ); + if( lightSamplesSearchBoxSize <= 0 ) + lightSamplesSearchBoxSize = 1; + if( lightSamplesSearchBoxSize > 4 ) + lightSamplesSearchBoxSize = 4; /* more makes no sense */ + else if( lightSamplesSearchBoxSize != 1 ) + Sys_Printf( "Adaptive supersampling uses %f times the normal search box size\n", lightSamplesSearchBoxSize ); + i++; + } + else if( !strcmp( argv[ i ], "-filter" ) ) { filter = qtrue; @@ -2690,6 +2767,11 @@ int LightMain( int argc, char **argv ) { lightmapExtraVisClusterNudge = qtrue; } + else if( !strcmp( argv[ i ], "-fill" ) ) + { + lightmapFill = qtrue; + Sys_Printf( "Filling lightmap colors from surrounding pixels to improve JPEG compression\n" ); + } /* unhandled args */ else { @@ -2698,6 +2780,38 @@ int LightMain( int argc, char **argv ) } + /* fix up samples count */ + if(lightRandomSamples) + { + if(!lightSamplesInsist) + { + /* approximately match -samples in quality */ + switch(lightSamples) + { + /* somewhat okay */ + case 1: + case 2: + lightSamples = 16; + Sys_Printf( "Adaptive supersampling preset enabled with %d random sample(s) per lightmap texel\n", lightSamples ); + break; + + /* good */ + case 3: + lightSamples = 64; + Sys_Printf( "Adaptive supersampling preset enabled with %d random sample(s) per lightmap texel\n", lightSamples ); + break; + + /* perfect */ + case 4: + lightSamples = 256; + Sys_Printf( "Adaptive supersampling preset enabled with %d random sample(s) per lightmap texel\n", lightSamples ); + break; + + default: break; + } + } + } + /* fix up lightmap search power */ if(lightmapMergeSize) { @@ -2741,7 +2855,7 @@ int LightMain( int argc, char **argv ) /* load map file */ value = ValueForKey( &entities[ 0 ], "_keepLights" ); if( value[ 0 ] != '1' ) - LoadMapFile( mapSource, qtrue ); + LoadMapFile( mapSource, qtrue, qfalse ); /* set the entity/model origins and init yDrawVerts */ SetEntityOrigins();