}
/* error check */
- if ( front->numVerts > maxPoints || front->numVerts > maxPoints ) {
+ if ( front->numVerts > maxPoints ) {
Error( "RadClipWindingEpsilon: points exceeded estimate" );
}
- if ( front->numVerts > MAX_POINTS_ON_WINDING || front->numVerts > MAX_POINTS_ON_WINDING ) {
+ if ( front->numVerts > MAX_POINTS_ON_WINDING ) {
Error( "RadClipWindingEpsilon: MAX_POINTS_ON_WINDING" );
}
}
#define SAMPLE_GRANULARITY 6
static void RadSample( int lightmapNum, bspDrawSurface_t *ds, rawLightmap_t *lm, shaderInfo_t *si, radWinding_t *rw, vec3_t average, vec3_t gradient, int *style ){
- int i, j, k, l, v, x, y, samples;
+ int i, j, k, l, v, x, y, samples, avgcolor, f_superSample;
vec3_t color, mins, maxs;
vec4_t textureColor;
float alpha, alphaI, bf;
/* multiply by texture color */
if ( !RadSampleImage( si->lightImage->pixels, si->lightImage->width, si->lightImage->height, rw->verts[ samples ].st, textureColor ) ) {
VectorCopy( si->averageColor, textureColor );
- textureColor[ 4 ] = 255.0f;
+ textureColor[ 3 ] = 255.0f;
}
+ avgcolor = ( textureColor[ 0 ] + textureColor[ 1 ] + textureColor[ 2 ] ) / 3;
for ( i = 0; i < 3; i++ )
- color[ i ] = ( textureColor[ i ] / 255 ) * ( rw->verts[ samples ].color[ lightmapNum ][ i ] / 255.0f );
+ color[ i ] = ( ( textureColor[ i ] * bounceColorRatio + ( avgcolor * ( 1 - bounceColorRatio ) ) ) / 255 ) * ( rw->verts[ samples ].color[ lightmapNum ][ i ] / 255.0f );
+// color[ i ] = ( textureColor[ i ] / 255 ) * ( rw->verts[ samples ].color[ lightmapNum ][ i ] / 255.0f );
AddPointToBounds( color, mins, maxs );
VectorAdd( average, color, average );
/* sample lightmap */
else
{
+ f_superSample = (float)superSample;
/* fracture the winding into a fan (including degenerate tris) */
for ( v = 1; v < ( rw->numVerts - 1 ) && samples < MAX_SAMPLES; v++ )
{
blend[ 0 ] = i;
blend[ 1 ] = j;
blend[ 2 ] = k;
- bf = ( 1.0 / ( blend[ 0 ] + blend[ 1 ] + blend[ 2 ] ) );
+ bf = ( 1.0f / ( blend[ 0 ] + blend[ 1 ] + blend[ 2 ] ) );
VectorScale( blend, bf, blend );
/* create a blended sample */
}
/* get lightmap xy coords */
- x = lightmap[ 0 ] / (float) superSample;
- y = lightmap[ 1 ] / (float) superSample;
+ /* xy = clamp(lightmap/superSample, 0, lm - 1)*/
+ x = lightmap[ 0 ] / f_superSample;
+ y = lightmap[ 1 ] / f_superSample;
+
if ( x < 0 ) {
x = 0;
}
/* multiply by texture color */
if ( !RadSampleImage( si->lightImage->pixels, si->lightImage->width, si->lightImage->height, st, textureColor ) ) {
VectorCopy( si->averageColor, textureColor );
- textureColor[ 4 ] = 255;
+ textureColor[ 3 ] = 255;
+ }
+ avgcolor = ( textureColor[ 0 ] + textureColor[ 1 ] + textureColor[ 2 ] ) / 3;
+ for ( i = 0; i < 3; i++ ){
+ color[ i ] = ( ( textureColor[ i ] * bounceColorRatio + ( avgcolor * ( 1 - bounceColorRatio ) ) ) / 255 ) * ( radLuxel[ i ] / 255 );
+ /*
+ Workaround for https://gitlab.com/xonotic/netradiant/-/issues/182
+ This loop normally uses the l iterator instead of i:
+ for ( l = 0; l < 3; l++ ){
+ color[ l ] = ( ( textureColor[ l ] * bounceColorRatio + ( avgcolor * ( 1 - bounceColorRatio ) ) ) / 255 ) * ( radLuxel[ l ] / 255 );
+ }
+ */
+ //Sys_Printf( "%i %i %i %i %i \n", (int) textureColor[ 0 ], (int) textureColor[ 1 ], (int) textureColor[ 2 ], (int) avgcolor, (int) color[ i ] );
}
- for ( i = 0; i < 3; i++ )
- color[ i ] = ( textureColor[ i ] / 255 ) * ( radLuxel[ i ] / 255 );
-
AddPointToBounds( color, mins, maxs );
VectorAdd( average, color, average );
#define RADIOSITY_MIN 0.0001f
#define RADIOSITY_CLIP_EPSILON 0.125f
+
+
static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, rawLightmap_t *lm, shaderInfo_t *si,
- float scale, float subdivide, qboolean original, radWinding_t *rw, clipWork_t *cw ){
+ float scale, float subdivide, radWinding_t *rw, clipWork_t *cw ){
int i, style = 0;
float dist, area, value;
vec3_t mins, maxs, normal, d1, d2, cross, color, gradient;
light_t *light, *splash;
- winding_t *w;
+ winding_t *w, *splash_w;
/* dummy check */
RadClipWindingEpsilon( rw, normal, dist, RADIOSITY_CLIP_EPSILON, &front, &back, cw );
/* recurse */
- RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, qfalse, &front, cw );
- RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, qfalse, &back, cw );
+ RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, &front, cw );
+ RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, &back, cw );
return;
}
}
/* if color gradient is too high, subdivide again */
if ( subdivide > minDiffuseSubdivide &&
( gradient[ 0 ] > RADIOSITY_MAX_GRADIENT || gradient[ 1 ] > RADIOSITY_MAX_GRADIENT || gradient[ 2 ] > RADIOSITY_MAX_GRADIENT ) ) {
- RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, ( subdivide / 2.0f ), qfalse, rw, cw );
+ RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, ( subdivide / 2.0f ), rw, cw );
return;
}
}
VectorMA( light->origin, 1.0f, light->normal, light->origin );
light->dist = DotProduct( light->origin, normal );
- /* optionally create a point splashsplash light for first pass */
- if ( original && si->backsplashFraction > 0 ) {
+#if 0
+ /* optionally create a point backsplash light */
+ if ( si->backsplashFraction > 0 ) {
+
/* allocate a new point light */
splash = safe_malloc0( sizeof( *splash ) );
+
splash->next = lights;
lights = splash;
+
/* set it up */
splash->flags = LIGHT_Q3A_DEFAULT;
splash->type = EMIT_POINT;
splash->photons = light->photons * si->backsplashFraction;
+
splash->fade = 1.0f;
splash->si = si;
VectorMA( light->origin, si->backsplashDistance, normal, splash->origin );
VectorCopy( si->color, splash->color );
+
splash->falloffTolerance = falloffTolerance;
splash->style = noStyles ? LS_NORMAL : light->style;
/* add to counts */
numPointLights++;
}
+#endif
+
+#if 1
+ /* optionally create area backsplash light */
+ //if ( original && si->backsplashFraction > 0 ) {
+ if ( si->backsplashFraction > 0 && !( si->compileFlags & C_SKY ) ) {
+ /* allocate a new area light */
+ splash = safe_malloc( sizeof( *splash ) );
+ memset( splash, 0, sizeof( *splash ) );
+ ThreadLock();
+ splash->next = lights;
+ lights = splash;
+ ThreadUnlock();
+
+ /* set it up */
+ splash->flags = LIGHT_AREA_DEFAULT;
+ splash->type = EMIT_AREA;
+ splash->photons = light->photons * 7.0f * si->backsplashFraction;
+ splash->add = light->add * 7.0f * si->backsplashFraction;
+ splash->fade = 1.0f;
+ splash->si = si;
+ VectorCopy( si->color, splash->color );
+ VectorScale( splash->color, splash->add, splash->emitColor );
+ splash->falloffTolerance = falloffTolerance;
+ splash->style = noStyles ? LS_NORMAL : si->lightStyle;
+ if ( splash->style < LS_NORMAL || splash->style >= LS_NONE ) {
+ splash->style = LS_NORMAL;
+ }
+
+ /* create a regular winding */
+ splash_w = AllocWinding( rw->numVerts );
+ splash_w->numpoints = rw->numVerts;
+ for ( i = 0; i < rw->numVerts; i++ )
+ VectorMA( rw->verts[rw->numVerts - 1 - i].xyz, si->backsplashDistance, normal, splash_w->p[ i ] );
+ splash->w = splash_w;
+
+ VectorMA( light->origin, si->backsplashDistance, normal, splash->origin );
+ VectorNegate( normal, splash->normal );
+ splash->dist = DotProduct( splash->origin, splash->normal );
+
+// splash->flags |= LIGHT_TWOSIDED;
+ }
+#endif
+
}
else
{
}
-
/*
RadLightForTriangles()
creates unbounced diffuse lights for triangle soup (misc_models, etc)
}
/* subdivide into area lights */
- RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, qtrue, &rw, cw );
+ RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, &rw, cw );
}
}
}
/* subdivide into area lights */
- RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, qtrue, &rw, cw );
+ RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, &rw, cw );
}
/* generate 2 tris */
}
/* subdivide into area lights */
- RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, qtrue, &rw, cw );
+ RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, &rw, cw );
}
}
}