]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - tools/quake3/q3map2/light_ydnar.c
apply all of VorteX's changes except deviance (that one sucks :P)
[xonotic/netradiant.git] / tools / quake3 / q3map2 / light_ydnar.c
index e11f3400b893b453e8453417af071da9da0db5d2..254a8c97bd1c60d596777d8d8870a60f5f3a0962 100644 (file)
@@ -1562,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;
@@ -2010,6 +2010,9 @@ void IlluminateRawLightmap( int rawLightmapNum )
                                        {
                                                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;
@@ -2101,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 );
+                                               }
                                        }
                                }
                        }
@@ -2340,53 +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;
-
-                                       brightness = flood[ 0 ] * 0.3f + flood[ 1 ] * 0.59f + flood[ 2 ] * 0.11f;
-                                       brightness *= (1.0 / 255.0);
-                                       VectorScale( normal, brightness, temp );
-                                       VectorAdd( deluxel, temp, deluxel );
-                               }
-                       }
-               }
-       }
+       /* floodlight pass */
+       FloodlightIlluminateLightmap(lm);
 
        if (debugnormals)
        {
@@ -2395,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++ )
@@ -2404,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;
@@ -2416,7 +2377,7 @@ void IlluminateRawLightmap( int rawLightmapNum )
                        }
                }
        }
-
+       
        /*      -----------------------------------------------------------------
                dirt pass
                ----------------------------------------------------------------- */
@@ -3899,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;
@@ -3927,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 )
                {
@@ -3942,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++ )
@@ -3953,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++ )
        {
@@ -3983,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;
@@ -3992,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 );
-               }
-       }
-       else
-       {
-               VectorSet( worldUp, 0.0f, 0.0f, 1.0f );
-               CrossProduct( normal, worldUp, myRt );
-               VectorNormalize( myRt, myRt );
-               CrossProduct( myRt, normal, myUp );
-               VectorNormalize( myUp, myUp );
+               FloodLightRawLightmapPass(lm, lm->floodlightRGB, lm->floodlightIntensity, lm->floodlightDistance, qfalse, lm->floodlightDirectionScale);
+               numSurfacesFloodlighten += 1;
        }
+}
 
-       /* 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 );
+                               }
+                       }
+               }
+       }
 }
-