Increase the influence of directional lights on the deluxemap by a)Ignoring angle...
authorjal <germangar@gmail.com>
Fri, 30 Apr 2010 09:32:11 +0000 (11:32 +0200)
committerjal <germangar@gmail.com>
Fri, 30 Apr 2010 09:32:11 +0000 (11:32 +0200)
libs/mathlib.h
tools/quake3/q3map2/light.c
tools/quake3/q3map2/light_ydnar.c
tools/quake3/q3map2/lightmaps_ydnar.c
tools/quake3/q3map2/model.c
tools/quake3/q3map2/q3map2.h

index bbf026d452e6c5825b463bcc3ed73b72c1b1d9b2..c2e2ed7589835a08ac4b750a4aa1c552449a4229 100644 (file)
@@ -77,6 +77,8 @@ extern const vec3_t g_vec3_axis_z;
 #define FLOAT_SNAP(f,snap) ( (float)( floor( (f) / (snap) + 0.5 ) * (snap) ) )
 #define FLOAT_TO_INTEGER(f) ( (float)( floor( (f) + 0.5 ) ) )
 
+#define RGBTOGRAY(x) ( (x)[0] * 0.2989f + (x)[1] * 0.5870f + (x)[2] * 0.1140f )
+
 #define Q_rint(in) ((vec_t)floor(in+0.5))
 
 qboolean VectorCompare (const vec3_t v1, const vec3_t v2);
index a47fee4cefe3bc919846b4b200f939acf9acf818..cf292a79ecfa088498e244f1e120d2671f021fb8 100644 (file)
@@ -749,7 +749,9 @@ int LightContributionToSample( trace_t *trace )
        float                   angle;
        float                   add;
        float                   dist;
-       
+       float                   addDeluxe = 0.0f, addDeluxeBounceScale = 0.25f;\r
+       qboolean                angledDeluxe = qfalse;\r
+       float                   colorBrightness;
        
        /* get light */
        light = trace->light;
@@ -757,6 +759,9 @@ int LightContributionToSample( trace_t *trace )
        /* clear color */
        VectorClear( trace->color );
        VectorClear( trace->colorNoShadow );
+       VectorClear( trace->directionContribution );\r
+\r
+       colorBrightness = RGBTOGRAY( light->color ) * ( 1.0f/255.0f );
        
        /* ydnar: early out */
        if( !(light->flags & LIGHT_SURFACES) || light->envelope <= 0.0f )
@@ -796,7 +801,7 @@ int LightContributionToSample( trace_t *trace )
                }
                
                /* nudge the point so that it is clearly forward of the light */
-               /* so that surfaces meeting a light emiter don't get black edges */
+               /* so that surfaces meeting a light emitter don't get black edges */
                if( d > -8.0f && d < 8.0f )
                        VectorMA( trace->origin, (8.0f - d), light->normal, pushedOrigin );                             
                else
@@ -832,6 +837,14 @@ int LightContributionToSample( trace_t *trace )
                                dist = 16.0f;
 
                        add = light->photons / (dist * dist) * angle;
+
+                       if( deluxemap )\r
+                       {\r
+                               if( angledDeluxe )\r
+                                       addDeluxe = light->photons / (dist * dist) * angle;\r
+                               else\r
+                                       addDeluxe = light->photons / (dist * dist);\r
+                       }
                }
                else
                {
@@ -858,6 +871,9 @@ int LightContributionToSample( trace_t *trace )
                        
                        /* ydnar: moved to here */
                        add = factor * light->add;
+
+                       if( deluxemap )\r
+                               addDeluxe = add;
                }
        }
        
@@ -916,9 +932,35 @@ int LightContributionToSample( trace_t *trace )
                        add = angle * light->photons * linearScale - (dist * light->fade);
                        if( add < 0.0f )
                                add = 0.0f;
+
+                       if( deluxemap )\r
+                       {\r
+                               if( angledDeluxe )\r
+                                       addDeluxe = angle * light->photons * linearScale - (dist * light->fade);\r
+                               else\r
+                                       addDeluxe = light->photons * linearScale - (dist * light->fade);\r
+\r
+                               if( addDeluxe < 0.0f )\r
+                                       addDeluxe = 0.0f;\r
+                       }
                }
                else
+               {
                        add = (light->photons / (dist * dist)) * angle;
+                       if( add < 0.0f )\r
+                               add = 0.0f;\r
+\r
+                       if( deluxemap )\r
+                       {\r
+                               if( angledDeluxe )\r
+                                       addDeluxe = (light->photons / (dist * dist)) * angle;\r
+                               else\r
+                                       addDeluxe = (light->photons / (dist * dist));\r
+                       }\r
+\r
+                       if( addDeluxe < 0.0f )\r
+                               addDeluxe = 0.0f;
+               }
                
                /* handle spotlights */
                if( light->type == EMIT_SPOT )
@@ -941,7 +983,16 @@ int LightContributionToSample( trace_t *trace )
                        
                        /* attenuate */
                        if( sampleRadius > (radiusAtDist - 32.0f) )
+                       {
                                add *= ((radiusAtDist - sampleRadius) / 32.0f);
+                               if( add < 0.0f )\r
+                                       add = 0.0f;\r
+\r
+                               addDeluxe *= ((radiusAtDist - sampleRadius) / 32.0f);\r
+\r
+                               if( addDeluxe < 0.0f )\r
+                                       addDeluxe = 0.0f;
+                       }
                }
        }
        
@@ -982,11 +1033,34 @@ int LightContributionToSample( trace_t *trace )
                
                /* attenuate */
                add = light->photons * angle;
+
+               if( deluxemap )\r
+               {\r
+                       if( angledDeluxe )\r
+                               addDeluxe = light->photons * angle;\r
+                       else\r
+                               addDeluxe = light->photons;\r
+\r
+                       if( addDeluxe < 0.0f )\r
+                               addDeluxe = 0.0f;\r
+               }
+
                if( add <= 0.0f )
                        return 0;
 
                /* VorteX: set noShadow color */
                VectorScale(light->color, add, trace->colorNoShadow);
+
+               addDeluxe *= colorBrightness;\r
+\r
+               if( bouncing )\r
+               {\r
+                       addDeluxe *= addDeluxeBounceScale;\r
+                       if( addDeluxe < 0.00390625f )\r
+                               addDeluxe = 0.00390625f;\r
+               }\r
+\r
+               VectorScale( trace->direction, addDeluxe, trace->directionContribution );
                
                /* setup trace */
                trace->testAll = qtrue;
@@ -1000,6 +1074,8 @@ int LightContributionToSample( trace_t *trace )
                        if( !(trace->compileFlags & C_SKY) || trace->opaque )
                        {
                                VectorClear( trace->color );
+                               VectorClear( trace->directionContribution );
+
                                return -1;
                        }
                }
@@ -1014,6 +1090,29 @@ int LightContributionToSample( trace_t *trace )
        /* ydnar: changed to a variable number */
        if( add <= 0.0f || (add <= light->falloffTolerance && (light->flags & LIGHT_FAST_ACTUAL)) )
                return 0;
+
+       addDeluxe *= colorBrightness;\r
+\r
+       /* hack land: scale down the radiosity contribution to light directionality.\r
+       Deluxemaps fusion many light directions into one. In a rtl process all lights\r
+       would contribute individually to the bump map, so several light sources together\r
+       would make it more directional (example: a yellow and red lights received from\r
+       opposing sides would light one side in red and the other in blue, adding\r
+       the effect of 2 directions applied. In the deluxemapping case, this 2 lights would\r
+       neutralize each other making it look like having no direction.\r
+       Same thing happens with radiosity. In deluxemapping case the radiosity contribution\r
+       is modifying the direction applied from directional lights, making it go closer and closer\r
+       to the surface normal the bigger is the amount of radiosity received.\r
+       So, for preserving the directional lights contributions, we scale down the radiosity\r
+       contribution. It's a hack, but there's a reason behind it */\r
+       if( bouncing )\r
+       {\r
+               addDeluxe *= addDeluxeBounceScale;\r
+               if( addDeluxe < 0.00390625f )\r
+                       addDeluxe = 0.00390625f;\r
+       }\r
+\r
+       VectorScale( trace->direction, addDeluxe, trace->directionContribution );
        
        /* setup trace */
        trace->testAll = qfalse;
@@ -1024,6 +1123,8 @@ int LightContributionToSample( trace_t *trace )
        if( trace->passSolid || trace->opaque )
        {
                VectorClear( trace->color );
+               VectorClear( trace->directionContribution );\r
+
                return -1;
        }
        
index dac94b62f03bc55263f49987caec8fcfdc853246..d26b05e57e667195c658d9d98d1f5431a89c73d5 100644 (file)
@@ -2006,11 +2006,12 @@ void IlluminateRawLightmap( int rawLightmapNum )
                                        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;
@@ -2094,23 +2095,14 @@ void IlluminateRawLightmap( int rawLightmapNum )
                                                LightContributionToSample( &trace );
                                                VectorCopy( trace.color, lightLuxel );
 
+                                               /* add the contribution to the deluxemap */\r
+                                               if( deluxemap )\r
+                                                       VectorAdd( deluxel, trace.directionContribution, deluxel );
+
                                                /* 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
-                                               {
-                                                       /* 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 );
-                                               }
-                                       }
                                }
                        }
                        
@@ -2442,6 +2434,7 @@ void IlluminateRawLightmap( int rawLightmapNum )
                                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;
                                
@@ -4194,8 +4187,7 @@ void FloodlightIlluminateLightmap( rawLightmap_t *lm )
                                        vec3_t                          lightvector;\r
 \r
                                        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];\r
+                                       brightness = RGBTOGRAY( floodlight ) * ( 1.0f/255.0f ) * floodlight[3];\r
 \r
                                        // use AT LEAST this amount of contribution from ambient for the deluxemap, fixes points that receive ZERO light\r
                                        if(brightness < 0.00390625f)\r
index 59076366b5f797d82446887fc91124afaa01faa2..58938880f943328603b785ae94eb4e32bd4c499c 100644 (file)
@@ -1921,7 +1921,7 @@ for a given surface lightmap, find output lightmap pages and positions for it
 #define LIGHTMAP_RESERVE_COUNT 1
 static void FindOutLightmaps( rawLightmap_t *lm )
 {
-       int                                     i, j, k, lightmapNum, xMax, yMax, x, y, sx, sy, ox, oy, offset, temp;
+       int                                     i, j, k, lightmapNum, xMax, yMax, x, y, sx, sy, ox, oy, offset;
        outLightmap_t           *olm;
        surfaceInfo_t           *info;
        float                           *luxel, *deluxel;
@@ -2193,21 +2193,12 @@ static void FindOutLightmaps( rawLightmap_t *lm )
                                if( deluxemap )
                                {
                                        /* normalize average light direction */
-                                       if( VectorNormalize( deluxel, direction ) )
-                                       {
-                                               /* encode [-1,1] in [0,255] */
-                                               pixel = olm->bspDirBytes + (((oy * olm->customWidth) + ox) * 3);
-                                               for( i = 0; i < 3; i++ )
-                                               {
-                                                       temp = (direction[ i ] + 1.0f) * 127.5f;
-                                                       if( temp < 0 )
-                                                               pixel[ i ] = 0;
-                                                       else if( temp > 255 )
-                                                               pixel[ i ] = 255;
-                                                       else
-                                                               pixel[ i ] = temp;
-                                               }
-                                       }
+                                       pixel = olm->bspDirBytes + (((oy * olm->customWidth) + ox) * 3);\r
+                                       VectorScale( deluxel, 1000.0f, direction );\r
+                                       VectorNormalize( direction, direction );\r
+                                       VectorScale( direction, 127.5f, direction );\r
+                                       for( i = 0; i < 3; i++ )\r
+                                               pixel[ i ] = (byte)( 127.5f + direction[ i ] );
                                }
                        }
                }
index 2e391379018633703d071708290f8439fd63f36e..9be630558c781225489224376ccc747ea0c57826 100644 (file)
@@ -401,7 +401,7 @@ void InsertModel( char *name, int frame, m4x4_t transform, remap_t *remap, shade
                                        dv->color[ j ][ 0 ] = 255.0f;
                                        dv->color[ j ][ 1 ] = 255.0f;
                                        dv->color[ j ][ 2 ] = 255.0f;
-                                       dv->color[ j ][ 3 ] = color[ 0 ] * 0.3f + color[ 1 ] * 0.59f + color[ 2 ] * 0.11f;
+                                       dv->color[ j ][ 3 ] = RGBTOGRAY( color );
                                }
                                else
                                {
index 5db3b8cd5095056c5abdaa03431244f01df2ee47..644a0510ab14a1b4893d3cc3271bd9140d2bb693 100644 (file)
@@ -1351,6 +1351,7 @@ typedef struct
        /* input and output */
        vec3_t                          color;                  /* starts out at full color, may be reduced if transparent surfaces are crossed */
        vec3_t                          colorNoShadow;  /* result color with no shadow casting */
+       vec3_t                          directionContribution; /* result contribution to the deluxe map */
 
        /* output */
        vec3_t                          hit;