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:
parent
91124d296f
commit
d8fd13d481
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
Loading…
Reference in New Issue