From 664be1eca59302850007a72be18ed000413ff168 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 2 Nov 2018 23:34:38 +0100 Subject: [PATCH] - implement the correct math for area lights --- src/lightmap/lightmap.cpp | 7 ++-- src/lightmap/lightsurface.cpp | 70 ++++++++--------------------------- src/lightmap/lightsurface.h | 2 +- 3 files changed, 19 insertions(+), 60 deletions(-) diff --git a/src/lightmap/lightmap.cpp b/src/lightmap/lightmap.cpp index 4d8b452..9acf665 100644 --- a/src/lightmap/lightmap.cpp +++ b/src/lightmap/lightmap.cpp @@ -301,11 +301,10 @@ kexVec3 kexLightmapBuilder::LightTexelSample(kexTrace &trace, const kexVec3 &ori { kexLightSurface *surfaceLight = map->lightSurfaces[i]; - float attenuation; - if (surfaceLight->TraceSurface(map, trace, surface, origin, &attenuation)) + float attenuation = surfaceLight->TraceSurface(map, trace, surface, origin); + if (attenuation > 0.0f) { - color += surfaceLight->GetRGB() * attenuation; - + color += surfaceLight->GetRGB() * surfaceLight->Intensity() * attenuation; tracedTexels++; } } diff --git a/src/lightmap/lightsurface.cpp b/src/lightmap/lightsurface.cpp index 3778075..a135b8a 100644 --- a/src/lightmap/lightsurface.cpp +++ b/src/lightmap/lightsurface.cpp @@ -243,23 +243,17 @@ void kexLightSurface::Subdivide(const float divide) } } -bool kexLightSurface::TraceSurface(FLevel *doomMap, kexTrace &trace, const surface_t *surf, const kexVec3 &origin, float *dist) +float kexLightSurface::TraceSurface(FLevel *doomMap, kexTrace &trace, const surface_t *surf, const kexVec3 &origin) { - kexVec3 normal; - kexVec3 lnormal; - float curDist; - - *dist = -M_INFINITY; - // light surface will always be fullbright if (surf == surface) { - *dist = Intensity(); - return true; + return 1.0f; } - lnormal = surface->plane.Normal(); + kexVec3 lnormal = surface->plane.Normal(); + kexVec3 normal; if (surf) { normal = surf->plane.Normal(); @@ -267,7 +261,7 @@ bool kexLightSurface::TraceSurface(FLevel *doomMap, kexTrace &trace, const surfa if (normal.Dot(lnormal) > 0) { // not facing the light surface - return false; + return 0.0f; } } else @@ -275,8 +269,7 @@ bool kexLightSurface::TraceSurface(FLevel *doomMap, kexTrace &trace, const surfa normal = kexVec3::vecUp; } - // we need to pick the closest sample point on the light surface. what really sucks is - // that we have to trace each one... which could really blow up the compile time + float total = 0.0f; for (unsigned int i = 0; i < origins.Length(); ++i) { kexVec3 center = origins[i]; @@ -289,25 +282,11 @@ bool kexLightSurface::TraceSurface(FLevel *doomMap, kexTrace &trace, const surfa continue; } - /*if(bWall) - { - angle = (origin - center).ToVec2().Normalize().Dot(lnormal.ToVec2()); - } - else - { - kexVec3 dir = (origin - center).Normalize(); + kexVec3 dir = (origin - center).Normalize(); + float attenuation = dir.Dot(lnormal); - if(surf) - { - if(normal.Dot(dir) >= 0) - { - // not even facing the light surface - continue; - } - } - - angle = dir.Dot(lnormal); - }*/ + if (attenuation <= 0.0f) + continue; // not even facing the light surface if (bWall) { @@ -324,36 +303,17 @@ bool kexLightSurface::TraceSurface(FLevel *doomMap, kexTrace &trace, const surfa // case the start/end points are directly on or inside the surface trace.Trace(center + lnormal, origin + normal); - if (trace.fraction != 1) + if (trace.fraction < 1.0f) { // something is obstructing it continue; } float d = origin.Distance(center); - - curDist = 1.0f - d / (distance * 2.0f); // 2.0 because gzdoom's dynlights do this and we want them to match - if (curDist < 0.0f) curDist = 0.0f; - - if (curDist >= 1) - { - curDist = 1; - - // might get large unlit gaps near the surface. this looks a lot worse for - // non-wall light surfaces so just clamp to full bright and exit out. - if (!bWall) - { - *dist = 1; - break; - } - } - - if (curDist > *dist) - { - *dist = curDist; - } + attenuation *= 1.0f - d / (distance * 2.0f); // 2.0 because gzdoom's dynlights do this and we want them to match + if (attenuation > 0.0f) + total += attenuation; } - *dist *= Intensity(); - return *dist > 0; + return total / origins.Length(); } diff --git a/src/lightmap/lightsurface.h b/src/lightmap/lightsurface.h index 3eb683d..098db64 100644 --- a/src/lightmap/lightsurface.h +++ b/src/lightmap/lightsurface.h @@ -42,7 +42,7 @@ public: void Init(const surfaceLightDef &lightSurfaceDef, surface_t *surface, const bool bWall, const bool bNoCenterPoint); void Subdivide(const float divide); void CreateCenterOrigin(); - bool TraceSurface(FLevel *doomMap, kexTrace &trace, const surface_t *surface, const kexVec3 &origin, float *dist); + float TraceSurface(FLevel *doomMap, kexTrace &trace, const surface_t *surface, const kexVec3 &origin); const float Distance() const { return distance; } const float Intensity() const { return intensity; }