light: hack around surface lights getting a black spot when a luxel lines up with a surflight emission point

This commit is contained in:
Eric Wasylishen 2023-06-06 22:29:51 -06:00
parent 062c458913
commit 502a490e5b
3 changed files with 51 additions and 3 deletions

View File

@ -1957,14 +1957,17 @@ LightFace_SurfaceLight(const mbsp_t *bsp, lightsurf_t *lightsurf, lightmapdict_t
qvec3f pos = vpl.points[c]; qvec3f pos = vpl.points[c];
qvec3f dir = lightsurf_pos - pos; qvec3f dir = lightsurf_pos - pos;
float dist = qv::length(dir); float dist = qv::length(dir);
bool use_normal = true;
if (dist == 0.0f) if (dist == 0.0f) {
dir = lightsurf_normal; dir = lightsurf_normal;
else use_normal = false;
} else {
dir /= dist; dir /= dist;
}
const qvec3f indirect = GetSurfaceLighting( const qvec3f indirect = GetSurfaceLighting(
cfg, &vpl, dir, dist, lightsurf_normal, true, standard_scale, sky_scale, hotspot_clamp); cfg, &vpl, dir, dist, lightsurf_normal, use_normal, standard_scale, sky_scale, hotspot_clamp);
if (!qv::gate(indirect, surflight_gate)) { // Each point contributes very little to the final result if (!qv::gate(indirect, surflight_gate)) { // Each point contributes very little to the final result
rs.pushRay(i, pos, dir, dist, &indirect); rs.pushRay(i, pos, dir, dist, &indirect);
} }

View File

@ -0,0 +1,36 @@
// Game: Quake 2
// Format: Quake2 (Valve)
// entity 0
{
"classname" "worldspawn"
"_surflight_minlight_scale" "0"
"_minlight_mottle" "0"
"_tb_textures" "textures/e1u1"
// brush 0
{
( -1152 -224 -608 ) ( -1152 -223 -608 ) ( -1152 -224 -607 ) e1u1/skip [ 0 -1 0 0 ] [ 0 0 -1 16 ] 0 1 1 1 640 0
( -1296 -224 -608 ) ( -1296 -224 -607 ) ( -1295 -224 -608 ) e1u1/skip [ 1 0 0 0 ] [ 0 0 -1 80 ] 0 1 1 1 640 0
( -1296 -224 -608 ) ( -1295 -224 -608 ) ( -1296 -223 -608 ) e1u1/skip [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 1 640 0
( -640 160 -592 ) ( -640 161 -592 ) ( -639 160 -592 ) e1u1/skip [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 1 640 0
( -640 160 -592 ) ( -639 160 -592 ) ( -640 160 -591 ) e1u1/skip [ -1 0 0 0 ] [ 0 0 -1 80 ] 0 1 1 1 640 0
( -848 160 -592 ) ( -848 160 -591 ) ( -848 161 -592 ) e1u1/skip [ 0 1 0 0 ] [ 0 0 -1 16 ] 0 1 1 1 640 0
}
}
// entity 1
{
"classname" "func_group"
// brush 0
{
( -992 16 -472 ) ( -992 17 -472 ) ( -992 16 -471 ) e1u1/skip [ 0 0 -1.0000000000000002 -16 ] [ 0 -1.0000000000000002 0 0 ] 0 1 1
( -976 0 -480 ) ( -977 0 -480 ) ( -976 0 -479 ) e1u1/skip [ 1.0000000000000002 0 0 0 ] [ 0 0 1.0000000000000002 16 ] 0 1 1
( -976 0 -480 ) ( -976 1 -480 ) ( -977 0 -480 ) e1u1/baselt_5 [ 1.6081226496766366e-16 -1 0 0 ] [ 1 1.6081226496766366e-16 0 0 ] 90 1 1 0 1 2500
( -992 16 -472 ) ( -993 16 -472 ) ( -992 17 -472 ) e1u1/skip [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1
( -992 16 -472 ) ( -992 16 -471 ) ( -993 16 -472 ) e1u1/skip [ 1.0000000000000002 0 0 0 ] [ 0 0 -1.0000000000000002 0 ] 0 1 1
( -976 0 -480 ) ( -976 0 -479 ) ( -976 1 -480 ) e1u1/skip [ 0 0 1.0000000000000002 0 ] [ 0 -1.0000000000000002 0 0 ] 0 1 1
}
}
// entity 2
{
"classname" "info_player_start"
"origin" "-1040 0 -568"
}

View File

@ -778,4 +778,13 @@ TEST_CASE("lit water opt-in")
auto *ti = Face_Texinfo(&bsp, f); auto *ti = Face_Texinfo(&bsp, f);
CHECK(ti->flags.native == TEX_SPECIAL); CHECK(ti->flags.native == TEX_SPECIAL);
} }
}
TEST_CASE("q2_light_divzero")
{
auto [bsp, bspx] = QbspVisLight_Q2("q2_light_divzero.map", {"-world_units_per_luxel", "8"});
INFO("should not have a black spot in the center of the light face");
CheckFaceLuxelAtPoint(&bsp, &bsp.dmodels[0], {255, 127, 63}, {-992, 0, -480}, {0, 0, -1}, nullptr, &bspx);
CheckFaceLuxelAtPoint(&bsp, &bsp.dmodels[0], {255, 127, 63}, {-984, 8, -480}, {0, 0, -1}, nullptr, &bspx);
} }