fix multiple bounce interaction with lightgrid
This commit is contained in:
parent
147be8f87a
commit
0509c9a790
|
|
@ -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);
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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); });
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue