From d8fd13d481b9d77beaff8a9f191ddfc59db6854f Mon Sep 17 00:00:00 2001 From: Jonathan Date: Fri, 29 Jul 2022 22:26:07 -0400 Subject: [PATCH] use <= gating for brightness for surface and bounce lighting, since these can often be very small values (provides a moderate speed increase as well, counter-balancing the next change) bounce lighting generates a grid of bounces rather than a single light, improving lighting in conditions with larger faces or where the midpoint is blocked by other geometry --- include/common/qvec.hh | 17 +++++++++++++++++ light/bounce.cc | 23 ++++++++++++----------- light/ltface.cc | 18 ++++++++---------- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/include/common/qvec.hh b/include/common/qvec.hh index 57f08b65..f9aaa18b 100644 --- a/include/common/qvec.hh +++ b/include/common/qvec.hh @@ -521,6 +521,23 @@ template return epsilonEqual({}, v1, epsilon); } +template +[[nodiscard]] inline bool gate(const T &v1, T epsilon) +{ + return v1 <= epsilon; +} + +template +[[nodiscard]] inline bool gate(const qvec &v, T epsilon) +{ + for (size_t i = 0; i < N; i++) { + if (gate(v[i], epsilon)) { + return true; + } + } + return false; +} + template [[nodiscard]] constexpr bool equalExact(const qvec &v1, const qvec &v2) { diff --git a/light/bounce.cc b/light/bounce.cc index a796356f..bc94c826 100644 --- a/light/bounce.cc +++ b/light/bounce.cc @@ -103,7 +103,7 @@ inline bouncelight_t &CreateBounceLight(const mface_t *face, const mbsp_t *bsp) return l; } -static void AddBounceLight(const qvec3d &pos, std::unordered_map &&colorByStyle, +static void AddBounceLight(const qvec3d &pos, const std::unordered_map &colorByStyle, const qvec3d &surfnormal, vec_t area, const mface_t *face, const mbsp_t *bsp) { for (const auto &styleColor : colorByStyle) { @@ -116,7 +116,7 @@ static void AddBounceLight(const qvec3d &pos, std::unordered_map && bouncelight_t &l = CreateBounceLight(face, bsp); l.poly = GLM_FacePoints(bsp, face); l.poly_edgeplanes = GLM_MakeInwardFacingEdgePlanes(l.poly); - l.pos = pos; + l.pos = pos + surfnormal; l.colorByStyle = colorByStyle; for (const auto &styleColor : l.colorByStyle) { @@ -128,9 +128,9 @@ static void AddBounceLight(const qvec3d &pos, std::unordered_map && l.area = area; if (light_options.visapprox.value() == visapprox_t::VIS) { - l.leaf = Light_PointInLeaf(bsp, pos); + l.leaf = Light_PointInLeaf(bsp, l.pos); } else if (light_options.visapprox.value() == visapprox_t::RAYS) { - l.bounds = EstimateVisibleBoundsAtPoint(pos); + l.bounds = EstimateVisibleBoundsAtPoint(l.pos); } } @@ -165,7 +165,7 @@ static void MakeBounceLightsThread(const settings::worldspawn_keys &cfg, const m auto &surf = *surf_ptr.get(); winding_t winding = winding_t::from_face(bsp, &face); - const vec_t area = winding.area(); + vec_t area = winding.area(); if (!area) { return; @@ -174,11 +174,6 @@ static void MakeBounceLightsThread(const settings::worldspawn_keys &cfg, const m const vec_t area_divisor = sqrt(area); const vec_t sample_divisor = surf.points.size() / (surf.vanilla_extents.width() * surf.vanilla_extents.height()); - qplane3d faceplane = winding.plane(); - - qvec3d facemidpoint = winding.center(); - facemidpoint += faceplane.normal; // lift 1 unit - // average them, area weighted std::unordered_map sum; @@ -212,7 +207,13 @@ static void MakeBounceLightsThread(const settings::worldspawn_keys &cfg, const m emitcolors[styleColor.first] = styleColor.second * blendedcolor; } - AddBounceLight(facemidpoint, std::move(emitcolors), faceplane.normal, area, &face, bsp); + qplane3d faceplane = winding.plane(); + + area /= surf.points.size(); + + for (auto &pt : surf.points) { + AddBounceLight(pt, emitcolors, faceplane.normal, area, &face, bsp); + } } void MakeBounceLights(const settings::worldspawn_keys &cfg, const mbsp_t *bsp) diff --git a/light/ltface.cc b/light/ltface.cc index 810bc8a9..f5963715 100644 --- a/light/ltface.cc +++ b/light/ltface.cc @@ -1685,7 +1685,7 @@ inline bool BounceLight_SphereCull(const mbsp_t *bsp, const bouncelight_t *vpl, // get light contribution const qvec3f color = BounceLight_ColorAtDist(cfg, vpl->area, vpl->componentwiseMaxColor, dist); - return LightSample_Brightness(color) < 0.25f; + return qv::gate(color, 0.01f); } static bool // mxd @@ -1703,7 +1703,7 @@ SurfaceLight_SphereCull(const surfacelight_t *vpl, const lightsurf_t *lightsurf) // Get light contribution const qvec3f color = SurfaceLight_ColorAtDist(cfg, vpl->totalintensity, vpl->color, dist); - return LightSample_Brightness(color) < 0.01f; + return qv::gate(color, 0.01f); } #if 0 @@ -1775,10 +1775,9 @@ static void LightFace_Bounce(const mbsp_t *bsp, const mface_t *face, lightsurf_t const qvec3d indirect = GetIndirectLighting(cfg, &vpl, color, dir, dist, lightsurf->points[i], lightsurf->normals[i]); - if (LightSample_Brightness(indirect) < 0.25) - continue; - - rs.pushRay(i, vpl.pos, dir, dist, &indirect); + if (!qv::gate(indirect, 0.01)) { + rs.pushRay(i, vpl.pos, dir, dist, &indirect); + } } if (!rs.numPushedRays()) @@ -1857,10 +1856,9 @@ LightFace_SurfaceLight(const mbsp_t *bsp, lightsurf_t *lightsurf, lightmapdict_t dir /= dist; const qvec3d indirect = GetSurfaceLighting(cfg, &vpl, dir, dist, lightsurf_normal); - if (LightSample_Brightness(indirect) < 0.01f) // Each point contributes very little to the final result - continue; - - rs.pushRay(i, pos, dir, dist, &indirect); + if (!qv::gate(indirect, 0.01)) { // Each point contributes very little to the final result + rs.pushRay(i, pos, dir, dist, &indirect); + } } if (!rs.numPushedRays())