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
This commit is contained in:
Jonathan 2022-07-29 22:26:07 -04:00
parent 91124d296f
commit d8fd13d481
3 changed files with 37 additions and 21 deletions

View File

@ -521,6 +521,23 @@ template<size_t N, class T>
return epsilonEqual({}, v1, epsilon);
}
template<typename T>
[[nodiscard]] inline bool gate(const T &v1, T epsilon)
{
return v1 <= epsilon;
}
template<size_t N, class T>
[[nodiscard]] inline bool gate(const qvec<T, N> &v, T epsilon)
{
for (size_t i = 0; i < N; i++) {
if (gate(v[i], epsilon)) {
return true;
}
}
return false;
}
template<size_t N, class T>
[[nodiscard]] constexpr bool equalExact(const qvec<T, N> &v1, const qvec<T, N> &v2)
{

View File

@ -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<int, qvec3d> &&colorByStyle,
static void AddBounceLight(const qvec3d &pos, const std::unordered_map<int, qvec3d> &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<int, qvec3d> &&
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<int, qvec3d> &&
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<int, qvec3d> 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)

View File

@ -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())