light: rework LightFace_Entity to fully fix testlightonface.map

This commit is contained in:
Eric Wasylishen 2016-04-05 12:52:44 -06:00
parent aed29da060
commit a407b971bc
2 changed files with 68 additions and 76 deletions

View File

@ -1102,15 +1102,15 @@ LightFace_Entity(const entity_t *entity, const lightsample_t *light,
const vec_t *surfpoint, *surfnorm; const vec_t *surfpoint, *surfnorm;
int i; int i;
qboolean hit; qboolean hit;
vec_t dist, add, angle, spotscale; vec_t planedist, add, angle, spotscale;
lightsample_t *sample; lightsample_t *sample;
lightmap_t *lightmap; lightmap_t *lightmap;
qboolean curved = lightsurf->curved; qboolean curved = lightsurf->curved;
dist = DotProduct(entity->origin, plane->normal) - plane->dist; planedist = DotProduct(entity->origin, plane->normal) - plane->dist;
/* don't bother with lights behind the surface */ /* don't bother with lights behind the surface */
if (dist < 0 && !curved) if (planedist < 0 && !curved)
return; return;
/* sphere cull surface and light */ /* sphere cull surface and light */
@ -1127,28 +1127,21 @@ LightFace_Entity(const entity_t *entity, const lightsample_t *light,
surfpoint = lightsurf->points[0]; surfpoint = lightsurf->points[0];
surfnorm = lightsurf->normals[0]; surfnorm = lightsurf->normals[0];
for (i = 0; i < lightsurf->numpoints; i++, sample++, surfpoint += 3, surfnorm += 3) { for (i = 0; i < lightsurf->numpoints; i++, sample++, surfpoint += 3, surfnorm += 3) {
vec3_t surfpoint_actual, ray; vec3_t surfpointToLightDir;
VectorSubtract(entity->origin, surfpoint, surfpointToLightDir);
// surfpoint is hovering above the face by 1 unit (see CalcPoints). vec_t surfpointToLightDist = VectorNormalize(surfpointToLightDir);
// We the point exactly on the plane for calculating the light angle,
// otherwise lights within 1 unit of a surface don't work
ProjectPointOntoPlane(surfpoint, &lightsurf->plane, surfpoint_actual);
VectorSubtract(entity->origin, surfpoint_actual, ray);
dist = VectorLength(ray);
/* Quick distance check first */ /* Quick distance check first */
if (fabs(GetLightValue(&entity->light, entity, dist)) <= fadegate) if (fabs(GetLightValue(&entity->light, entity, surfpointToLightDist)) <= fadegate)
continue; continue;
angle = DotProduct(surfpointToLightDir, surfnorm);
angle = qmax(0.0f, angle); // light can be behind sample point if the light is right on the face
/* Check spotlight cone */ /* Check spotlight cone */
VectorScale(ray, 1.0 / dist, ray);
angle = DotProduct(ray, surfnorm);
if (angle < 0)
continue; //curved surfaces are allowed to have the light 'behind' the surface. omitting this check results in erroneous darkening on these surfaces
spotscale = 1; spotscale = 1;
if (entity->spotlight) { if (entity->spotlight) {
vec_t falloff = DotProduct(entity->spotvec, ray); vec_t falloff = DotProduct(entity->spotvec, surfpointToLightDir);
if (falloff > entity->spotfalloff) if (falloff > entity->spotfalloff)
continue; continue;
if (falloff > entity->spotfalloff2) { if (falloff > entity->spotfalloff2) {
@ -1160,26 +1153,25 @@ LightFace_Entity(const entity_t *entity, const lightsample_t *light,
} }
/* HACK: support lights lying exactly on a face by only tracing up to 0.1 units from the light */ /* HACK: support lights lying exactly on a face by only tracing up to 0.1 units from the light */
dist = qmax(0.0f, dist - 0.1f); surfpointToLightDist = qmax(0.0f, surfpointToLightDist - 0.01f);
if (!TestLight_embree(surfpoint, ray, dist, modelinfo)) if (!TestLight_embree(surfpoint, surfpointToLightDir, surfpointToLightDist, modelinfo))
continue; continue;
if (dist >= 0) //anglescale normally lights the surface more than it otherwise should, meaning the dark side would be visible if there were no occlusion. naturally, this doesn't work when we're relaxing occlusion to faciliate curves.
angle = (1.0 - entity->anglescale) + entity->anglescale * angle; angle = (1.0 - entity->anglescale) + entity->anglescale * angle;
add = GetLightValue(light, entity, dist) * angle * spotscale; add = GetLightValue(light, entity, surfpointToLightDist) * angle * spotscale;
add *= Dirt_GetScaleFactor(lightsurf->occlusion[i], entity, lightsurf); add *= Dirt_GetScaleFactor(lightsurf->occlusion[i], entity, lightsurf);
if (entity->projectedmip) if (entity->projectedmip)
{ {
vec3_t col; vec3_t col;
VectorCopy(light->color, col); VectorCopy(light->color, col);
VectorScale(ray, 255, col); VectorScale(surfpointToLightDir, 255, col);
LightFace_SampleMipTex(entity->projectedmip, entity->projectionmatrix, surfpoint_actual, col); LightFace_SampleMipTex(entity->projectedmip, entity->projectionmatrix, surfpoint, col);
Light_Add(sample, add, col, ray); Light_Add(sample, add, col, surfpointToLightDir);
} else {
Light_Add(sample, add, light->color, surfpointToLightDir);
} }
else
Light_Add(sample, add, light->color, ray);
/* Check if we really hit, ignore tiny lights */ /* Check if we really hit, ignore tiny lights */
/* ericw -- never ignore generated lights, which can be tiny and need /* ericw -- never ignore generated lights, which can be tiny and need

View File

@ -6,122 +6,122 @@
"wad" "free_wad.wad" "wad" "free_wad.wad"
// brush 0 // brush 0
{ {
( 480 64 16 ) ( 480 64 17 ) ( 480 65 16 ) sgrate4 0 0 0 1 1 ( 528 64 16 ) ( 528 64 17 ) ( 528 65 16 ) sgrate4 0 0 0 1 1
( -64 -64 -16 ) ( -64 -63 -16 ) ( -64 -64 -15 ) sgrate4 0 0 0 1 1 ( -64 -64 -16 ) ( -64 -63 -16 ) ( -64 -64 -15 ) sgrate4 0 0 0 1 1
( 64 192 16 ) ( 65 192 16 ) ( 64 192 17 ) sgrate4 0 0 0 1 1 ( 64 256 16 ) ( 65 256 16 ) ( 64 256 17 ) sgrate4 0 0 0 1 1
( -64 -288 -16 ) ( -64 -288 -15 ) ( -63 -288 -16 ) sgrate4 0 0 0 1 1 ( -64 -320 -16 ) ( -64 -320 -15 ) ( -63 -320 -16 ) sgrate4 0 0 0 1 1
( 64 64 16 ) ( 64 65 16 ) ( 65 64 16 ) sgrate4 0 0 0 1 1 ( 64 64 16 ) ( 64 65 16 ) ( 65 64 16 ) sgrate4 0 0 0 1 1
( -64 -64 -16 ) ( -63 -64 -16 ) ( -64 -63 -16 ) sgrate4 0 0 0 1 1 ( -64 -64 -16 ) ( -63 -64 -16 ) ( -64 -63 -16 ) sgrate4 0 0 0 1 1
} }
// brush 1 // brush 1
{ {
( 480 -256 16 ) ( 480 -256 17 ) ( 480 -255 16 ) gray_brick 0 0 0 1 1 ( 544 -288 16 ) ( 544 -288 17 ) ( 544 -287 16 ) gray_brick 0 0 0 1 1
( -64 -384 -16 ) ( -64 -383 -16 ) ( -64 -384 -15 ) gray_brick 0 0 0 1 1 ( -64 -416 -16 ) ( -64 -415 -16 ) ( -64 -416 -15 ) gray_brick 0 0 0 1 1
( 64 -288 16 ) ( 65 -288 16 ) ( 64 -288 17 ) gray_brick 0 0 0 1 1 ( 64 -320 16 ) ( 65 -320 16 ) ( 64 -320 17 ) gray_brick 0 0 0 1 1
( -64 -320 -16 ) ( -64 -320 -15 ) ( -63 -320 -16 ) gray_brick 0 0 0 1 1 ( -64 -352 -16 ) ( -64 -352 -15 ) ( -63 -352 -16 ) gray_brick 0 0 0 1 1
( 64 -256 256 ) ( 64 -255 256 ) ( 65 -256 256 ) gray_brick 0 0 0 1 1 ( 64 -288 800 ) ( 64 -287 800 ) ( 65 -288 800 ) gray_brick 0 0 0 1 1
( -64 -384 -16 ) ( -63 -384 -16 ) ( -64 -383 -16 ) gray_brick 0 0 0 1 1 ( -64 -416 -16 ) ( -63 -416 -16 ) ( -64 -415 -16 ) gray_brick 0 0 0 1 1
} }
// brush 2 // brush 2
{ {
( -64 64 16 ) ( -64 64 17 ) ( -64 65 16 ) gray_brick 0 0 0 1 1 ( -64 64 16 ) ( -64 64 17 ) ( -64 65 16 ) gray_brick 0 0 0 1 1
( -96 -64 -16 ) ( -96 -63 -16 ) ( -96 -64 -15 ) gray_brick 0 0 0 1 1 ( -96 -64 -16 ) ( -96 -63 -16 ) ( -96 -64 -15 ) gray_brick 0 0 0 1 1
( 32 192 16 ) ( 33 192 16 ) ( 32 192 17 ) gray_brick 0 0 0 1 1 ( 32 256 16 ) ( 33 256 16 ) ( 32 256 17 ) gray_brick 0 0 0 1 1
( -96 -288 -16 ) ( -96 -288 -15 ) ( -95 -288 -16 ) gray_brick 0 0 0 1 1 ( -96 -320 -16 ) ( -96 -320 -15 ) ( -95 -320 -16 ) gray_brick 0 0 0 1 1
( 32 64 256 ) ( 32 65 256 ) ( 33 64 256 ) gray_brick 0 0 0 1 1 ( 32 64 800 ) ( 32 65 800 ) ( 33 64 800 ) gray_brick 0 0 0 1 1
( -96 -64 -16 ) ( -95 -64 -16 ) ( -96 -63 -16 ) gray_brick 0 0 0 1 1 ( -96 -64 -16 ) ( -95 -64 -16 ) ( -96 -63 -16 ) gray_brick 0 0 0 1 1
} }
// brush 3 // brush 3
{ {
( 512 64 16 ) ( 512 64 17 ) ( 512 65 16 ) gray_brick 0 0 0 1 1 ( 544 64 16 ) ( 544 64 17 ) ( 544 65 16 ) gray_brick 0 0 0 1 1
( 480 -64 -16 ) ( 480 -63 -16 ) ( 480 -64 -15 ) gray_brick 0 0 0 1 1 ( 512 -64 -16 ) ( 512 -63 -16 ) ( 512 -64 -15 ) gray_brick 0 0 0 1 1
( 608 192 16 ) ( 609 192 16 ) ( 608 192 17 ) gray_brick 0 0 0 1 1 ( 640 256 16 ) ( 641 256 16 ) ( 640 256 17 ) gray_brick 0 0 0 1 1
( 480 -288 -16 ) ( 480 -288 -15 ) ( 481 -288 -16 ) gray_brick 0 0 0 1 1 ( 512 -320 -16 ) ( 512 -320 -15 ) ( 513 -320 -16 ) gray_brick 0 0 0 1 1
( 608 64 256 ) ( 608 65 256 ) ( 609 64 256 ) gray_brick 0 0 0 1 1 ( 640 64 800 ) ( 640 65 800 ) ( 641 64 800 ) gray_brick 0 0 0 1 1
( 480 -64 -16 ) ( 481 -64 -16 ) ( 480 -63 -16 ) gray_brick 0 0 0 1 1 ( 512 -64 -16 ) ( 513 -64 -16 ) ( 512 -63 -16 ) gray_brick 0 0 0 1 1
} }
// brush 4 // brush 4
{ {
( 480 256 16 ) ( 480 256 17 ) ( 480 257 16 ) gray_brick 0 0 0 1 1 ( 528 320 16 ) ( 528 320 17 ) ( 528 321 16 ) gray_brick 0 0 0 1 1
( 192 128 -16 ) ( 192 129 -16 ) ( 192 128 -15 ) gray_brick 0 0 0 1 1 ( 192 192 -16 ) ( 192 193 -16 ) ( 192 192 -15 ) gray_brick 0 0 0 1 1
( -32 224 16 ) ( -31 224 16 ) ( -32 224 17 ) gray_brick 0 0 0 1 1 ( -32 288 16 ) ( -31 288 16 ) ( -32 288 17 ) gray_brick 0 0 0 1 1
( -160 192 -16 ) ( -160 192 -15 ) ( -159 192 -16 ) gray_brick 0 0 0 1 1 ( -160 256 -16 ) ( -160 256 -15 ) ( -159 256 -16 ) gray_brick 0 0 0 1 1
( -32 256 256 ) ( -32 257 256 ) ( -31 256 256 ) gray_brick 0 0 0 1 1 ( -32 320 800 ) ( -32 321 800 ) ( -31 320 800 ) gray_brick 0 0 0 1 1
( -160 128 -16 ) ( -159 128 -16 ) ( -160 129 -16 ) gray_brick 0 0 0 1 1 ( -160 192 -16 ) ( -159 192 -16 ) ( -160 193 -16 ) gray_brick 0 0 0 1 1
} }
// brush 5 // brush 5
{ {
( 480 64 272 ) ( 480 64 273 ) ( 480 65 272 ) sgrate4 0 0 0 1 1 ( 512 64 816 ) ( 512 64 817 ) ( 512 65 816 ) sgrate4 0 0 0 1 1
( -64 -64 240 ) ( -64 -63 240 ) ( -64 -64 241 ) sgrate4 0 0 0 1 1 ( -64 -64 784 ) ( -64 -63 784 ) ( -64 -64 785 ) sgrate4 0 0 0 1 1
( 64 192 272 ) ( 65 192 272 ) ( 64 192 273 ) sgrate4 0 0 0 1 1 ( 64 256 816 ) ( 65 256 816 ) ( 64 256 817 ) sgrate4 0 0 0 1 1
( -64 -288 240 ) ( -64 -288 241 ) ( -63 -288 240 ) sgrate4 0 0 0 1 1 ( -64 -320 784 ) ( -64 -320 785 ) ( -63 -320 784 ) sgrate4 0 0 0 1 1
( 64 64 272 ) ( 64 65 272 ) ( 65 64 272 ) sgrate4 0 0 0 1 1 ( 64 64 816 ) ( 64 65 816 ) ( 65 64 816 ) sgrate4 0 0 0 1 1
( -64 -64 256 ) ( -63 -64 256 ) ( -64 -63 256 ) sgrate4 0 0 0 1 1 ( -64 -64 800 ) ( -63 -64 800 ) ( -64 -63 800 ) sgrate4 0 0 0 1 1
} }
// brush 6 // brush 6
{ {
( 192 256 16 ) ( 192 256 17 ) ( 192 257 16 ) gray_brick 0 0 0 1 1 ( 192 320 16 ) ( 192 320 17 ) ( 192 321 16 ) gray_brick 0 0 0 1 1
( -64 128 -16 ) ( -64 129 -16 ) ( -64 128 -15 ) gray_brick 0 0 0 1 1 ( -112 192 -16 ) ( -112 193 -16 ) ( -112 192 -15 ) gray_brick 0 0 0 1 1
( -192 224 16 ) ( -191 224 16 ) ( -192 224 17 ) gray_brick 0 0 0 1 1 ( -192 288 16 ) ( -191 288 16 ) ( -192 288 17 ) gray_brick 0 0 0 1 1
( -320 192 -16 ) ( -320 192 -15 ) ( -319 192 -16 ) gray_brick 0 0 0 1 1 ( -320 256 -16 ) ( -320 256 -15 ) ( -319 256 -16 ) gray_brick 0 0 0 1 1
( -192 256 256 ) ( -192 257 256 ) ( -191 256 256 ) gray_brick 0 0 0 1 1 ( -192 320 800 ) ( -192 321 800 ) ( -191 320 800 ) gray_brick 0 0 0 1 1
( -320 128 -16 ) ( -319 128 -16 ) ( -320 129 -16 ) gray_brick 0 0 0 1 1 ( -320 192 -16 ) ( -319 192 -16 ) ( -320 193 -16 ) gray_brick 0 0 0 1 1
} }
// brush 7 // brush 7
{ {
( 224 -64 64 ) ( 256 -64 80 ) ( 256 -64 64 ) +aulrichbut 0 0 0 1 1
( 192 -64 64 ) ( 192 -32 80 ) ( 192 -64 80 ) +aulrichbut 0 0 0 1 1
( 224 -64 64 ) ( 256 -32 64 ) ( 224 -32 64 ) +aulrichbut 0 0 0 1 1
( 224 -64 128 ) ( 256 -32 128 ) ( 256 -64 128 ) +aulrichbut 0 0 0 1 1
( 224 -0 64 ) ( 256 -0 80 ) ( 224 -0 80 ) +aulrichbut 0 0 0 1 1
( 256 -64 64 ) ( 256 -32 80 ) ( 256 -32 64 ) +aulrichbut 0 0 0 1 1 ( 256 -64 64 ) ( 256 -32 80 ) ( 256 -32 64 ) +aulrichbut 0 0 0 1 1
( 192 -64 64 ) ( 192 -32 80 ) ( 192 -64 80 ) +aulrichbut 0 0 0 1 1
( 224 -0 64 ) ( 256 -0 80 ) ( 224 -0 80 ) +aulrichbut 0 0 0 1 1
( 224 -64 64 ) ( 256 -64 80 ) ( 256 -64 64 ) +aulrichbut 0 0 0 1 1
( 224 -64 128 ) ( 256 -32 128 ) ( 256 -64 128 ) +aulrichbut 0 0 0 1 1
( 224 -64 64 ) ( 256 -32 64 ) ( 224 -32 64 ) +aulrichbut 0 0 0 1 1
} }
} }
// entity 1 // entity 1
{ {
"classname" "info_player_start" "classname" "info_player_start"
"origin" "112 -64 40" "origin" "48 -208 40"
"angle" "-0" "angle" "45"
} }
// entity 2 // entity 2
{ {
"classname" "light" "classname" "light"
"origin" "224 -32 128" "origin" "224 -32 128"
"angle" "-0" "angle" "0"
"delay" "2" "delay" "2"
} }
// entity 3 // entity 3
{ {
"classname" "light" "classname" "light"
"origin" "224 -32 64" "origin" "224 -32 64"
"angle" "-0" "angle" "0"
"delay" "2" "delay" "2"
} }
// entity 4 // entity 4
{ {
"classname" "light" "classname" "light"
"origin" "192 -32 96" "origin" "192 -32 96"
"angle" "-0" "angle" "0"
"delay" "2" "delay" "2"
} }
// entity 5 // entity 5
{ {
"classname" "light" "classname" "light"
"origin" "256 -32 96" "origin" "256 -32 96"
"angle" "-0" "angle" "0"
"delay" "2" "delay" "2"
} }
// entity 6 // entity 6
{ {
"classname" "light" "classname" "light"
"origin" "224 -64 96" "origin" "224 -64 96"
"angle" "90" "angle" "0"
"delay" "2" "delay" "2"
} }
// entity 7 // entity 7
{ {
"classname" "light" "classname" "light"
"origin" "224 -0 96" "origin" "224 -0 96"
"angle" "90" "angle" "0"
"delay" "2" "delay" "2"
} }