From 82aa1e43967838e5cd626ad64ba60b91c5ee287b Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Wed, 14 Dec 2022 21:46:36 -0700 Subject: [PATCH] light: make "_light_alpha 0" behave as expected (invisible to light) --- include/common/bspfile.hh | 2 +- light/trace_embree.cc | 3 +- qbsp/map.cc | 4 +- qbsp/writebsp.cc | 2 +- testmaps/q2_light_translucency.map | 94 +++++++++++++++++++++++++++--- tests/test_ltface.cc | 36 ++++++++++-- 6 files changed, 122 insertions(+), 19 deletions(-) diff --git a/include/common/bspfile.hh b/include/common/bspfile.hh index a480d2f6..aa58a9bd 100644 --- a/include/common/bspfile.hh +++ b/include/common/bspfile.hh @@ -208,7 +208,7 @@ struct surfflags_t qvec3b minlight_color; // custom opacity - vec_t light_alpha; + std::optional light_alpha; // maxlight value for this face vec_t maxlight; diff --git a/light/trace_embree.cc b/light/trace_embree.cc index ca5e831f..7e4b57f2 100644 --- a/light/trace_embree.cc +++ b/light/trace_embree.cc @@ -67,9 +67,8 @@ static float Face_Alpha(const mbsp_t *bsp, const modelinfo_t *modelinfo, const m const int surf_flags = Face_ContentsOrSurfaceFlags(bsp, face); const bool is_q2 = bsp->loadversion->game->id == GAME_QUAKE_II; - // for "_light_alpha", 0 is considered unset if (extended_flags.light_alpha) { - return extended_flags.light_alpha; + return *extended_flags.light_alpha; } // next check "alpha" key (q1) diff --git a/qbsp/map.cc b/qbsp/map.cc index 26e3059a..203bdcda 100644 --- a/qbsp/map.cc +++ b/qbsp/map.cc @@ -680,8 +680,8 @@ static surfflags_t SurfFlagsForEntity(const maptexinfo_t &texinfo, const mapenti } // handle "_light_alpha" - const vec_t lightalpha = entity.epairs.get_float("_light_alpha"); - if (lightalpha != 0.0) { + if (entity.epairs.has("_light_alpha")) { + const vec_t lightalpha = entity.epairs.get_float("_light_alpha"); flags.light_alpha = clamp(lightalpha, 0.0, 1.0); } diff --git a/qbsp/writebsp.cc b/qbsp/writebsp.cc index 91f91b86..033470a7 100644 --- a/qbsp/writebsp.cc +++ b/qbsp/writebsp.cc @@ -393,7 +393,7 @@ static void WriteExtendedTexinfoFlags(void) t["minlight_color"] = tx.flags.minlight_color; } if (tx.flags.light_alpha) { - t["light_alpha"] = tx.flags.light_alpha; + t["light_alpha"] = *tx.flags.light_alpha; } if (tx.flags.lightcolorscale != 1.0) { t["lightcolorscale"] = tx.flags.lightcolorscale; diff --git a/testmaps/q2_light_translucency.map b/testmaps/q2_light_translucency.map index 84653c6e..e1ae269f 100644 --- a/testmaps/q2_light_translucency.map +++ b/testmaps/q2_light_translucency.map @@ -9,7 +9,7 @@ "_tb_def" "builtin:Quake2.fgd" // brush 0 { -( -160 -256 16 ) ( -160 -255 16 ) ( -160 -256 17 ) e1u1/floor1_1 [ 0 -1 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( -768 -256 16 ) ( -768 -255 16 ) ( -768 -256 17 ) e1u1/floor1_1 [ 0 -1 0 0 ] [ 0 0 -1 0 ] 0 1 1 ( 80 -384 16 ) ( 80 -384 17 ) ( 81 -384 16 ) e1u1/floor1_1 [ 1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 ( 80 -256 16 ) ( 81 -256 16 ) ( 80 -255 16 ) e1u1/floor1_1 [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 ( 496 -32 32 ) ( 496 -31 32 ) ( 497 -32 32 ) e1u1/floor1_1 [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 @@ -18,7 +18,7 @@ } // brush 1 { -( -160 -384 32 ) ( -160 -383 32 ) ( -160 -384 33 ) e1u1/floor1_1 [ 0 -1 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( -768 -384 32 ) ( -768 -383 32 ) ( -768 -384 33 ) e1u1/floor1_1 [ 0 -1 0 0 ] [ 0 0 -1 0 ] 0 1 1 ( -160 -384 32 ) ( -160 -384 33 ) ( -159 -384 32 ) e1u1/floor1_1 [ 1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 ( -160 -384 32 ) ( -159 -384 32 ) ( -160 -383 32 ) e1u1/floor1_1 [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 ( 256 -320 288 ) ( 256 -319 288 ) ( 257 -320 288 ) e1u1/floor1_1 [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 @@ -27,7 +27,7 @@ } // brush 2 { -( -160 304 32 ) ( -160 305 32 ) ( -160 304 33 ) e1u1/floor1_1 [ 0 -1 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( -768 304 32 ) ( -768 305 32 ) ( -768 304 33 ) e1u1/floor1_1 [ 0 -1 0 0 ] [ 0 0 -1 0 ] 0 1 1 ( -160 304 32 ) ( -160 304 33 ) ( -159 304 32 ) e1u1/floor1_1 [ 1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 ( -160 304 32 ) ( -159 304 32 ) ( -160 305 32 ) e1u1/floor1_1 [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 ( 256 368 288 ) ( 256 369 288 ) ( 257 368 288 ) e1u1/floor1_1 [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 @@ -40,12 +40,12 @@ ( -784 -320 32 ) ( -784 -320 33 ) ( -783 -320 32 ) e1u1/floor1_1 [ 1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 ( -784 240 32 ) ( -783 240 32 ) ( -784 241 32 ) e1u1/floor1_1 [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 ( -368 304 288 ) ( -368 305 288 ) ( -367 304 288 ) e1u1/floor1_1 [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 -( -368 304 48 ) ( -367 304 48 ) ( -368 304 49 ) e1u1/floor1_1 [ -1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( -368 192 48 ) ( -367 192 48 ) ( -368 192 49 ) e1u1/floor1_1 [ -1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 ( -128 304 48 ) ( -128 304 49 ) ( -128 305 48 ) e1u1/floor1_1 [ 0 1 0 0 ] [ 0 0 -1 0 ] 0 1 1 } // brush 4 { -( -160 -256 288 ) ( -160 -255 288 ) ( -160 -256 289 ) e1u1/floor1_1 [ 0 -1 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( -768 -256 288 ) ( -768 -255 288 ) ( -768 -256 289 ) e1u1/floor1_1 [ 0 -1 0 0 ] [ 0 0 -1 0 ] 0 1 1 ( 80 -320 288 ) ( 80 -320 289 ) ( 81 -320 288 ) e1u1/floor1_1 [ 1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 ( 80 -256 288 ) ( 81 -256 288 ) ( 80 -255 288 ) e1u1/floor1_1 [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 ( 496 -32 304 ) ( 496 -31 304 ) ( 497 -32 304 ) e1u1/floor1_1 [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 @@ -70,12 +70,48 @@ ( 336 0 184 ) ( 337 0 184 ) ( 336 0 185 ) e1u1/skip [ 1.0000000000000002 0 0 0 ] [ 0 0 -1.0000000000000002 16 ] 0 1 1 32 128 0 ( 256 48 184 ) ( 256 48 185 ) ( 256 49 184 ) e1u1/skip [ 0 -1 0 0 ] [ 0 0 -1 16 ] 0 1 1 32 128 0 } +// brush 7 +{ +( -800 240 32 ) ( -800 241 32 ) ( -800 240 33 ) e1u1/floor1_1 [ 0 -1 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( -1424 -320 32 ) ( -1424 -320 33 ) ( -1423 -320 32 ) e1u1/floor1_1 [ 1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( -1424 240 32 ) ( -1423 240 32 ) ( -1424 241 32 ) e1u1/floor1_1 [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( -1008 304 288 ) ( -1008 305 288 ) ( -1007 304 288 ) e1u1/floor1_1 [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( -1008 320 48 ) ( -1007 320 48 ) ( -1008 320 49 ) e1u1/floor1_1 [ -1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( -768 304 48 ) ( -768 304 49 ) ( -768 305 48 ) e1u1/floor1_1 [ 0 1 0 0 ] [ 0 0 -1 0 ] 0 1 1 +} +// brush 8 +{ +( -448 240 32 ) ( -448 241 32 ) ( -448 240 33 ) e1u1/floor1_1 [ 0 -1 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( -1072 -320 32 ) ( -1072 -320 33 ) ( -1071 -320 32 ) e1u1/floor1_1 [ 1 0 0 32 ] [ 0 0 -1 0 ] 0 1 1 +( -1072 240 32 ) ( -1071 240 32 ) ( -1072 241 32 ) e1u1/floor1_1 [ -1 0 0 -32 ] [ 0 -1 0 0 ] 0 1 1 +( -656 304 288 ) ( -656 305 288 ) ( -655 304 288 ) e1u1/floor1_1 [ 1 0 0 32 ] [ 0 -1 0 0 ] 0 1 1 +( -656 32 48 ) ( -655 32 48 ) ( -656 32 49 ) e1u1/floor1_1 [ -1 0 0 -32 ] [ 0 0 -1 0 ] 0 1 1 +( -416 304 48 ) ( -416 304 49 ) ( -416 305 48 ) e1u1/floor1_1 [ 0 1 0 0 ] [ 0 0 -1 0 ] 0 1 1 +} +// brush 9 +{ +( -640 -112 32 ) ( -640 -111 32 ) ( -640 -112 33 ) e1u1/floor1_1 [ 0 0 -1.0000000000000002 -32 ] [ 0 -1.0000000000000002 0 0 ] 0 1 1 +( -640 -112 32 ) ( -640 -112 33 ) ( -639 -112 32 ) e1u1/floor1_1 [ 1.0000000000000002 0 0 0 ] [ 0 0 1.0000000000000002 16 ] 0 1 1 +( -640 -112 32 ) ( -639 -112 32 ) ( -640 -111 32 ) e1u1/floor1_1 [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( -576 -64 40 ) ( -576 -63 40 ) ( -575 -64 40 ) e1u1/floor1_1 [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( -576 -64 40 ) ( -575 -64 40 ) ( -576 -64 41 ) e1u1/floor1_1 [ 1.0000000000000002 0 0 0 ] [ 0 0 -1.0000000000000002 -32 ] 0 1 1 +( -576 -64 40 ) ( -576 -64 41 ) ( -576 -63 40 ) e1u1/floor1_1 [ 0 0 1.0000000000000002 32 ] [ 0 -1.0000000000000002 0 0 ] 0 1 1 +} +// brush 10 +{ +( -320 -112 32 ) ( -320 -111 32 ) ( -320 -112 33 ) e1u1/floor1_1 [ 0 0 -1.0000000000000002 -32 ] [ 0 -1.0000000000000002 0 0 ] 0 1 1 +( -320 -112 32 ) ( -320 -112 33 ) ( -319 -112 32 ) e1u1/floor1_1 [ 1.0000000000000002 0 0 0 ] [ 0 0 1.0000000000000002 16 ] 0 1 1 +( -320 -112 32 ) ( -319 -112 32 ) ( -320 -111 32 ) e1u1/floor1_1 [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( -256 -64 40 ) ( -256 -63 40 ) ( -255 -64 40 ) e1u1/floor1_1 [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( -256 -64 40 ) ( -255 -64 40 ) ( -256 -64 41 ) e1u1/floor1_1 [ 1.0000000000000002 0 0 0 ] [ 0 0 -1.0000000000000002 -32 ] 0 1 1 +( -256 -64 40 ) ( -256 -64 41 ) ( -256 -63 40 ) e1u1/floor1_1 [ 0 0 1.0000000000000002 32 ] [ 0 -1.0000000000000002 0 0 ] 0 1 1 +} } // entity 1 { "classname" "info_player_start" -"origin" "152 -256 96" -"angle" "90" +"origin" "-136 272 96" +"angle" "270" } // entity 2 { @@ -85,3 +121,47 @@ "delay" "3" "_anglesense" "0" } +// entity 3 +{ +"classname" "light" +"origin" "-296 -96 248" +"light" "150" +"delay" "3" +"_anglesense" "0" +} +// entity 4 +{ +"classname" "func_group" +"_light_alpha" "0" +// brush 0 +{ +( -384 -176 176 ) ( -384 -175 176 ) ( -384 -176 177 ) e1u1/skip [ 0 -1 0 0 ] [ 0 0 -1 16 ] 0 1 1 32 128 0 +( -424 -176 176 ) ( -424 -176 177 ) ( -423 -176 176 ) e1u1/skip [ -1.0000000000000002 0 0 16 ] [ 0 0 -1.0000000000000002 16 ] 0 1 1 32 128 0 +( -424 -176 208 ) ( -423 -176 208 ) ( -424 -175 208 ) e1u1/skip [ 0 -1.0000000000000002 0 0 ] [ -1.0000000000000002 0 0 0 ] 0 1 1 32 128 0 +( -112 48 224 ) ( -112 49 224 ) ( -111 48 224 ) e1u1/test [ 1 0 0 32 ] [ 0 -1 0 32 ] 0 2 2 32 32 0 +( -112 0 184 ) ( -111 0 184 ) ( -112 0 185 ) e1u1/skip [ 1.0000000000000002 0 0 0 ] [ 0 0 -1.0000000000000002 16 ] 0 1 1 32 128 0 +( -192 48 184 ) ( -192 48 185 ) ( -192 49 184 ) e1u1/skip [ 0 -1 0 0 ] [ 0 0 -1 16 ] 0 1 1 32 128 0 +} +} +// entity 5 +{ +"classname" "light" +"origin" "-616 -96 248" +"light" "150" +"delay" "3" +"_anglesense" "0" +} +// entity 6 +{ +"classname" "func_group" +"_light_alpha" "1" +// brush 0 +{ +( -704 -176 176 ) ( -704 -175 176 ) ( -704 -176 177 ) e1u1/skip [ 0 -1 0 0 ] [ 0 0 -1 16 ] 0 1 1 32 128 0 +( -744 -176 176 ) ( -744 -176 177 ) ( -743 -176 176 ) e1u1/skip [ -1.0000000000000002 0 0 -16 ] [ 0 0 -1.0000000000000002 16 ] 0 1 1 32 128 0 +( -744 -176 208 ) ( -743 -176 208 ) ( -744 -175 208 ) e1u1/skip [ 0 -1.0000000000000002 0 0 ] [ -1.0000000000000002 0 0 0 ] 0 1 1 32 128 0 +( -432 48 224 ) ( -432 49 224 ) ( -431 48 224 ) e1u1/test [ 1 0 0 0 ] [ 0 -1 0 32 ] 0 2 2 32 32 0 +( -432 0 184 ) ( -431 0 184 ) ( -432 0 185 ) e1u1/skip [ 1.0000000000000002 0 0 0 ] [ 0 0 -1.0000000000000002 16 ] 0 1 1 32 128 0 +( -512 48 184 ) ( -512 48 185 ) ( -512 49 184 ) e1u1/skip [ 0 -1 0 0 ] [ 0 0 -1 16 ] 0 1 1 32 128 0 +} +} diff --git a/tests/test_ltface.cc b/tests/test_ltface.cc index 5d9038f7..225a4c93 100644 --- a/tests/test_ltface.cc +++ b/tests/test_ltface.cc @@ -243,13 +243,37 @@ TEST_CASE("q2_light_translucency") { auto [bsp, bspx] = LoadTestmap("q2_light_translucency.map", {}); - auto *face_under_water = BSP_FindFaceAtPoint(&bsp, &bsp.dmodels[0], {152, -96, 32}); - REQUIRE(face_under_water); + { + auto *face_under_water = BSP_FindFaceAtPoint(&bsp, &bsp.dmodels[0], {152, -96, 32}); + REQUIRE(face_under_water); - CheckFaceLuxels(bsp, *face_under_water, [](qvec3b sample){ - INFO("green color from the texture"); - CHECK(sample == qvec3b(100, 150, 100)); - }); + CheckFaceLuxels(bsp, *face_under_water, [](qvec3b sample) { + INFO("green color from the texture"); + CHECK(sample == qvec3b(100, 150, 100)); + }); + } + + { + INFO("under _light_alpha 0 is not tinted"); + + auto *under_alpha_0_glass = BSP_FindFaceAtPoint(&bsp, &bsp.dmodels[0], {-296, -96, 40}); + REQUIRE(under_alpha_0_glass); + + CheckFaceLuxels(bsp, *under_alpha_0_glass, [](qvec3b sample) { + CHECK(sample == qvec3b(150)); + }); + } + + { + INFO("under _light_alpha 1 is fully tinted"); + + auto *under_alpha_1_glass = BSP_FindFaceAtPoint(&bsp, &bsp.dmodels[0], {-616, -96, 40}); + REQUIRE(under_alpha_1_glass); + + CheckFaceLuxels(bsp, *under_alpha_1_glass, [](qvec3b sample) { + CHECK(sample == qvec3b(0, 150, 0)); + }); + } } TEST_CASE("-visapprox vis with opaque liquids") {