mirror of
https://github.com/ZDoom/ZDRay.git
synced 2025-01-24 16:51:08 +00:00
- implement the correct math for area lights
This commit is contained in:
parent
b588b809ea
commit
664be1eca5
3 changed files with 19 additions and 60 deletions
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
if (curDist > *dist)
|
||||
{
|
||||
*dist = curDist;
|
||||
}
|
||||
}
|
||||
|
||||
*dist *= Intensity();
|
||||
return *dist > 0;
|
||||
return total / origins.Length();
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
Loading…
Reference in a new issue