light: q2: avoid black seams on geometry near sky

This commit is contained in:
Eric Wasylishen 2020-12-29 15:58:40 -07:00
parent eb842ba165
commit 2d15d20410
3 changed files with 22 additions and 6 deletions

View File

@ -26,6 +26,11 @@ See file, 'COPYING', for details.
typedef struct {
vec3_t pos;
qvec3f surfnormal;
/**
* disables use of the surfnormal. We set this to true on sky surface lights,
* to avoid black seams on geometry meeting the sky
*/
bool omnidirectional;
std::vector<qvec3f> points;
// Surface light settings...

View File

@ -1921,19 +1921,29 @@ static qvec3f
GetSurfaceLighting(const globalconfig_t &cfg, const surfacelight_t *vpl, const qvec3f &dir, const float dist, const qvec3f &normal)
{
qvec3f result{0};
const float dp1 = qv::dot(vpl->surfnormal, dir);
if (dp1 < 0.0f) return result; // sample point behind vpl
float dotProductFactor = 1.0f;
const float dp1 = qv::dot(vpl->surfnormal, dir);
const qvec3f sp_vpl = dir * -1.0f;
float dp2 = qv::dot(sp_vpl, normal);
if (dp2 < 0.0f) return result; // vpl behind sample face
if (!vpl->omnidirectional) {
if (dp1 < 0.0f) return {0}; // sample point behind vpl
if (dp2 < 0.0f) return {0}; // vpl behind sample face
dp2 = 0.5f + dp2 * 0.5f; // Rescale a bit to brighten the faces nearly-perpendicular to the surface light plane...
dotProductFactor = dp1 * dp2;
} else {
// used for sky face surface lights
dotProductFactor = dp2;
}
// Get light contribution
result = SurfaceLight_ColorAtDist(cfg, vpl->intensity, vec3_t_to_glm(vpl->color), dist);
dp2 = 0.5f + dp2 * 0.5f; // Rescale a bit to brighten the faces nearly-perpendicular to the surface light plane...
// Apply angle scale
const qvec3f resultscaled = result * dp1 * dp2;
const qvec3f resultscaled = result * dotProductFactor;
Q_assert(!std::isnan(resultscaled[0]) && !std::isnan(resultscaled[1]) && !std::isnan(resultscaled[2]));
return resultscaled;

View File

@ -149,6 +149,7 @@ MakeSurfaceLightsThread(void *arg)
// Add surfacelight...
surfacelight_t l;
l.surfnormal = vec3_t_to_glm(facenormal);
l.omnidirectional = (info->flags & Q2_SURF_SKY) ? true : false;
l.points = points;
VectorCopy(facemidpoint, l.pos);