From 0509c9a790caad7f659cde5b49d476d27070fa93 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Sat, 16 Sep 2023 11:55:10 -0400 Subject: [PATCH] fix multiple bounce interaction with lightgrid --- include/light/bounce.hh | 4 ++-- include/light/ltface.hh | 2 +- include/light/surflight.hh | 2 +- light/bounce.cc | 46 +++++--------------------------------- light/light.cc | 13 +++++------ light/ltface.cc | 12 +++++----- 6 files changed, 21 insertions(+), 58 deletions(-) diff --git a/include/light/bounce.hh b/include/light/bounce.hh index d22cd570..ecf768db 100644 --- a/include/light/bounce.hh +++ b/include/light/bounce.hh @@ -28,5 +28,5 @@ struct mbsp_t; // public functions -bool MakeBounceLights(const settings::worldspawn_keys &cfg, const mbsp_t *bsp); -void ClearBounceLights(const mbsp_t *bsp); +bool MakeBounceLights(const settings::worldspawn_keys &cfg, const mbsp_t *bsp, size_t depth); + diff --git a/include/light/ltface.hh b/include/light/ltface.hh index 1438e6d1..86b82b04 100644 --- a/include/light/ltface.hh +++ b/include/light/ltface.hh @@ -51,7 +51,7 @@ std::unique_ptr CreateLightmapSurface(const mbsp_t *bsp, const mfac bool Face_IsLightmapped(const mbsp_t *bsp, const mface_t *face); bool Face_IsEmissive(const mbsp_t *bsp, const mface_t *face); void DirectLightFace(const mbsp_t *bsp, lightsurf_t &lightsurf, const settings::worldspawn_keys &cfg); -void IndirectLightFace(const mbsp_t *bsp, lightsurf_t &lightsurf, const settings::worldspawn_keys &cfg); +void IndirectLightFace(const mbsp_t *bsp, lightsurf_t &lightsurf, const settings::worldspawn_keys &cfg, size_t bounce_depth); void PostProcessLightFace(const mbsp_t *bsp, lightsurf_t &lightsurf, const settings::worldspawn_keys &cfg); void FinishLightmapSurface(const mbsp_t *bsp, lightsurf_t *lightsurf); void SaveLightmapSurface(const mbsp_t *bsp, mface_t *face, facesup_t *facesup, diff --git a/include/light/surflight.hh b/include/light/surflight.hh index d104ac5f..6b42c7eb 100644 --- a/include/light/surflight.hh +++ b/include/light/surflight.hh @@ -52,7 +52,7 @@ struct surfacelight_t // Surface light settings... struct per_style_t { - bool bounce = false; // whether this is a direct or indirect emission + std::optional bounce_level = std::nullopt; // whether this is a direct or indirect emission /** * disables use of the surfnormal. We set this to true on sky surface lights, * to avoid black seams on geometry meeting the sky diff --git a/light/bounce.cc b/light/bounce.cc index 51669fad..65d66033 100644 --- a/light/bounce.cc +++ b/light/bounce.cc @@ -80,7 +80,7 @@ static bool Face_ShouldBounce(const mbsp_t *bsp, const mface_t *face) static void MakeBounceLight(const mbsp_t *bsp, const settings::worldspawn_keys &cfg, lightsurf_t &surf, qvec3d texture_color, int32_t style, std::vector &points, - const vec_t &area, const qvec3d &facenormal, const qvec3d &facemidpoint) + const vec_t &area, const qvec3d &facenormal, const qvec3d &facemidpoint, size_t depth) { if (!Face_IsEmissive(bsp, surf.face)) { return; @@ -130,7 +130,7 @@ static void MakeBounceLight(const mbsp_t *bsp, const settings::worldspawn_keys & { auto &l = surf.vpl; auto &setting = l->styles.emplace_back(); - setting.bounce = true; + setting.bounce_level = depth; setting.style = style; setting.totalintensity = intensity * area; setting.intensity = setting.totalintensity / l->points.size(); @@ -138,7 +138,7 @@ static void MakeBounceLight(const mbsp_t *bsp, const settings::worldspawn_keys & } } -static bool MakeBounceLightsThread(const settings::worldspawn_keys &cfg, const mbsp_t *bsp, const mface_t &face) +static bool MakeBounceLightsThread(const settings::worldspawn_keys &cfg, const mbsp_t *bsp, const mface_t &face, size_t depth) { if (!Face_ShouldBounce(bsp, &face)) { return false; @@ -229,53 +229,19 @@ static bool MakeBounceLightsThread(const settings::worldspawn_keys &cfg, const m } for (auto &style : emitcolors) { - MakeBounceLight(bsp, cfg, surf, style.second, style.first, points, area, facenormal, facemidpoint); + MakeBounceLight(bsp, cfg, surf, style.second, style.first, points, area, facenormal, facemidpoint, depth); } return true; } -static void ClearBounceLightsThread(const mbsp_t *bsp, const mface_t &face) -{ - if (!Face_ShouldBounce(bsp, &face)) { - return; - } - - auto &surf_ptr = LightSurfaces()[&face - bsp->dfaces.data()]; - - if (!surf_ptr) { - return; - } - - auto &surf = *surf_ptr.get(); - - // no bouncing yet - if (!surf.vpl) { - return; - } - - // remove all styles that are bounce - auto &l = *surf.vpl; - auto removed = std::remove_if(l.styles.begin(), l.styles.end(), [](surfacelight_t::per_style_t &p) { - return p.bounce; - }); - l.styles.erase(removed, l.styles.end()); -} - -bool MakeBounceLights(const settings::worldspawn_keys &cfg, const mbsp_t *bsp) +bool MakeBounceLights(const settings::worldspawn_keys &cfg, const mbsp_t *bsp, size_t depth) { logging::funcheader(); std::atomic_bool any_to_bounce = false; - logging::parallel_for_each(bsp->dfaces, [&](const mface_t &face) { any_to_bounce = MakeBounceLightsThread(cfg, bsp, face) || any_to_bounce; }); + logging::parallel_for_each(bsp->dfaces, [&](const mface_t &face) { any_to_bounce = MakeBounceLightsThread(cfg, bsp, face, depth) || any_to_bounce; }); return any_to_bounce.load(); } - -void ClearBounceLights(const mbsp_t *bsp) -{ - logging::funcheader(); - - logging::parallel_for_each(bsp->dfaces, [&](const mface_t &face) { ClearBounceLightsThread(bsp, face); }); -} \ No newline at end of file diff --git a/light/light.cc b/light/light.cc index e1cb2bdf..25cada9e 100644 --- a/light/light.cc +++ b/light/light.cc @@ -941,23 +941,20 @@ static void LightWorld(bspdata_t *bspdata, bool forcedscale) for (size_t i = 0; i < light_options.bounce.value(); i++) { - if (i != 0) { - ClearBounceLights(&bsp); - } - - if (!MakeBounceLights(light_options, &bsp)) { + if (!MakeBounceLights(light_options, &bsp, i)) { logging::header("No bounces; indirect lighting halted"); break; } logging::header(fmt::format("Indirect Lighting (pass {0})", i).c_str()); // mxd - logging::parallel_for(static_cast(0), bsp.dfaces.size(), [&bsp](size_t i) { - if (light_surfaces[i] && Face_IsLightmapped(&bsp, &bsp.dfaces[i])) { + + logging::parallel_for(static_cast(0), bsp.dfaces.size(), [i, &bsp](size_t f) { + if (light_surfaces[f] && Face_IsLightmapped(&bsp, &bsp.dfaces[f])) { #if defined(HAVE_EMBREE) && defined(__SSE2__) _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); #endif - IndirectLightFace(&bsp, *light_surfaces[i].get(), light_options); + IndirectLightFace(&bsp, *light_surfaces[f].get(), light_options, i); } }); } diff --git a/light/ltface.cc b/light/ltface.cc index 57b8f392..7d9a108e 100644 --- a/light/ltface.cc +++ b/light/ltface.cc @@ -1982,7 +1982,7 @@ SurfaceLight_SphereCull(const surfacelight_t *vpl, const lightsurf_t *lightsurf, } static void // mxd -LightFace_SurfaceLight(const mbsp_t *bsp, lightsurf_t *lightsurf, lightmapdict_t *lightmaps, bool bounce, +LightFace_SurfaceLight(const mbsp_t *bsp, lightsurf_t *lightsurf, lightmapdict_t *lightmaps, std::optional bounce_depth, const vec_t &standard_scale, const vec_t &sky_scale, const float &hotspot_clamp) { const settings::worldspawn_keys &cfg = *lightsurf->cfg; @@ -2004,7 +2004,7 @@ LightFace_SurfaceLight(const mbsp_t *bsp, lightsurf_t *lightsurf, lightmapdict_t for (const auto &vpl_setting : surf_ptr->vpl->styles) { - if (vpl_setting.bounce != bounce) + if (vpl_setting.bounce_level != bounce_depth) continue; else if (SurfaceLight_SphereCull(&vpl, lightsurf, vpl_setting, surflight_gate, hotspot_clamp)) continue; @@ -2113,7 +2113,7 @@ LightPoint_SurfaceLight(const mbsp_t *bsp, const std::vector *pvs, rays // 1 ray for (auto &vpl_settings : vpl.styles) { - if (vpl_settings.bounce != bounce) + if (vpl_settings.bounce_level.has_value() != bounce) continue; qvec3f pos = vpl.points[c]; @@ -3363,7 +3363,7 @@ void DirectLightFace(const mbsp_t *bsp, lightsurf_t &lightsurf, const settings:: // mxd. Add surface lights... // FIXME: negative surface lights LightFace_SurfaceLight( - bsp, &lightsurf, lightmaps, false, cfg.surflightscale.value(), cfg.surflightskyscale.value(), 16.0f); + bsp, &lightsurf, lightmaps, std::nullopt, cfg.surflightscale.value(), cfg.surflightskyscale.value(), 16.0f); } LightFace_LocalMin(bsp, face, &lightsurf, lightmaps); @@ -3388,7 +3388,7 @@ void DirectLightFace(const mbsp_t *bsp, lightsurf_t &lightsurf, const settings:: * IndirectLightFace * ============ */ -void IndirectLightFace(const mbsp_t *bsp, lightsurf_t &lightsurf, const settings::worldspawn_keys &cfg) +void IndirectLightFace(const mbsp_t *bsp, lightsurf_t &lightsurf, const settings::worldspawn_keys &cfg, size_t bounce_depth) { auto face = lightsurf.face; const modelinfo_t *modelinfo = ModelInfoForFace(bsp, Face_GetNum(bsp, face)); @@ -3403,7 +3403,7 @@ void IndirectLightFace(const mbsp_t *bsp, lightsurf_t &lightsurf, const settings /* add bounce lighting */ // note: scale here is just to keep it close-ish to the old code LightFace_SurfaceLight( - bsp, &lightsurf, lightmaps, true, cfg.bouncescale.value() * 0.5, cfg.bouncescale.value(), 128.0f); + bsp, &lightsurf, lightmaps, bounce_depth, cfg.bouncescale.value() * 0.5, cfg.bouncescale.value(), 128.0f); } } }