flags |= LIGHT_GRID;
flags &= ~LIGHT_SURFACES;
}
-
+
+ /* vortex: unnormalized? */
+ if (spawnflags & 32)
+ flags |= LIGHT_UNNORMALIZED;
+
+ /* vortex: distance atten? */
+ if (spawnflags & 64)
+ flags |= LIGHT_ATTEN_DISTANCE;
+
/* store the flags */
light->flags = flags;
if( _color && _color[ 0 ] )
{
sscanf( _color, "%f %f %f", &light->color[ 0 ], &light->color[ 1 ], &light->color[ 2 ] );
- ColorNormalize( light->color, light->color );
+ if (!(light->flags & LIGHT_UNNORMALIZED))
+ {
+ ColorNormalize( light->color, light->color );
+ }
}
else
light->color[ 0 ] = light->color[ 1 ] = light->color[ 2 ] = 1.0f;
-
+
intensity = intensity * pointScale;
light->photons = intensity;
-
+
light->type = EMIT_POINT;
/* set falloff threshold */
/* clear color */
VectorClear( trace->color );
+ VectorClear( trace->colorNoShadow );
/* ydnar: early out */
if( !(light->flags & LIGHT_SURFACES) || light->envelope <= 0.0f )
float d;
vec3_t pushedOrigin;
-
/* project sample point into light plane */
d = DotProduct( trace->origin, light->normal ) - light->dist;
if( d < 3.0f )
{
float distByNormal, radiusAtDist, sampleRadius;
vec3_t pointAtDist, distToSample;
-
-
+
/* do cone calculation */
distByNormal = -DotProduct( trace->displacement, light->normal );
if( distByNormal < 0.0f )
add = light->photons * angle;
if( add <= 0.0f )
return 0;
+
+ /* VorteX: set noShadow color */
+ VectorScale(light->color, add, trace->colorNoShadow);
/* setup trace */
trace->testAll = qtrue;
/* return to sender */
return 1;
}
+
+ /* VorteX: set noShadow color */
+ VectorScale(light->color, add, trace->colorNoShadow);
/* ydnar: changed to a variable number */
if( add <= 0.0f || (add <= light->falloffTolerance && (light->flags & LIGHT_FAST_ACTUAL)) )
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 > 0.5 )
return;
}
trace.normal[2]=-1;
}
- f = FloodLightForSample(&trace);
+ f = FloodLightForSample(&trace, floodlightDistance, floodlight_lowquality);
contributions[ numCon ].color[0]=col[0]*f;
contributions[ numCon ].color[1]=col[1]*f;
/////////////////////
/* 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;
/* ambient light will be at 1/4 the value of directed light */
/* (ydnar: nuke this in favor of more dramatic lighting?) */
+ /* (PM: how about actually making it work? d=1 when it got here for single lights/sun :P */
+// d = 0.25f;
+ /* (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 );
for( j = 0; j < 3; j++ )
if( color[ j ] < minGridLight[ j ] )
color[ j ] = minGridLight[ j ];
- ColorToBytes( color, bgp->ambient[ i ], 1.0f );
- ColorToBytes( gp->directed[ i ], bgp->directed[ i ], 1.0f );
+
+ /* vortex: apply gridscale and gridambientscale here */
+ ColorToBytes( color, bgp->ambient[ i ], gridScale*gridAmbientScale );
+ ColorToBytes( gp->directed[ i ], bgp->directed[ i ], gridScale );
}
/* debug code */
#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" );
+ ps = patchShadows;
+ patchShadows = qfalse; /* patch shadows + lightgrid sampling tends to sample between patch and caulk, so let's turn that off for now FIXME */
RunThreadsOnIndividual( numRawGridPoints, qtrue, TraceGrid );
+ patchShadows = ps;
Sys_Printf( "%d x %d x %d = %d grid\n",
gridBounds[ 0 ], gridBounds[ 1 ], gridBounds[ 2 ], numBSPGridPoints );
RunThreadsOnIndividual( numRawLightmaps, qtrue, DirtyRawLightmap );
}
- /* floodlight them up */
- if( floodlighty )
- {
- Sys_Printf( "--- FloodlightRawLightmap ---\n" );
- RunThreadsOnIndividual( numRawLightmaps, qtrue, FloodLightRawLightmap );
- }
+ /* floodlight pass */
+ FloodlightRawLightmaps();
/* ydnar: set up light envelopes */
SetupEnvelopes( qfalse, fast );
gridBoundsCulled = 0;
Sys_Printf( "--- BounceGrid ---\n" );
+ ps = patchShadows;
+ patchShadows = qfalse; /* patch shadows + lightgrid sampling tends to sample between patch and caulk, so let's turn that off for now FIXME */
RunThreadsOnIndividual( numRawGridPoints, qtrue, TraceGrid );
+ patchShadows = ps;
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 */
Sys_Printf( "--- Light ---\n" );
-
+ Sys_Printf( "--- ProcessGameSpecific ---\n" );
+
/* set standard game flags */
wolfLight = game->wolfLight;
+ if (wolfLight == qtrue)
+ Sys_Printf( " lightning model: wolf\n" );
+ else
+ Sys_Printf( " lightning model: quake3\n" );
+
lmCustomSize = game->lightmapSize;
+ Sys_Printf( " lightmap size: %d x %d pixels\n", lmCustomSize, lmCustomSize );
+
lightmapGamma = game->lightmapGamma;
+ Sys_Printf( " lightning gamma: %f\n", lightmapGamma );
+
lightmapCompensate = game->lightmapCompensate;
+ Sys_Printf( " lightning compensation: %f\n", lightmapCompensate );
+
+ lightmapExposure = game->lightmapExposure;
+ Sys_Printf( " lightning exposure: %f\n", lightmapExposure );
+
+ gridScale = game->gridScale;
+ Sys_Printf( " lightgrid scale: %f\n", gridScale );
+
+ gridAmbientScale = game->gridAmbientScale;
+ Sys_Printf( " lightgrid ambient scale: %f\n", gridAmbientScale );
+
+ noStyles = game->noStyles;
+ if (noStyles == qtrue)
+ Sys_Printf( " shader lightstyles hack: disabled\n" );
+ else
+ Sys_Printf( " shader lightstyles hack: enabled\n" );
+
+ keepLights = game->keepLights;
+ if (keepLights == qtrue)
+ Sys_Printf( " keep lights: enabled\n" );
+ else
+ Sys_Printf( " keep lights: disabled\n" );
+
+ patchShadows = game->patchShadows;
+ if (patchShadows == qtrue)
+ Sys_Printf( " patch shadows: enabled\n" );
+ else
+ Sys_Printf( " patch shadows: disabled\n" );
+
+ deluxemap = game->deluxeMap;
+ deluxemode = game->deluxeMode;
+ if (deluxemap == qtrue)
+ {
+ if (deluxemode)
+ Sys_Printf( " deluxemapping: enabled with tangentspace deluxemaps\n" );
+ else
+ Sys_Printf( " deluxemapping: enabled with modelspace deluxemaps\n" );
+ }
+ else
+ Sys_Printf( " deluxemapping: disabled\n" );
+
+ Sys_Printf( "--- ProcessCommandLine ---\n" );
/* process commandline arguments */
for( i = 1; i < (argc - 1); i++ )
Sys_Printf( "All light scaled by %f\n", f );
i++;
}
+
+ else if( !strcmp( argv[ i ], "-gridscale" ) )
+ {
+ f = atof( argv[ i + 1 ] );
+ Sys_Printf( "Grid lightning scaled by %f\n", f );
+ gridScale *= f;
+ i++;
+ }
+
+ else if( !strcmp( argv[ i ], "-gridambientscale" ) )
+ {
+ f = atof( argv[ i + 1 ] );
+ Sys_Printf( "Grid ambient lightning scaled by %f\n", f );
+ 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" ) )
{
Sys_Printf( "Dark lightmap seams enabled\n" );
}
-
-
-
-
-
-
else if( !strcmp( argv[ i ], "-shadeangle" ) )
{
shadeAngleDegrees = atof( argv[ i + 1 ] );
Sys_Printf( "Approximating lightmaps within a byte tolerance of %d\n", approximateTolerance );
i++;
}
-
else if( !strcmp( argv[ i ], "-deluxe" ) || !strcmp( argv[ i ], "-deluxemap" ) )
{
deluxemap = qtrue;
Sys_Printf( "Generating deluxemaps for average light direction\n" );
}
-
+ else if( !strcmp( argv[ i ], "-deluxemode" ))
+ {
+ deluxemode = atoi( argv[ i + 1 ] );
+ if (deluxemode == 0 || deluxemode > 1 || deluxemode < 0)
+ {
+ Sys_Printf( "Generating modelspace deluxemaps\n" );
+ deluxemode = 0;
+ }
+ else
+ Sys_Printf( "Generating tangentspace deluxemaps\n" );
+ i++;
+ }
+ else if( !strcmp( argv[ i ], "-nodeluxe" ) || !strcmp( argv[ i ], "-nodeluxemap" ) )
+ {
+ deluxemap = qfalse;
+ Sys_Printf( "Disabling generating of deluxemaps for average light direction\n" );
+ }
else if( !strcmp( argv[ i ], "-external" ) )
{
externalLightmaps = qtrue;
}
}
+ 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];
+ i++;
+ Sys_Printf( "Lightmap directory set to %s\n", lmCustomDir );
+ externalLightmaps = qtrue;
+ Sys_Printf( "Storing all lightmaps externally\n" );
+ }
+
/* ydnar: add this to suppress warnings */
else if( !strcmp( argv[ i ], "-custinfoparms") )
{
noCollapse = qtrue;
Sys_Printf( "Identical lightmap collapsing disabled\n" );
}
+
+ else if( !strcmp( argv[ i ], "-nolightmapsearch" ) )
+ {
+ 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" ) )
{
i++;
Sys_Printf( "Minimum lightmap sample size set to %dx%d units\n", minSampleSize, minSampleSize );
}
+ else if( !strcmp( argv[ i ], "-samplescale" ) )
+ {
+ sampleScale = atoi( argv[ i + 1 ] );
+ i++;
+ Sys_Printf( "Lightmaps sample scale set to %d\n", sampleScale);
+ }
else if( !strcmp( argv[ i ], "-novertex" ) )
{
noVertexLighting = qtrue;
noStyles = qtrue;
Sys_Printf( "Disabling lightstyles\n" );
}
+ else if( !strcmp( argv[ i ], "-style" ) || !strcmp( argv[ i ], "-styles" ) )
+ {
+ noStyles = qfalse;
+ Sys_Printf( "Enabling lightstyles\n" );
+ }
+ else if( !strcmp( argv[ i ], "-keeplights" ))
+ {
+ keepLights = qtrue;
+ Sys_Printf( "Leaving light entities on map after compile\n" );
+ }
else if( !strcmp( argv[ i ], "-cpma" ) )
{
cpmaHack = 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 ] ) );