light: fix angled emissive surfaces not shining on adjacent faces

This commit is contained in:
Eric Wasylishen 2022-11-19 14:57:56 -07:00
parent c9111b2a6c
commit 0c4aab737d
4 changed files with 88 additions and 3 deletions

View File

@ -65,7 +65,7 @@ std::vector<const mface_t *> BSP_FindFacesAtPoint(
* is used to disambiguate these.
*/
const mface_t *BSP_FindFaceAtPoint(
const mbsp_t *bsp, const dmodelh2_t *model, const qvec3d &point, const qvec3d &wantedNormal);
const mbsp_t *bsp, const dmodelh2_t *model, const qvec3d &point, const qvec3d &wantedNormal = qvec3d(0, 0, 0));
/**
* Searches for a decision node in hull0 that contains `point`, and has a plane normal of either
* wanted_normal or -wanted_normal.

View File

@ -1709,9 +1709,9 @@ inline qvec3f GetSurfaceLighting(const settings::worldspawn_keys &cfg, const sur
float dp2 = qv::dot(sp_vpl, normal);
if (!vpl->omnidirectional) {
if (dp1 < 0.0f)
if (dp1 < -LIGHT_ANGLE_EPSILON)
return {0}; // sample point behind vpl
if (dp2 < 0.0f)
if (dp2 < -LIGHT_ANGLE_EPSILON)
return {0}; // vpl behind sample face
// Rescale a bit to brighten the faces nearly-perpendicular to the surface light plane...

View File

@ -0,0 +1,69 @@
// Game: Quake 2
// Format: Quake2 (Valve)
// entity 0
{
"mapversion" "220"
"classname" "worldspawn"
"_tb_textures" "textures/e1u1"
"_bounce" "0"
// brush 0
{
( 304 -32 176 ) ( 288 -48 304 ) ( 288 -48 176 ) e1u1/color1_6 [ -0.7071067811865476 -0.7071067811865476 0 0 ] [ 0 0 -1 0 ] 0 1 1
( 240 -384 32 ) ( 240 -384 33 ) ( 241 -384 32 ) e1u1/skip [ 1.0000000000000002 0 0 0 ] [ 0 0 1.0000000000000002 0 ] 0 1 1
( 240 -48 32 ) ( 241 -48 32 ) ( 240 -47 32 ) e1u1/skip [ 1.0000000000000002 0 0 0 ] [ 0 -1.0000000000000002 0 0 ] 0 1 1
( 432 -32 160 ) ( 432 -31 160 ) ( 433 -32 160 ) e1u1/skip [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1
( 160 -176 160 ) ( 160 -256 176 ) ( 160 -256 304 ) e1u1/skip [ 0 0 1.0000000000000002 0 ] [ 0 -1.0000000000000002 0 0 ] 0 1 1
}
// brush 1
{
( 160 -176 160 ) ( 160 -256 304 ) ( 160 -256 176 ) e1u1/skip [ 0 0 -1.0000000000000002 0 ] [ 0 -1.0000000000000002 0 0 ] 0 1 1
( 304 -32 176 ) ( 288 -48 304 ) ( 288 -48 176 ) e1u1/baselt_5 [ 1.0000000000000002 0 0 0 ] [ 0 0 -1.0000000000000002 32 ] 0 1 1 0 1 1000
( 240 -384 32 ) ( 240 -384 33 ) ( 241 -384 32 ) e1u1/skip [ 1.0000000000000002 0 0 0 ] [ 0 0 1.0000000000000002 0 ] 0 1 1
( 240 -48 32 ) ( 241 -48 32 ) ( 240 -47 32 ) e1u1/skip [ 1.0000000000000002 0 0 0 ] [ 0 -1.0000000000000002 0 0 ] 0 1 1
( 432 -32 160 ) ( 432 -31 160 ) ( 433 -32 160 ) e1u1/skip [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1
( 192 -144 112 ) ( 192 -144 144 ) ( 192 -16 144 ) e1u1/skip [ 0 0 1.0000000000000002 0 ] [ 0 -1.0000000000000002 0 0 ] 0 1 1
}
// brush 2
{
( 192 -144 112 ) ( 192 -16 144 ) ( 192 -144 144 ) e1u1/skip [ 0 0 -1.0000000000000002 0 ] [ 0 -1.0000000000000002 0 0 ] 0 1 1
( 304 -32 176 ) ( 288 -48 304 ) ( 288 -48 176 ) e1u1/color1_6 [ -0.7071067811865476 -0.7071067811865476 0 0 ] [ 0 0 -1 0 ] 0 1 1
( 240 -384 32 ) ( 240 -384 33 ) ( 241 -384 32 ) e1u1/skip [ 1.0000000000000002 0 0 0 ] [ 0 0 1.0000000000000002 0 ] 0 1 1
( 240 -48 32 ) ( 241 -48 32 ) ( 240 -47 32 ) e1u1/skip [ 1.0000000000000002 0 0 0 ] [ 0 -1.0000000000000002 0 0 ] 0 1 1
( 432 -32 160 ) ( 432 -31 160 ) ( 433 -32 160 ) e1u1/skip [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1
( 432 -32 48 ) ( 433 -32 48 ) ( 432 -32 49 ) e1u1/color1_6 [ 1.0000000000000002 0 0 -48 ] [ 0 0 -1.0000000000000002 0 ] 0 1 1
( 352 -32 128 ) ( 352 96 96 ) ( 352 -32 96 ) e1u1/skip [ 0 0 1.0000000000000002 0 ] [ 0 -1.0000000000000002 0 0 ] 0 1 1
}
// brush 3
{
( 352 -32 128 ) ( 352 -32 96 ) ( 352 96 96 ) e1u1/skip [ 0 0 -1.0000000000000002 0 ] [ 0 -1.0000000000000002 0 0 ] 0 1 1
( 240 -384 32 ) ( 240 -384 33 ) ( 241 -384 32 ) e1u1/skip [ 1.0000000000000002 0 0 0 ] [ 0 0 1.0000000000000002 0 ] 0 1 1
( 240 -48 32 ) ( 241 -48 32 ) ( 240 -47 32 ) e1u1/skip [ 1.0000000000000002 0 0 0 ] [ 0 -1.0000000000000002 0 0 ] 0 1 1
( 432 -32 160 ) ( 432 -31 160 ) ( 433 -32 160 ) e1u1/skip [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1
( 432 -32 48 ) ( 433 -32 48 ) ( 432 -32 49 ) e1u1/baselt_5 [ 1.0000000000000002 0 0 -64 ] [ 0 0 -1.0000000000000002 32 ] 0 1 1 0 1 1000
( 384 -32 160 ) ( 384 96 128 ) ( 384 -32 128 ) e1u1/skip [ 0 0 1.0000000000000002 0 ] [ 0 -1.0000000000000002 0 0 ] 0 1 1
}
// brush 4
{
( 384 -32 160 ) ( 384 -32 128 ) ( 384 96 128 ) e1u1/skip [ 0 0 -1.0000000000000002 0 ] [ 0 -1.0000000000000002 0 0 ] 0 1 1
( 240 -384 32 ) ( 240 -384 33 ) ( 241 -384 32 ) e1u1/skip [ 1.0000000000000002 0 0 0 ] [ 0 0 1.0000000000000002 0 ] 0 1 1
( 240 -48 32 ) ( 241 -48 32 ) ( 240 -47 32 ) e1u1/skip [ 1.0000000000000002 0 0 0 ] [ 0 -1.0000000000000002 0 0 ] 0 1 1
( 432 -32 160 ) ( 432 -31 160 ) ( 433 -32 160 ) e1u1/skip [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1
( 432 -32 48 ) ( 433 -32 48 ) ( 432 -32 49 ) e1u1/color1_6 [ 1.0000000000000002 0 0 -48 ] [ 0 0 -1.0000000000000002 0 ] 0 1 1
( 496 -32 48 ) ( 496 -32 49 ) ( 496 -31 48 ) e1u1/skip [ 0 0 1.0000000000000002 16 ] [ 0 -1.0000000000000002 0 0 ] 0 1 1
}
// brush 5
{
( -160 -256 16 ) ( -160 -255 16 ) ( -160 -256 17 ) e1u1/skip [ 0 -1 0 0 ] [ 0 0 -1 0 ] 0 1 1
( 80 -384 16 ) ( 80 -384 17 ) ( 81 -384 16 ) e1u1/skip [ 1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1
( 80 -256 16 ) ( 81 -256 16 ) ( 80 -255 16 ) e1u1/skip [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1
( 496 -32 32 ) ( 496 -31 32 ) ( 497 -32 32 ) e1u1/skip [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1
( 496 368 32 ) ( 497 368 32 ) ( 496 368 33 ) e1u1/skip [ -1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1
( 496 -32 32 ) ( 496 -32 33 ) ( 496 -31 32 ) e1u1/skip [ 0 1 0 0 ] [ 0 0 -1 0 ] 0 1 1
}
}
// entity 1
{
"classname" "info_player_start"
"origin" "288 144 56"
"angle" "270"
}

View File

@ -147,3 +147,19 @@ TEST_CASE("-novanilla + -world_units_per_luxel")
}
CHECK(bsp.dlightdata.size() == expected_dlightdata_bytes);
}
TEST_CASE("emissive lights") {
auto [bsp, bspx] = LoadTestmap("q2_light_flush.map", {});
// all of this face should be receiving some light
auto *face = BSP_FindFaceAtPoint(&bsp, &bsp.dmodels[0], {244, -92, 92});
const faceextents_t extents(*face, bsp, LMSCALE_DEFAULT);
for (int x = 0; x < extents.width(); ++x) {
for (int y = 0; y < extents.height(); ++y) {
auto sample = LM_Sample(&bsp, extents, face->lightofs, {x, y});
INFO("sample ", x, ", ", y);
CHECK(sample[0] > 0);
}
}
}