X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=blobdiff_plain;f=tools%2Fquake3%2Fq3map2%2Flight_ydnar.c;h=254a8c97bd1c60d596777d8d8870a60f5f3a0962;hp=4f62949262b4f91a0398e7880665eb874f75b138;hb=f560e2703b3ccb1cab0f4071ee8c676d8d3f8068;hpb=107765f0e4b543dfc346851ee5b4605cc17eb1c6 diff --git a/tools/quake3/q3map2/light_ydnar.c b/tools/quake3/q3map2/light_ydnar.c index 4f629492..254a8c97 100644 --- a/tools/quake3/q3map2/light_ydnar.c +++ b/tools/quake3/q3map2/light_ydnar.c @@ -533,7 +533,7 @@ static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t //1) Test the sample origin to see if it lays on the wrong side of any edge (x/y) //2) if it does, nudge it onto the correct side. - if (worldverts!=NULL) + if (worldverts!=NULL && lightmapTriangleCheck) { for (j=0;j<3;j++) { @@ -604,9 +604,12 @@ static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t origin[ lm->axisNum ] += lightmapSampleOffset; VectorCopy(origin,origintwo); - origintwo[0]+=vecs[2][0]; - origintwo[1]+=vecs[2][1]; - origintwo[2]+=vecs[2][2]; + if(lightmapExtraVisClusterNudge) + { + origintwo[0]+=vecs[2][0]; + origintwo[1]+=vecs[2][1]; + origintwo[2]+=vecs[2][2]; + } /* get cluster */ pointCluster = ClusterForPointExtFilter( origintwo, LUXEL_EPSILON, numClusters, clusters ); @@ -631,8 +634,8 @@ static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t /* get pvs cluster */ pointCluster = ClusterForPointExtFilter( nudged, LUXEL_EPSILON, numClusters, clusters ); //% + 0.625 ); - //if( pointCluster >= 0 ) - // VectorCopy( nudged, origin ); + if( pointCluster >= 0 ) + VectorCopy( nudged, origin ); luxel[ 1 ] += 1.0f; } } @@ -642,8 +645,8 @@ static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t { VectorMA( dv->xyz, lightmapSampleOffset, dv->normal, nudged ); pointCluster = ClusterForPointExtFilter( nudged, LUXEL_EPSILON, numClusters, clusters ); - //if( pointCluster >= 0 ) - // VectorCopy( nudged, origin ); + if( pointCluster >= 0 ) + VectorCopy( nudged, origin ); luxel[ 1 ] += 1.0f; } @@ -1559,7 +1562,7 @@ void DirtyRawLightmap( int rawLightmapNum ) trace.numSurfaces = lm->numLightSurfaces; trace.surfaces = &lightSurfaces[ lm->firstLightSurface ]; trace.inhibitRadius = DEFAULT_INHIBIT_RADIUS; - trace.testAll = qfalse; + trace.testAll = qtrue; /* twosided lighting (may or may not be a good idea for lightmapped stuff) */ trace.twoSided = qfalse; @@ -2004,7 +2007,14 @@ void IlluminateRawLightmap( int rawLightmapNum ) { VectorCopy( ambientColor, luxel ); if( deluxemap ) - VectorScale( normal, 0.00390625f, deluxel ); + { + brightness = ambientColor[ 0 ] * 0.3f + ambientColor[ 1 ] * 0.59f + ambientColor[ 2 ] * 0.11f; + brightness *= (1.0 / 255.0); + // 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; } } @@ -2063,6 +2073,7 @@ void IlluminateRawLightmap( int rawLightmapNum ) origin = SUPER_ORIGIN( x, y ); normal = SUPER_NORMAL( x, y ); +#if 0 ////////// 27's temp hack for testing edge clipping //// if( origin[0]==0 && origin[1]==0 && origin[2]==0 ) { @@ -2071,6 +2082,7 @@ void IlluminateRawLightmap( int rawLightmapNum ) totalLighted++; } else +#endif { /* set contribution count */ lightLuxel[ 3 ] = 1.0f; @@ -2092,11 +2104,14 @@ void IlluminateRawLightmap( int rawLightmapNum ) /* add to light direction map (fixme: use luxel normal as starting point for deluxel?) */ if( deluxemap ) { - /* color to grayscale (photoshop rgb weighting) */ - brightness = trace.color[ 0 ] * 0.3f + trace.color[ 1 ] * 0.59f + trace.color[ 2 ] * 0.11f; - brightness *= (1.0 / 255.0); - VectorScale( trace.direction, brightness, trace.direction ); - VectorAdd( deluxel, trace.direction, deluxel ); + 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 ); + } } } } @@ -2331,48 +2346,8 @@ void IlluminateRawLightmap( int rawLightmapNum ) /* free light list */ FreeTraceLights( &trace ); - /* ----------------------------------------------------------------- - floodlight pass - ----------------------------------------------------------------- */ - - if( floodlighty ) - { - /* walk lightmaps */ - for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) - { - /* early out */ - if( lm->superLuxels[ lightmapNum ] == NULL ) - continue; - - /* apply floodlight to each luxel */ - for( y = 0; y < lm->sh; y++ ) - { - for( x = 0; x < lm->sw; x++ ) - { - /* get cluster */ - cluster = SUPER_CLUSTER( x, y ); - //% if( *cluster < 0 ) - //% continue; - - /* get particulars */ - luxel = SUPER_LUXEL( lightmapNum, x, y ); - floodlight = SUPER_FLOODLIGHT( x, y ); - - flood[0]=floodlightRGB[0]*floodlightIntensity; - flood[1]=floodlightRGB[1]*floodlightIntensity; - flood[2]=floodlightRGB[2]*floodlightIntensity; - - /* scale light value */ - VectorScale( flood, *floodlight, flood ); - luxel[0]+=flood[0]; - luxel[1]+=flood[1]; - luxel[2]+=flood[2]; - - if (luxel[3]==0) luxel[3]=1; - } - } - } - } + /* floodlight pass */ + FloodlightIlluminateLightmap(lm); if (debugnormals) { @@ -2381,7 +2356,7 @@ void IlluminateRawLightmap( int rawLightmapNum ) /* early out */ if( lm->superLuxels[ lightmapNum ] == NULL ) continue; - + for( y = 0; y < lm->sh; y++ ) { for( x = 0; x < lm->sw; x++ ) @@ -2390,11 +2365,11 @@ void IlluminateRawLightmap( int rawLightmapNum ) cluster = SUPER_CLUSTER( x, y ); //% if( *cluster < 0 ) //% continue; - + /* get particulars */ luxel = SUPER_LUXEL( lightmapNum, x, y ); normal = SUPER_NORMAL ( x, y ); - + luxel[0]=(normal[0]*127)+127; luxel[1]=(normal[1]*127)+127; luxel[2]=(normal[2]*127)+127; @@ -2402,7 +2377,7 @@ void IlluminateRawLightmap( int rawLightmapNum ) } } } - + /* ----------------------------------------------------------------- dirt pass ----------------------------------------------------------------- */ @@ -2423,7 +2398,7 @@ void IlluminateRawLightmap( int rawLightmapNum ) { /* get cluster */ cluster = SUPER_CLUSTER( x, y ); - //% if( *cluster < 0 ) + //% if( *cluster < 0 ) // TODO why not do this check? These pixels should be zero anyway //% continue; /* get particulars */ @@ -2536,6 +2511,44 @@ void IlluminateRawLightmap( int rawLightmapNum ) } } } + + +#if 0 + // audit pass + for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) + { + /* early out */ + if( lm->superLuxels[ lightmapNum ] == NULL ) + continue; + for( y = 0; y < lm->sh; y++ ) + for( x = 0; x < lm->sw; x++ ) + { + /* get cluster */ + cluster = SUPER_CLUSTER( x, y ); + luxel = SUPER_LUXEL( lightmapNum, x, y ); + deluxel = SUPER_DELUXEL( x, y ); + if(!luxel || !deluxel || !cluster) + { + Sys_FPrintf(SYS_VRB, "WARNING: I got NULL'd.\n"); + continue; + } + else if(*cluster < 0) + { + // unmapped pixel + // should have neither deluxemap nor lightmap + if(deluxel[3]) + Sys_FPrintf(SYS_VRB, "WARNING: I have written deluxe to an unmapped luxel. Sorry.\n"); + } + else + { + // mapped pixel + // should have both deluxemap and lightmap + if(deluxel[3]) + Sys_FPrintf(SYS_VRB, "WARNING: I forgot to write deluxe to a mapped luxel. Sorry.\n"); + } + } + } +#endif } @@ -3847,24 +3860,145 @@ void SetupFloodLight( void ) VectorNormalize(floodlightRGB,floodlightRGB); } -//27 - lighttracer style ambient occlusion light hack. -//Kudos to the dirtmapping author for most of this source. -void FloodLightRawLightmap( int rawLightmapNum ) +/* +FloodLightForSample() +calculates floodlight value for a given sample +once again, kudos to the dirtmapping coder +*/ + +float FloodLightForSample( trace_t *trace , float floodLightDistance, qboolean floodLightLowQuality) { - int i, x, y, sx, sy, *cluster; - float *origin, *normal, *floodlight, *floodlight2, average, samples; - rawLightmap_t *lm; - surfaceInfo_t *info; - trace_t trace; + int i; + float d; + float contribution; + int sub = 0; + float gatherLight, outLight; + vec3_t normal, worldUp, myUp, myRt, direction, displacement; + float dd; + int vecs = 0; + + gatherLight=0; + /* dummy check */ + //if( !dirty ) + // return 1.0f; + if( trace == NULL || trace->cluster < 0 ) + return 0.0f; + - /* bail if this number exceeds the number of raw lightmaps */ - if( rawLightmapNum >= numRawLightmaps ) - return; + /* setup */ + dd = floodLightDistance; + 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[ 2 ] == 1.0f ) + { + VectorSet( myRt, 1.0f, 0.0f, 0.0f ); + VectorSet( myUp, 0.0f, 1.0f, 0.0f ); + } + else if( normal[ 2 ] == -1.0f ) + { + VectorSet( myRt, -1.0f, 0.0f, 0.0f ); + VectorSet( myUp, 0.0f, 1.0f, 0.0f ); + } + } + else + { + VectorSet( worldUp, 0.0f, 0.0f, 1.0f ); + CrossProduct( normal, worldUp, myRt ); + VectorNormalize( myRt, myRt ); + CrossProduct( myRt, normal, myUp ); + VectorNormalize( myUp, myUp ); + } - /* get lightmap */ - lm = &rawLightmaps[ rawLightmapNum ]; + /* vortex: optimise floodLightLowQuality a bit */ + if ( floodLightLowQuality == qtrue ) + { + /* iterate through ordered vectors */ + for( i = 0; i < numFloodVectors; i++ ) + if (rand()%10 != 0 ) continue; + } + else + { + /* iterate through ordered vectors */ + for( i = 0; i < numFloodVectors; i++ ) + { + vecs++; + + /* transform vector into tangent space */ + direction[ 0 ] = myRt[ 0 ] * floodVectors[ i ][ 0 ] + myUp[ 0 ] * floodVectors[ i ][ 1 ] + normal[ 0 ] * floodVectors[ i ][ 2 ]; + direction[ 1 ] = myRt[ 1 ] * floodVectors[ i ][ 0 ] + myUp[ 1 ] * floodVectors[ i ][ 1 ] + normal[ 1 ] * floodVectors[ i ][ 2 ]; + direction[ 2 ] = myRt[ 2 ] * floodVectors[ i ][ 0 ] + myUp[ 2 ] * floodVectors[ i ][ 1 ] + normal[ 2 ] * floodVectors[ i ][ 2 ]; + + /* set endpoint */ + VectorMA( trace->origin, dd, direction, trace->end ); + + //VectorMA( trace->origin, 1, direction, trace->origin ); + + SetupTrace( trace ); + /* trace */ + TraceLine( trace ); + contribution=1; + + if (trace->compileFlags & C_SKY ) + { + contribution=1.0f; + } + else if ( trace->opaque ) + { + VectorSubtract( trace->hit, trace->origin, displacement ); + d=VectorLength( displacement ); + + // d=trace->distance; + //if (d>256) gatherDirt+=1; + contribution=d/dd; + if (contribution>1) contribution=1.0f; + + //gatherDirt += 1.0f - ooDepth * VectorLength( displacement ); + } + + gatherLight+=contribution; + } + } + + /* early out */ + if( gatherLight <= 0.0f ) + return 0.0f; + + sub=vecs; + + if (sub<1) sub=1; + gatherLight/=(sub); + outLight=gatherLight; + if( outLight > 1.0f ) + outLight = 1.0f; + + /* return to sender */ + return outLight; +} + +/* +FloodLightRawLightmap +lighttracer style ambient occlusion light hack. +Kudos to the dirtmapping author for most of this source. +VorteX: modified to floodlight up custom surfaces (q3map_floodLight) +VorteX: fixed problems with deluxemapping +*/ + +// floodlight pass on a lightmap +void FloodLightRawLightmapPass( rawLightmap_t *lm , vec3_t lmFloodLightRGB, float lmFloodLightIntensity, float lmFloodLightDistance, qboolean lmFloodLightLowQuality, float floodlightDirectionScale) +{ + int i, x, y, *cluster; + float *origin, *normal, *floodlight, floodLightAmount; + surfaceInfo_t *info; + trace_t trace; + // int sx, sy; + // float samples, average, *floodlight2; + memset(&trace,0,sizeof(trace_t)); + /* setup trace */ trace.testOcclusion = qtrue; trace.forceSunlight = qfalse; @@ -3875,14 +4009,14 @@ void FloodLightRawLightmap( int rawLightmapNum ) trace.inhibitRadius = DEFAULT_INHIBIT_RADIUS; trace.testAll = qfalse; trace.distance = 1024; - + /* twosided lighting (may or may not be a good idea for lightmapped stuff) */ //trace.twoSided = qfalse; for( i = 0; i < trace.numSurfaces; i++ ) { /* get surface */ info = &surfaceInfos[ trace.surfaces[ i ] ]; - + /* check twosidedness */ if( info->si->twoSided ) { @@ -3890,8 +4024,8 @@ void FloodLightRawLightmap( int rawLightmapNum ) break; } } - - /* gather dirt */ + + /* gather floodlight */ for( y = 0; y < lm->sh; y++ ) { for( x = 0; x < lm->sw; x++ ) @@ -3901,29 +4035,35 @@ void FloodLightRawLightmap( int rawLightmapNum ) origin = SUPER_ORIGIN( x, y ); normal = SUPER_NORMAL( x, y ); floodlight = SUPER_FLOODLIGHT( x, y ); - + /* set default dirt */ *floodlight = 0.0f; - + /* only look at mapped luxels */ if( *cluster < 0 ) continue; - + /* copy to trace */ trace.cluster = *cluster; VectorCopy( origin, trace.origin ); VectorCopy( normal, trace.normal ); - - - - /* get dirt */ - *floodlight = FloodLightForSample( &trace ); + + /* get floodlight */ + floodLightAmount = FloodLightForSample( &trace , lmFloodLightDistance, lmFloodLightLowQuality)*lmFloodLightIntensity; + + /* add floodlight */ + floodlight[0] += lmFloodLightRGB[0]*floodLightAmount; + floodlight[1] += lmFloodLightRGB[1]*floodLightAmount; + floodlight[2] += lmFloodLightRGB[2]*floodLightAmount; + floodlight[3] += floodlightDirectionScale; } } - + /* testing no filtering */ return; +#if 0 + /* filter "dirt" */ for( y = 0; y < lm->sh; y++ ) { @@ -3931,8 +4071,8 @@ void FloodLightRawLightmap( int rawLightmapNum ) { /* get luxel */ cluster = SUPER_CLUSTER( x, y ); - floodlight = SUPER_FLOODLIGHT( x, y ); - + floodlight = SUPER_FLOODLIGHT(x, y ); + /* filter dirt by adjacency to unmapped luxels */ average = *floodlight; samples = 1.0f; @@ -3940,148 +4080,127 @@ void FloodLightRawLightmap( int rawLightmapNum ) { if( sy < 0 || sy >= lm->sh ) continue; - + for( sx = (x - 1); sx <= (x + 1); sx++ ) { if( sx < 0 || sx >= lm->sw || (sx == x && sy == y) ) continue; - + /* get neighboring luxel */ cluster = SUPER_CLUSTER( sx, sy ); floodlight2 = SUPER_FLOODLIGHT( sx, sy ); if( *cluster < 0 || *floodlight2 <= 0.0f ) continue; - + /* add it */ average += *floodlight2; samples += 1.0f; } - + /* bail */ if( samples <= 0.0f ) break; } - + /* bail */ if( samples <= 0.0f ) continue; - + /* scale dirt */ *floodlight = average / samples; } } +#endif } -/* -FloodLightForSample() -calculates floodlight value for a given sample -once again, kudos to the dirtmapping coder -*/ -float FloodLightForSample( trace_t *trace ) +void FloodLightRawLightmap( int rawLightmapNum ) { - int i; - float d; - float contribution; - int sub = 0; - float gatherLight, outLight; - vec3_t normal, worldUp, myUp, myRt, direction, displacement; - float dd; - int vecs = 0; - - gatherLight=0; - /* dummy check */ - //if( !dirty ) - // return 1.0f; - if( trace == NULL || trace->cluster < 0 ) - return 0.0f; + rawLightmap_t *lm; + /* bail if this number exceeds the number of raw lightmaps */ + if( rawLightmapNum >= numRawLightmaps ) + return; + /* get lightmap */ + lm = &rawLightmaps[ rawLightmapNum ]; - /* setup */ - dd = floodlightDistance; - VectorCopy( trace->normal, normal ); + /* global pass */ + if (floodlighty && floodlightIntensity) + FloodLightRawLightmapPass(lm, floodlightRGB, floodlightIntensity, floodlightDistance, floodlight_lowquality, 0); - /* check if the normal is aligned to the world-up */ - if( normal[ 0 ] == 0.0f && normal[ 1 ] == 0.0f ) + /* custom pass */ + if (lm->floodlightIntensity) { - if( normal[ 2 ] == 1.0f ) - { - VectorSet( myRt, 1.0f, 0.0f, 0.0f ); - VectorSet( myUp, 0.0f, 1.0f, 0.0f ); - } - else if( normal[ 2 ] == -1.0f ) - { - VectorSet( myRt, -1.0f, 0.0f, 0.0f ); - VectorSet( myUp, 0.0f, 1.0f, 0.0f ); - } + FloodLightRawLightmapPass(lm, lm->floodlightRGB, lm->floodlightIntensity, lm->floodlightDistance, qfalse, lm->floodlightDirectionScale); + numSurfacesFloodlighten += 1; } - else - { - VectorSet( worldUp, 0.0f, 0.0f, 1.0f ); - CrossProduct( normal, worldUp, myRt ); - VectorNormalize( myRt, myRt ); - CrossProduct( myRt, normal, myUp ); - VectorNormalize( myUp, myUp ); - } - - /* iterate through ordered vectors */ - for( i = 0; i < numFloodVectors; i++ ) - { - if (floodlight_lowquality==qtrue) - { - if (rand()%10 != 0 ) continue; - } - - vecs++; +} - /* transform vector into tangent space */ - direction[ 0 ] = myRt[ 0 ] * floodVectors[ i ][ 0 ] + myUp[ 0 ] * floodVectors[ i ][ 1 ] + normal[ 0 ] * floodVectors[ i ][ 2 ]; - direction[ 1 ] = myRt[ 1 ] * floodVectors[ i ][ 0 ] + myUp[ 1 ] * floodVectors[ i ][ 1 ] + normal[ 1 ] * floodVectors[ i ][ 2 ]; - direction[ 2 ] = myRt[ 2 ] * floodVectors[ i ][ 0 ] + myUp[ 2 ] * floodVectors[ i ][ 1 ] + normal[ 2 ] * floodVectors[ i ][ 2 ]; +void FloodlightRawLightmaps() +{ + Sys_Printf( "--- FloodlightRawLightmap ---\n" ); + numSurfacesFloodlighten = 0; + RunThreadsOnIndividual( numRawLightmaps, qtrue, FloodLightRawLightmap ); + Sys_Printf( "%9d custom lightmaps floodlighted\n", numSurfacesFloodlighten ); +} - /* set endpoint */ - VectorMA( trace->origin, dd, direction, trace->end ); +/* +FloodLightIlluminate() +illuminate floodlight into lightmap luxels +*/ - //VectorMA( trace->origin, 1, direction, trace->origin ); +void FloodlightIlluminateLightmap( rawLightmap_t *lm ) +{ + float *luxel, *floodlight, *deluxel, *normal; + int *cluster; + float brightness; + vec3_t lightvector; + int x, y, lightmapNum; - SetupTrace( trace ); - /* trace */ - TraceLine( trace ); - contribution=1; + /* walk lightmaps */ + for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) + { + /* early out */ + if( lm->superLuxels[ lightmapNum ] == NULL ) + continue; - if (trace->compileFlags & C_SKY ) - { - contribution=1.0f; - } - else if ( trace->opaque ) + /* apply floodlight to each luxel */ + for( y = 0; y < lm->sh; y++ ) { - VectorSubtract( trace->hit, trace->origin, displacement ); - d=VectorLength( displacement ); - - // d=trace->distance; - //if (d>256) gatherDirt+=1; - contribution=d/dd; - if (contribution>1) contribution=1.0f; - - //gatherDirt += 1.0f - ooDepth * VectorLength( displacement ); - } - - gatherLight+=contribution; - } + for( x = 0; x < lm->sw; x++ ) + { + /* get floodlight */ + floodlight = SUPER_FLOODLIGHT( x, y ); + if (!floodlight[0] && !floodlight[1] && !floodlight[2]) + continue; + + /* get cluster */ + cluster = SUPER_CLUSTER( x, y ); - /* early out */ - if( gatherLight <= 0.0f ) - return 0.0f; + /* only process mapped luxels */ + if( *cluster < 0 ) + continue; - sub=vecs; + /* get particulars */ + luxel = SUPER_LUXEL( lightmapNum, x, y ); + deluxel = SUPER_DELUXEL( x, y ); - if (sub<1) sub=1; - gatherLight/=(sub); + /* add to lightmap */ + luxel[0]+=floodlight[0]; + luxel[1]+=floodlight[1]; + luxel[2]+=floodlight[2]; - outLight=gatherLight; - if( outLight > 1.0f ) - outLight = 1.0f; + if (luxel[3]==0) luxel[3]=1; - /* return to sender */ - return outLight; + /* add to deluxemap */ + if (deluxemap && floodlight[3] > 0) + { + 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]; + VectorScale( normal, brightness, lightvector ); + VectorAdd( deluxel, lightvector, deluxel ); + } + } + } + } } -