fix multiple bounce interaction with lightgrid

This commit is contained in:
Jonathan 2023-09-16 11:55:10 -04:00
parent 147be8f87a
commit 0509c9a790
6 changed files with 21 additions and 58 deletions

View File

@ -28,5 +28,5 @@ struct mbsp_t;
// public functions // public functions
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);
void ClearBounceLights(const mbsp_t *bsp);

View File

@ -51,7 +51,7 @@ std::unique_ptr<lightsurf_t> CreateLightmapSurface(const mbsp_t *bsp, const mfac
bool Face_IsLightmapped(const mbsp_t *bsp, const mface_t *face); bool Face_IsLightmapped(const mbsp_t *bsp, const mface_t *face);
bool Face_IsEmissive(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 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 PostProcessLightFace(const mbsp_t *bsp, lightsurf_t &lightsurf, const settings::worldspawn_keys &cfg);
void FinishLightmapSurface(const mbsp_t *bsp, lightsurf_t *lightsurf); void FinishLightmapSurface(const mbsp_t *bsp, lightsurf_t *lightsurf);
void SaveLightmapSurface(const mbsp_t *bsp, mface_t *face, facesup_t *facesup, void SaveLightmapSurface(const mbsp_t *bsp, mface_t *face, facesup_t *facesup,

View File

@ -52,7 +52,7 @@ struct surfacelight_t
// Surface light settings... // Surface light settings...
struct per_style_t struct per_style_t
{ {
bool bounce = false; // whether this is a direct or indirect emission std::optional<size_t> 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, * disables use of the surfnormal. We set this to true on sky surface lights,
* to avoid black seams on geometry meeting the sky * to avoid black seams on geometry meeting the sky

View File

@ -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, static void MakeBounceLight(const mbsp_t *bsp, const settings::worldspawn_keys &cfg, lightsurf_t &surf,
qvec3d texture_color, int32_t style, std::vector<qvec3f> &points, qvec3d texture_color, int32_t style, std::vector<qvec3f> &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)) { if (!Face_IsEmissive(bsp, surf.face)) {
return; return;
@ -130,7 +130,7 @@ static void MakeBounceLight(const mbsp_t *bsp, const settings::worldspawn_keys &
{ {
auto &l = surf.vpl; auto &l = surf.vpl;
auto &setting = l->styles.emplace_back(); auto &setting = l->styles.emplace_back();
setting.bounce = true; setting.bounce_level = depth;
setting.style = style; setting.style = style;
setting.totalintensity = intensity * area; setting.totalintensity = intensity * area;
setting.intensity = setting.totalintensity / l->points.size(); 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)) { if (!Face_ShouldBounce(bsp, &face)) {
return false; return false;
@ -229,53 +229,19 @@ static bool MakeBounceLightsThread(const settings::worldspawn_keys &cfg, const m
} }
for (auto &style : emitcolors) { 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; return true;
} }
static void ClearBounceLightsThread(const mbsp_t *bsp, const mface_t &face) bool MakeBounceLights(const settings::worldspawn_keys &cfg, const mbsp_t *bsp, size_t depth)
{
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)
{ {
logging::funcheader(); logging::funcheader();
std::atomic_bool any_to_bounce = false; 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(); 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); });
}

View File

@ -941,23 +941,20 @@ static void LightWorld(bspdata_t *bspdata, bool forcedscale)
for (size_t i = 0; i < light_options.bounce.value(); i++) { for (size_t i = 0; i < light_options.bounce.value(); i++) {
if (i != 0) { if (!MakeBounceLights(light_options, &bsp, i)) {
ClearBounceLights(&bsp);
}
if (!MakeBounceLights(light_options, &bsp)) {
logging::header("No bounces; indirect lighting halted"); logging::header("No bounces; indirect lighting halted");
break; break;
} }
logging::header(fmt::format("Indirect Lighting (pass {0})", i).c_str()); // mxd logging::header(fmt::format("Indirect Lighting (pass {0})", i).c_str()); // mxd
logging::parallel_for(static_cast<size_t>(0), bsp.dfaces.size(), [&bsp](size_t i) {
if (light_surfaces[i] && Face_IsLightmapped(&bsp, &bsp.dfaces[i])) { logging::parallel_for(static_cast<size_t>(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__) #if defined(HAVE_EMBREE) && defined(__SSE2__)
_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
#endif #endif
IndirectLightFace(&bsp, *light_surfaces[i].get(), light_options); IndirectLightFace(&bsp, *light_surfaces[f].get(), light_options, i);
} }
}); });
} }

View File

@ -1982,7 +1982,7 @@ SurfaceLight_SphereCull(const surfacelight_t *vpl, const lightsurf_t *lightsurf,
} }
static void // mxd 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<size_t> bounce_depth,
const vec_t &standard_scale, const vec_t &sky_scale, const float &hotspot_clamp) const vec_t &standard_scale, const vec_t &sky_scale, const float &hotspot_clamp)
{ {
const settings::worldspawn_keys &cfg = *lightsurf->cfg; 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) { for (const auto &vpl_setting : surf_ptr->vpl->styles) {
if (vpl_setting.bounce != bounce) if (vpl_setting.bounce_level != bounce_depth)
continue; continue;
else if (SurfaceLight_SphereCull(&vpl, lightsurf, vpl_setting, surflight_gate, hotspot_clamp)) else if (SurfaceLight_SphereCull(&vpl, lightsurf, vpl_setting, surflight_gate, hotspot_clamp))
continue; continue;
@ -2113,7 +2113,7 @@ LightPoint_SurfaceLight(const mbsp_t *bsp, const std::vector<uint8_t> *pvs, rays
// 1 ray // 1 ray
for (auto &vpl_settings : vpl.styles) { for (auto &vpl_settings : vpl.styles) {
if (vpl_settings.bounce != bounce) if (vpl_settings.bounce_level.has_value() != bounce)
continue; continue;
qvec3f pos = vpl.points[c]; qvec3f pos = vpl.points[c];
@ -3363,7 +3363,7 @@ void DirectLightFace(const mbsp_t *bsp, lightsurf_t &lightsurf, const settings::
// mxd. Add surface lights... // mxd. Add surface lights...
// FIXME: negative surface lights // FIXME: negative surface lights
LightFace_SurfaceLight( 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); LightFace_LocalMin(bsp, face, &lightsurf, lightmaps);
@ -3388,7 +3388,7 @@ void DirectLightFace(const mbsp_t *bsp, lightsurf_t &lightsurf, const settings::
* IndirectLightFace * 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; auto face = lightsurf.face;
const modelinfo_t *modelinfo = ModelInfoForFace(bsp, Face_GetNum(bsp, 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 */ /* add bounce lighting */
// note: scale here is just to keep it close-ish to the old code // note: scale here is just to keep it close-ish to the old code
LightFace_SurfaceLight( 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);
} }
} }
} }