sample[ i ] = pow( sample[ i ] / 255.0f, gamma ) * 255.0f;
}
- if (lightmapExposure == 1)
+ if (lightmapExposure == 0)
{
/* clamp with color normalization */
max = sample[ 0 ];
}
else
{
- if (lightmapExposure==0)
- {
- lightmapExposure=1.0f;
- }
inv=1.f/lightmapExposure;
//Exposure
/* compensate for ingame overbrighting/bitshifting */
VectorScale( sample, (1.0f / lightmapCompensate), sample );
+
+ /* sRGB lightmaps */
+ if(lightmapsRGB)
+ {
+ sample[0] = floor(Image_sRGBFloatFromLinearFloat(sample[0] * (1.0 / 255.0)) * 255.0 + 0.5);
+ sample[1] = floor(Image_sRGBFloatFromLinearFloat(sample[1] * (1.0 / 255.0)) * 255.0 + 0.5);
+ sample[2] = floor(Image_sRGBFloatFromLinearFloat(sample[2] * (1.0 / 255.0)) * 255.0 + 0.5);
+ }
/* store it off */
colorBytes[ 0 ] = sample[ 0 ];
if( MapQuad( lm, info, dv ) )
continue;
- /* get drawverts and map first triangle */
- MapTriangle( lm, info, dv, mapNonAxial );
-
- /* get drawverts and map second triangle */
- dv[ 1 ] = &verts[ pw[ r + 2 ] ];
- dv[ 2 ] = &verts[ pw[ r + 3 ] ];
- MapTriangle( lm, info, dv, mapNonAxial );
+ for( mapNonAxial = 0; mapNonAxial < 2; mapNonAxial++ )
+ {
+ /* get drawverts and map first triangle */
+ dv[ 1 ] = &verts[ pw[ r + 1 ] ];
+ dv[ 2 ] = &verts[ pw[ r + 2 ] ];
+ MapTriangle( lm, info, dv, mapNonAxial );
+
+ /* get drawverts and map second triangle */
+ dv[ 1 ] = &verts[ pw[ r + 2 ] ];
+ dv[ 2 ] = &verts[ pw[ r + 3 ] ];
+ MapTriangle( lm, info, dv, mapNonAxial );
+ }
}
}
/* trace */
TraceLine( trace );
- if( trace->opaque )
+ if( trace->opaque && !(trace->compileFlags & C_SKY) )
{
VectorSubtract( trace->hit, trace->origin, displacement );
gatherDirt += 1.0f - ooDepth * VectorLength( displacement );
trace.recvShadows = lm->recvShadows;
trace.numSurfaces = lm->numLightSurfaces;
trace.surfaces = &lightSurfaces[ lm->firstLightSurface ];
- trace.inhibitRadius = DEFAULT_INHIBIT_RADIUS;
- trace.testAll = qtrue;
+ trace.inhibitRadius = 0.0f;
+ trace.testAll = qfalse;
/* twosided lighting (may or may not be a good idea for lightmapped stuff) */
trace.twoSided = qfalse;
//% normal2 = SUPER_NORMAL( x, y );
}
else
- Sys_Printf( "WARNING: Spurious lightmap S vector\n" );
+ {
+ Error( "Spurious lightmap S vector\n" );
+ }
VectorSubtract( origin2, origin, originVecs[ 0 ] );
//% VectorSubtract( normal2, normal, normalVecs[ 0 ] );
vec3_t deluxel[ 3 ];
vec3_t origin[ 4 ], normal[ 4 ];
float biasDirs[ 4 ][ 2 ] = { { -1.0f, -1.0f }, { 1.0f, -1.0f }, { -1.0f, 1.0f }, { 1.0f, 1.0f } };
- vec3_t color, direction, total;
+ vec3_t color, direction = { 0, 0, 0 }, total;
/* limit check */
//% VectorClear( color );
//% samples = 0;
VectorCopy( lightLuxel, color );
- VectorCopy( lightDeluxel, direction );
+ if(lightDeluxel)
+ {
+ VectorCopy( lightDeluxel, direction );
+ }
samples = 1;
for( b = 0; b < 4; b++ )
{
float dx, dy;
VectorClear( total );
+ VectorClear( totaldirection );
mapped = 0;
for(b = 0; b < lightSamples; ++b)
{
/* set origin */
VectorCopy( sampleOrigin, origin );
GaussLikeRandom(bias, &dx, &dy);
- if(dx > 1) dx = 1;
- if(dy > 1) dy = 1;
- if(dx < -1) dx = -1;
- if(dy < -1) dy = -1;
/* calculate position */
if( !SubmapRawLuxel( lm, x, y, dx, dy, &cluster, origin, normal ) )
void IlluminateRawLightmap( int rawLightmapNum )
{
- int i, t, x, y, sx, sy, size, llSize, ldSize, luxelFilterRadius, lightmapNum;
+ int i, t, x, y, sx, sy, size, luxelFilterRadius, lightmapNum;
int *cluster, *cluster2, mapped, lighted, totalLighted;
+ size_t llSize, ldSize;
rawLightmap_t *lm;
surfaceInfo_t *info;
qboolean filterColor, filterDir;
/* subsample it */
if(lightRandomSamples)
- RandomSubsampleRawLuxel( lm, &trace, origin, sx, sy, 0.5f, lightLuxel, deluxemap ? lightDeluxel : NULL );
+ RandomSubsampleRawLuxel( lm, &trace, origin, sx, sy, 0.5f * lightSamplesSearchBoxSize, lightLuxel, deluxemap ? lightDeluxel : NULL );
else
SubsampleRawLuxel_r( lm, &trace, origin, sx, sy, 0.25f * lightSamplesSearchBoxSize, lightLuxel, deluxemap ? lightDeluxel : NULL );
radVertLuxel[ 2 ] <= ambientColor[ 2 ] )
{
/* nudge the sample point around a bit */
- for( x = 0; x < 4; x++ )
+ for( x = 0; x < 5; x++ )
{
/* two's complement 0, 1, -1, 2, -2, etc */
x1 = ((x >> 1) ^ (x & 1 ? -1 : 0)) + (x & 1);
- for( y = 0; y < 4; y++ )
+ for( y = 0; y < 5; y++ )
{
y1 = ((y >> 1) ^ (y & 1 ? -1 : 0)) + (y & 1);
- for( z = 0; z < 4; z++ )
+ for( z = 0; z < 5; z++ )
{
z1 = ((z >> 1) ^ (z & 1 ? -1 : 0)) + (z & 1);
trace.cluster = ClusterForPointExtFilter( origin, VERTEX_EPSILON, info->numSurfaceClusters, &surfaceClusters[ info->firstSurfaceCluster ] );
if( trace.cluster < 0 )
continue;
+
+ /* r7 dirt */
+ if( dirty && !bouncing )
+ dirt = DirtForSample( &trace );
+ else
+ dirt = 1.0f;
+
+ /* jal: floodlight */
+ floodLightAmount = 0.0f;
+ VectorClear( floodColor );
+ if( floodlighty && !bouncing )
+ {
+ floodLightAmount = floodlightIntensity * FloodLightForSample( &trace, floodlightDistance, floodlight_lowquality );
+ VectorScale( floodlightRGB, floodLightAmount, floodColor );
+ }
/* trace */
LightingAtSample( &trace, ds->vertexStyles, colors );
determines opaque brushes in the world and find sky shaders for sunlight calculations
*/
-void SetupBrushes( void )
+void SetupBrushesFlags( int mask_any, int test_any, int mask_all, int test_all )
{
- int i, j, b, compileFlags;
+ int i, j, b;
+ unsigned int compileFlags, allCompileFlags;
qboolean inside;
bspBrush_t *brush;
bspBrushSide_t *side;
/* check all sides */
inside = qtrue;
compileFlags = 0;
+ allCompileFlags = ~(0u);
for( j = 0; j < brush->numSides && inside; j++ )
{
/* do bsp shader calculations */
side = &bspBrushSides[ brush->firstSide + j ];
shader = &bspShaders[ side->shaderNum ];
-
+
/* get shader info */
- si = ShaderInfoForShader( shader->shader );
+ si = ShaderInfoForShaderNull( shader->shader );
if( si == NULL )
continue;
/* or together compile flags */
compileFlags |= si->compileFlags;
+ allCompileFlags &= si->compileFlags;
}
-
+
/* determine if this brush is opaque to light */
- if( !(compileFlags & C_TRANSLUCENT) )
+ if( (compileFlags & mask_any) == test_any && (allCompileFlags & mask_all) == test_all )
{
opaqueBrushes[ b >> 3 ] |= (1 << (b & 7));
numOpaqueBrushes++;
/* emit some statistics */
Sys_FPrintf( SYS_VRB, "%9d opaque brushes\n", numOpaqueBrushes );
}
+void SetupBrushes( void )
+{
+ SetupBrushesFlags(C_TRANSLUCENT, 0, 0, 0);
+}
qboolean ClusterVisible( int a, int b )
{
- int portalClusters, leafBytes;
+ int leafBytes;
byte *pvs;
return qtrue;
/* get pvs data */
- portalClusters = ((int *) bspVisBytes)[ 0 ];
+ /* portalClusters = ((int *) bspVisBytes)[ 0 ]; */
leafBytes = ((int*) bspVisBytes)[ 1 ];
pvs = bspVisBytes + VIS_HEADER_SIZE + (a * leafBytes);
int i, x, y, z, x1, y1, z1;
light_t *light, *light2, **owner;
bspLeaf_t *leaf;
- vec3_t origin, dir, mins, maxs, nullVector = { 0, 0, 0 };
+ vec3_t origin, dir, mins, maxs;
float radius, intensity;
light_t *buckets[ 256 ];
/* handle area lights */
if( exactPointToPolygon && light->type == EMIT_AREA && light->w != NULL )
{
- /* ugly hack to calculate extent for area lights, but only done once */
- VectorScale( light->normal, -1.0f, dir );
- for( radius = 100.0f; radius < 130000.0f && light->envelope == 0; radius += 10.0f )
+ light->envelope = MAX_WORLD_COORD * 8.0f;
+
+ /* check for fast mode */
+ if( (light->flags & LIGHT_FAST) || (light->flags & LIGHT_FAST_TEMP) )
{
- float factor;
-
- VectorMA( light->origin, radius, light->normal, origin );
- factor = PointToPolygonFormFactor( origin, dir, light->w );
- if( factor < 0.0f )
- factor *= -1.0f;
- if( (factor * light->add) <= light->falloffTolerance )
- light->envelope = radius;
+ /* ugly hack to calculate extent for area lights, but only done once */
+ VectorScale( light->normal, -1.0f, dir );
+ for( radius = 100.0f; radius < MAX_WORLD_COORD * 8.0f; radius += 10.0f )
+ {
+ float factor;
+
+ VectorMA( light->origin, radius, light->normal, origin );
+ factor = PointToPolygonFormFactor( origin, dir, light->w );
+ if( factor < 0.0f )
+ factor *= -1.0f;
+ if( (factor * light->add) <= light->falloffTolerance )
+ {
+ light->envelope = radius;
+ break;
+ }
+ }
}
- /* check for fast mode */
- if( !(light->flags & LIGHT_FAST) && !(light->flags & LIGHT_FAST_TEMP) )
- light->envelope = MAX_WORLD_COORD * 8.0f;
+ intensity = light->photons; /* hopefully not used */
}
else
{
/* solve distance for non-distance lights */
if( !(light->flags & LIGHT_ATTEN_DISTANCE) )
light->envelope = MAX_WORLD_COORD * 8.0f;
-
- /* solve distance for linear lights */
- else if( (light->flags & LIGHT_ATTEN_LINEAR ) )
- //% light->envelope = ((intensity / light->falloffTolerance) * linearScale - 1 + radius) / light->fade;
- light->envelope = ((intensity * linearScale) - light->falloffTolerance) / light->fade;
-
- /*
- add = angle * light->photons * linearScale - (dist * light->fade);
- T = (light->photons * linearScale) - (dist * light->fade);
- T + (dist * light->fade) = (light->photons * linearScale);
- dist * light->fade = (light->photons * linearScale) - T;
- dist = ((light->photons * linearScale) - T) / light->fade;
- */
-
- /* solve for inverse square falloff */
+
+ else if( (light->flags & LIGHT_FAST) || (light->flags & LIGHT_FAST_TEMP) )
+ {
+ /* solve distance for linear lights */
+ if( (light->flags & LIGHT_ATTEN_LINEAR ) )
+ light->envelope = ((intensity * linearScale) - light->falloffTolerance) / light->fade;
+
+ /*
+ add = angle * light->photons * linearScale - (dist * light->fade);
+ T = (light->photons * linearScale) - (dist * light->fade);
+ T + (dist * light->fade) = (light->photons * linearScale);
+ dist * light->fade = (light->photons * linearScale) - T;
+ dist = ((light->photons * linearScale) - T) / light->fade;
+ */
+
+ /* solve for inverse square falloff */
+ else
+ light->envelope = sqrt( intensity / light->falloffTolerance ) + radius;
+
+ /*
+ add = light->photons / (dist * dist);
+ T = light->photons / (dist * dist);
+ T * (dist * dist) = light->photons;
+ dist = sqrt( light->photons / T );
+ */
+ }
else
- light->envelope = sqrt( intensity / light->falloffTolerance ) + radius;
+ {
+ /* solve distance for linear lights */
+ if( (light->flags & LIGHT_ATTEN_LINEAR ) )
+ light->envelope = (intensity * linearScale) / light->fade;
- /*
- add = light->photons / (dist * dist);
- T = light->photons / (dist * dist);
- T * (dist * dist) = light->photons;
- dist = sqrt( light->photons / T );
- */
+ /* can't cull these */
+ else
+ light->envelope = MAX_WORLD_COORD * 8.0f;
+ }
}
/* chop radius against pvs */
int i, j;
float angle, elevation, angleStep, elevationStep;
const char *value;
- double v1,v2,v3,v4,v5;
+ double v1,v2,v3,v4,v5,v6;
/* note it */
Sys_FPrintf( SYS_VRB, "--- SetupFloodLight ---\n" );
v1=v2=v3=0;
v4=floodlightDistance;
v5=floodlightIntensity;
+ v6=floodlightDirectionScale;
- sscanf( value, "%lf %lf %lf %lf %lf", &v1, &v2, &v3, &v4, &v5);
+ sscanf( value, "%lf %lf %lf %lf %lf %lf", &v1, &v2, &v3, &v4, &v5, &v6);
floodlightRGB[0]=v1;
floodlightRGB[1]=v2;
if (VectorLength(floodlightRGB)==0)
{
- VectorSet(floodlightRGB,240,240,255);
+ VectorSet(floodlightRGB,0.94,0.94,1.0);
}
if (v4<1) v4=1024;
if (v5<1) v5=128;
+ if (v6<0) v6=1;
floodlightDistance=v4;
floodlightIntensity=v5;
+ floodlightDirectionScale=v6;
floodlighty = qtrue;
Sys_Printf( "FloodLighting enabled via worldspawn _floodlight key.\n" );
}
else
{
- VectorSet(floodlightRGB,240,240,255);
- //floodlighty = qtrue;
- //Sys_Printf( "FloodLighting enabled via worldspawn _floodlight key.\n" );
+ VectorSet(floodlightRGB,0.94,0.94,1.0);
+ }
+ if(colorsRGB)
+ {
+ floodlightRGB[0] = Image_LinearFloatFromsRGBFloat(floodlightRGB[0]);
+ floodlightRGB[1] = Image_LinearFloatFromsRGBFloat(floodlightRGB[1]);
+ floodlightRGB[2] = Image_LinearFloatFromsRGBFloat(floodlightRGB[2]);
}
- VectorNormalize(floodlightRGB,floodlightRGB);
+ ColorNormalize(floodlightRGB,floodlightRGB);
}
/*
TraceLine( trace );
contribution=1;
- if (trace->compileFlags & C_SKY )
+ if ( trace->compileFlags & C_SKY || trace->compileFlags & C_TRANSLUCENT )
{
contribution=1.0f;
}
/* global pass */
if (floodlighty && floodlightIntensity)
- FloodLightRawLightmapPass(lm, floodlightRGB, floodlightIntensity, floodlightDistance, floodlight_lowquality, 1.0f);
+ FloodLightRawLightmapPass(lm, floodlightRGB, floodlightIntensity, floodlightDistance, floodlight_lowquality, floodlightDirectionScale);
/* custom pass */
if (lm->floodlightIntensity)