diff --git a/changelog.txt b/changelog.txt index a72c269f..d1a913ea 100644 --- a/changelog.txt +++ b/changelog.txt @@ -8,6 +8,7 @@ * light: removed old bsp30 support * light: lit files now automatically generated when coloured lights detected * light: implemented 4x4 oversampling with -extra4 command line +* light: implemented the -gate option to help speed processing (default 0.001) 2013-02-25 TyrUtils v0.5 diff --git a/include/common/mathlib.h b/include/common/mathlib.h index f22b53ea..b9252ebe 100644 --- a/include/common/mathlib.h +++ b/include/common/mathlib.h @@ -20,12 +20,15 @@ #ifndef __COMMON_MATHLIB_H__ #define __COMMON_MATHLIB_H__ +#include #include #ifdef DOUBLEVEC_T typedef double vec_t; +#define VECT_MAX DBL_MAX; #else typedef float vec_t; +#define VECT_MAX FLT_MAX; #endif typedef vec_t vec3_t[3]; diff --git a/include/light/entities.h b/include/light/entities.h index a9de7b9e..e9af006f 100644 --- a/include/light/entities.h +++ b/include/light/entities.h @@ -62,6 +62,7 @@ typedef struct entity_s { float atten; light_formula_t formula; vec3_t lightcolor; + vec_t fadedist; char target[MAX_ENT_VALUE]; char targetname[MAX_ENT_VALUE]; diff --git a/include/light/light.h b/include/light/light.h index c329b35b..7b16ec26 100644 --- a/include/light/light.h +++ b/include/light/light.h @@ -45,6 +45,7 @@ void MakeTnodes(void); extern float scaledist; extern float rangescale; +extern float fadegate; extern int worldminlight; extern const vec3_t vec3_white; extern vec3_t minlight_color; diff --git a/light.txt b/light.txt index 6c093028..44571b15 100644 --- a/light.txt +++ b/light.txt @@ -37,6 +37,13 @@ OPTIONS The same effect can be achieved on individual lights by adjusting both the "light" and "wait" attributes. + -gate n Set a minimum light level, below which can be considered + zero brightness. This can dramatically speed up + processing when there are large numbers of lights with + inverse or inverse square falloff. In most cases, values + less than 1.0 will cause no discernable visual + differences. Default 0.001. + -colored (DEPRECATED) Turn on coloured lighting support. By -coloured default this will output a bsp in "BSP30" format, which almost no Quake engines support. BSP30 support will be diff --git a/light/entities.c b/light/entities.c index c4f0e710..830f8a0f 100644 --- a/light/entities.c +++ b/light/entities.c @@ -186,6 +186,40 @@ CheckEntityFields(entity_t *entity) } else { VectorCopy(vec3_white, entity->lightcolor); } + + if (entity->formula == LF_LINEAR) { + /* Linear formula always has a falloff point */ + entity->fadedist = fabs(entity->light / entity->atten / scaledist); + } else if (fadegate < EQUAL_EPSILON) { + /* If fadegate is tiny, other lights have effectively infinite reach */ + entity->fadedist = VECT_MAX; + } else { + /* Calculate the distance at which brightness falls to zero */ + switch (entity->formula) { + case LF_INFINITE: + case LF_LOCALMIN: + entity->fadedist = VECT_MAX; + break; + case LF_INVERSE: + entity->fadedist = entity->light * entity->atten * scaledist; + entity->fadedist *= LF_SCALE / fadegate; + entity->fadedist = fabs(entity->fadedist); + break; + case LF_INVERSE2: + entity->fadedist = entity->light * entity->atten * scaledist; + entity->fadedist *= LF_SCALE / sqrt(fadegate); + entity->fadedist = fabs(entity->fadedist); + break; + case LF_INVERSE2A: + entity->fadedist = entity->light * entity->atten * scaledist; + entity->fadedist -= LF_SCALE; + entity->fadedist *= LF_SCALE / sqrt(fadegate); + entity->fadedist = fabs(entity->fadedist); + break; + default: + Error("Internal error: formula not handled in %s", __func__); + } + } } diff --git a/light/light.c b/light/light.c index a01d3226..84b4d045 100644 --- a/light/light.c +++ b/light/light.c @@ -23,6 +23,7 @@ float scaledist = 1.0; float rangescale = 0.5; +float fadegate = EQUAL_EPSILON; int worldminlight = 0; int sunlight = 0; const vec3_t vec3_white = { 255, 255, 255 }; @@ -209,6 +210,9 @@ main(int argc, const char **argv) } else if (!strcmp(argv[i], "-range")) { rangescale = atof(argv[i + 1]); i++; + } else if (!strcmp(argv[i], "-gate")) { + fadegate = atof(argv[i + 1]); + i++; } else if (!strcmp(argv[i], "-light")) { worldminlight = atof(argv[i + 1]); i++; @@ -232,7 +236,7 @@ main(int argc, const char **argv) if (i != argc - 1) Error("usage: light [-threads num] [-light num] [-extra|-extra4]\n" - " [-dist n] [-range n] [-lit] [-compress]\n" + " [-dist n] [-range n] [-gate n] [-lit] [-compress]\n" " [-nominlimit] bspfile\n"); start = I_FloatTime(); diff --git a/light/ltface.c b/light/ltface.c index 3d3ee547..b6ed1244 100644 --- a/light/ltface.c +++ b/light/ltface.c @@ -556,6 +556,12 @@ SingleLightFace(const entity_t *light, lightinfo_t * l, VectorSubtract(light->origin, surf, ray); dist = VectorLength(ray); + + /* Quick distance check first */ + if (dist > light->fadedist) + continue; + + /* Check spotlight cone */ VectorScale(ray, 1.0 / dist, ray); angle = DotProduct(ray, l->facenormal); if (light->spotlight) {