dist = 16.0f;
/* angle attenuation */
- angle = (light->flags & LIGHT_ATTEN_ANGLE) ? DotProduct( trace->normal, trace->direction ) : 1.0f;
+ if( light->flags & LIGHT_ATTEN_ANGLE )
+ {
+ /* standard Lambert attenuation */
+ float dot = DotProduct( trace->normal, trace->direction );
+
+ /* twosided lighting */
+ if( trace->twoSided )
+ dot = fabs( dot );
+
+ /* jal: optional half Lambert attenuation (http://developer.valvesoftware.com/wiki/Half_Lambert) */
+ if( lightAngleHL )
+ {
+ if( dot > 0.001f ) // skip coplanar
+ {
+ if( dot > 1.0f ) dot = 1.0f;
+ dot = ( dot * 0.5f ) + 0.5f;
+ dot *= dot;
+ }
+ else
+ dot = 0;
+ }
+
+ angle = dot;
+ }
+ else
+ angle = 1.0f;
+
if( light->angleScale != 0.0f )
{
angle /= light->angleScale;
angle = 1.0f;
}
- /* twosided lighting */
- if( trace->twoSided )
- angle = fabs( angle );
-
/* attenuate */
if( light->flags & LIGHT_ATTEN_LINEAR )
{
/* get origin and direction */
VectorAdd( trace->origin, light->origin, trace->end );
dist = SetupTrace( trace );
-
+
/* angle attenuation */
- angle = (light->flags & LIGHT_ATTEN_ANGLE)
- ? DotProduct( trace->normal, trace->direction )
- : 1.0f;
-
- /* twosided lighting */
- if( trace->twoSided )
- angle = fabs( angle );
+ if( light->flags & LIGHT_ATTEN_ANGLE )
+ {
+ /* standard Lambert attenuation */
+ float dot = DotProduct( trace->normal, trace->direction );
+
+ /* twosided lighting */
+ if( trace->twoSided )
+ dot = fabs( dot );
+
+ /* jal: optional half Lambert attenuation (http://developer.valvesoftware.com/wiki/Half_Lambert) */
+ if( lightAngleHL )
+ {
+ if( dot > 0.001f ) // skip coplanar
+ {
+ if( dot > 1.0f ) dot = 1.0f;
+ dot = ( dot * 0.5f ) + 0.5f;
+ dot *= dot;
+ }
+ else
+ dot = 0;
+ }
+
+ angle = dot;
+ }
+ else
+ angle = 1.0f;
/* attenuate */
add = light->photons * angle;
of dynamically placed entities in the world
*/
-#define MAX_CONTRIBUTIONS 1024
+#define MAX_CONTRIBUTIONS 32768
typedef struct
{
void TraceGrid( int num )
{
- int i, j, x, y, z, mod, step, numCon, numStyles;
- float d;
- vec3_t baseOrigin, cheapColor, color;
+ int i, j, x, y, z, mod, numCon, numStyles;
+ float d, step;
+ vec3_t baseOrigin, cheapColor, color, thisdir;
rawGridPoint_t *gp;
bspGridPoint_t *bgp;
contribution_t contributions[ MAX_CONTRIBUTIONS ];
trace_t trace;
-
/* get grid points */
gp = &rawGridPoints[ num ];
bgp = &bspGridPoints[ num ];
{
/* try to nudge the origin around to find a valid point */
VectorCopy( trace.origin, baseOrigin );
- for( step = 9; step <= 18; step += 9 )
+ for( step = 0; (step += 0.005) <= 1.0; )
{
- for( i = 0; i < 8; i++ )
- {
- VectorCopy( baseOrigin, trace.origin );
- if( i & 1 )
- trace.origin[ 0 ] += step;
- else
- trace.origin[ 0 ] -= step;
-
- if( i & 2 )
- trace.origin[ 1 ] += step;
- else
- trace.origin[ 1 ] -= step;
-
- if( i & 4 )
- trace.origin[ 2 ] += step;
- else
- trace.origin[ 2 ] -= step;
+ VectorCopy( baseOrigin, trace.origin );
+ trace.origin[ 0 ] += step * (Random() - 0.5) * gridSize[0];
+ trace.origin[ 1 ] += step * (Random() - 0.5) * gridSize[1];
+ trace.origin[ 2 ] += step * (Random() - 0.5) * gridSize[2];
- /* ydnar: changed to find cluster num */
- trace.cluster = ClusterForPointExt( trace.origin, VERTEX_EPSILON );
- if( trace.cluster >= 0 )
- break;
- }
-
- if( i != 8 )
+ /* ydnar: changed to find cluster num */
+ trace.cluster = ClusterForPointExt( trace.origin, VERTEX_EPSILON );
+ if( trace.cluster >= 0 )
break;
}
/* can't find a valid point at all */
- if( step > 18 )
+ if( step > 1.0 )
return;
}
/////////////////////
/* normalize to get primary light direction */
- VectorNormalize( gp->dir, gp->dir );
+ VectorNormalize( gp->dir, thisdir );
/* now that we have identified the primary light direction,
go back and separate all the light into directed and ambient */
+
numStyles = 1;
for( i = 0; i < numCon; i++ )
{
/* get relative directed strength */
- d = DotProduct( contributions[ i ].dir, gp->dir );
+ d = DotProduct( contributions[ i ].dir, thisdir );
+ /* we map 1 to gridDirectionality, and 0 to gridAmbientDirectionality */
+ d = gridAmbientDirectionality + d * (gridDirectionality - gridAmbientDirectionality);
if( d < 0.0f )
d = 0.0f;
/* (Hobbes: always setting it to .25 is hardly any better) */
d = 0.25f * (1.0f - d);
VectorMA( gp->ambient[ j ], d, contributions[ i ].color, gp->ambient[ j ] );
+
+/*
+ * div0:
+ * the total light average = ambient value + 0.25 * sum of all directional values
+ * we can also get the total light average as 0.25 * the sum of all contributions
+ *
+ * 0.25 * sum(contribution_i) == ambient + 0.25 * sum(d_i contribution_i)
+ *
+ * THIS YIELDS:
+ * ambient == 0.25 * sum((1 - d_i) contribution_i)
+ *
+ * So, 0.25f * (1.0f - d) IS RIGHT. If you want to tune it, tune d BEFORE.
+ */
}
/* store off sample */
for( i = 0; i < MAX_LIGHTMAPS; i++ )
{
+#if 0
/* do some fudging to keep the ambient from being too low (2003-07-05: 0.25 -> 0.125) */
if( !bouncing )
VectorMA( gp->ambient[ i ], 0.125f, gp->directed[ i ], gp->ambient[ i ] );
+#endif
/* set minimum light and copy off to bytes */
VectorCopy( gp->ambient[ i ], color );
#endif
/* store direction */
- if( !bouncing )
- NormalToLatLong( gp->dir, bgp->latLong );
+ NormalToLatLong( thisdir, bgp->latLong );
}
vec3_t color;
float f;
int b, bt;
- qboolean minVertex, minGrid;
+ qboolean minVertex, minGrid, ps;
const char *value;
SetupEnvelopes( qtrue, fastgrid );
Sys_Printf( "--- TraceGrid ---\n" );
+ inGrid = qtrue;
RunThreadsOnIndividual( numRawGridPoints, qtrue, TraceGrid );
+ inGrid = qfalse;
Sys_Printf( "%d x %d x %d = %d grid\n",
gridBounds[ 0 ], gridBounds[ 1 ], gridBounds[ 2 ], numBSPGridPoints );
gridBoundsCulled = 0;
Sys_Printf( "--- BounceGrid ---\n" );
+ inGrid = qtrue;
RunThreadsOnIndividual( numRawGridPoints, qtrue, TraceGrid );
+ inGrid = qfalse;
Sys_FPrintf( SYS_VRB, "%9d grid points envelope culled\n", gridEnvelopeCulled );
Sys_FPrintf( SYS_VRB, "%9d grid points bounds culled\n", gridBoundsCulled );
}
float f;
char mapSource[ 1024 ];
const char *value;
+ int lightmapMergeSize = 0;
/* note it */
gridAmbientScale = game->gridAmbientScale;
Sys_Printf( " lightgrid ambient scale: %f\n", gridAmbientScale );
+ lightAngleHL = game->lightAngleHL;
+ if( lightAngleHL )
+ Sys_Printf( " half lambert light angle attenuation enabled \n" );
+
noStyles = game->noStyles;
if (noStyles == qtrue)
Sys_Printf( " shader lightstyles hack: disabled\n" );
gridAmbientScale *= f;
i++;
}
+
+ else if( !strcmp( argv[ i ], "-griddirectionality" ) )
+ {
+ f = atof( argv[ i + 1 ] );
+ if(f < 0) f = 0;
+ if(f > gridAmbientDirectionality) f = gridAmbientDirectionality;
+ Sys_Printf( "Grid directionality is %f\n", 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;
+ Sys_Printf( "Grid ambient directionality is %f\n", f );
+ gridAmbientDirectionality *= f;
+ i++;
+ }
else if( !strcmp( argv[ i ], "-gamma" ) )
{
}
}
+ else if( !strcmp( argv[ i ], "-rawlightmapsizelimit" ) )
+ {
+ lmLimitSize = atoi( argv[ i + 1 ] );
+
+ i++;
+ Sys_Printf( "Raw lightmap size limit set to %d x %d pixels\n", lmLimitSize, lmLimitSize );
+ }
+
else if( !strcmp( argv[ i ], "-lightmapdir" ) )
{
lmCustomDir = argv[i + 1];
else if( !strcmp( argv[ i ], "-nolightmapsearch" ) )
{
- noLightmapSearch = qtrue;
+ lightmapSearchBlockSize = 1;
Sys_Printf( "No lightmap searching - all lightmaps will be sequential\n" );
}
+ else if( !strcmp( argv[ i ], "-lightmapsearchpower" ) )
+ {
+ lightmapMergeSize = (game->lightmapSize << atoi(argv[i+1]));
+ ++i;
+ Sys_Printf( "Restricted lightmap searching enabled - optimize for lightmap merge power %d (size %d)\n", atoi(argv[i]), lightmapMergeSize );
+ }
+
+ else if( !strcmp( argv[ i ], "-lightmapsearchblocksize" ) )
+ {
+ lightmapSearchBlockSize = atoi(argv[i+1]);
+ ++i;
+ Sys_Printf( "Restricted lightmap searching enabled - block size set to %d\n", lightmapSearchBlockSize );
+ }
+
else if( !strcmp( argv[ i ], "-shade" ) )
{
shade = qtrue;
loMem = qtrue;
Sys_Printf( "Enabling low-memory (potentially slower) lighting mode\n" );
}
+ else if( !strcmp( argv[ i ], "-lightanglehl" ) )
+ {
+ if( ( atoi( argv[ i + 1 ] ) != 0 ) != lightAngleHL )
+ {
+ lightAngleHL = ( atoi( argv[ i + 1 ] ) != 0 );
+ if( lightAngleHL )
+ Sys_Printf( "Enabling half lambert light angle attenuation\n" );
+ else
+ Sys_Printf( "Disabling half lambert light angle attenuation\n" );
+ }
+ }
else if( !strcmp( argv[ i ], "-nostyle" ) || !strcmp( argv[ i ], "-nostyles" ) )
{
noStyles = qtrue;
}
}
+
+ /* fix up lightmap search power */
+ if(lightmapMergeSize)
+ {
+ lightmapSearchBlockSize = (lightmapMergeSize / lmCustomSize) * (lightmapMergeSize / lmCustomSize);
+ if(lightmapSearchBlockSize < 1)
+ lightmapSearchBlockSize = 1;
+
+ Sys_Printf( "Restricted lightmap searching enabled - block size adjusted to %d\n", lightmapSearchBlockSize );
+ }
/* clean up map name */
strcpy( source, ExpandArg( argv[ i ] ) );