light: implement the -gate option

Precalculate the distance at which lights will fade to zero brightness.
For lights with inverse falloff, use the gate value to determine the
cut-off distance.  Use this value to cull samples and avoid the ray
tracing overhead.

Hopefully not too controversially, I am going to default this to "on" with
a gate value of 0.001. Unless you have > 1000 lights contributing
fractional light values across your map, this is not going to make any
visible difference.

Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
This commit is contained in:
Kevin Shanahan 2013-03-03 13:36:52 +10:30
parent 8b1a501087
commit a8d8150791
8 changed files with 58 additions and 1 deletions

View File

@ -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

View File

@ -20,12 +20,15 @@
#ifndef __COMMON_MATHLIB_H__
#define __COMMON_MATHLIB_H__
#include <float.h>
#include <math.h>
#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];

View File

@ -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];

View File

@ -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;

View File

@ -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

View File

@ -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__);
}
}
}

View File

@ -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();

View File

@ -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) {