mirror of
https://github.com/ZDoom/ZDRay.git
synced 2025-02-03 13:11:04 +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];
|
kexLightSurface *surfaceLight = map->lightSurfaces[i];
|
||||||
|
|
||||||
float attenuation;
|
float attenuation = surfaceLight->TraceSurface(map, trace, surface, origin);
|
||||||
if (surfaceLight->TraceSurface(map, trace, surface, origin, &attenuation))
|
if (attenuation > 0.0f)
|
||||||
{
|
{
|
||||||
color += surfaceLight->GetRGB() * attenuation;
|
color += surfaceLight->GetRGB() * surfaceLight->Intensity() * attenuation;
|
||||||
|
|
||||||
tracedTexels++;
|
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
|
// light surface will always be fullbright
|
||||||
if (surf == surface)
|
if (surf == surface)
|
||||||
{
|
{
|
||||||
*dist = Intensity();
|
return 1.0f;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lnormal = surface->plane.Normal();
|
kexVec3 lnormal = surface->plane.Normal();
|
||||||
|
|
||||||
|
kexVec3 normal;
|
||||||
if (surf)
|
if (surf)
|
||||||
{
|
{
|
||||||
normal = surf->plane.Normal();
|
normal = surf->plane.Normal();
|
||||||
|
@ -267,7 +261,7 @@ bool kexLightSurface::TraceSurface(FLevel *doomMap, kexTrace &trace, const surfa
|
||||||
if (normal.Dot(lnormal) > 0)
|
if (normal.Dot(lnormal) > 0)
|
||||||
{
|
{
|
||||||
// not facing the light surface
|
// not facing the light surface
|
||||||
return false;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -275,8 +269,7 @@ bool kexLightSurface::TraceSurface(FLevel *doomMap, kexTrace &trace, const surfa
|
||||||
normal = kexVec3::vecUp;
|
normal = kexVec3::vecUp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we need to pick the closest sample point on the light surface. what really sucks is
|
float total = 0.0f;
|
||||||
// that we have to trace each one... which could really blow up the compile time
|
|
||||||
for (unsigned int i = 0; i < origins.Length(); ++i)
|
for (unsigned int i = 0; i < origins.Length(); ++i)
|
||||||
{
|
{
|
||||||
kexVec3 center = origins[i];
|
kexVec3 center = origins[i];
|
||||||
|
@ -289,25 +282,11 @@ bool kexLightSurface::TraceSurface(FLevel *doomMap, kexTrace &trace, const surfa
|
||||||
continue;
|
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 (attenuation <= 0.0f)
|
||||||
{
|
continue; // not even facing the light surface
|
||||||
if(normal.Dot(dir) >= 0)
|
|
||||||
{
|
|
||||||
// not even facing the light surface
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
angle = dir.Dot(lnormal);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (bWall)
|
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
|
// case the start/end points are directly on or inside the surface
|
||||||
trace.Trace(center + lnormal, origin + normal);
|
trace.Trace(center + lnormal, origin + normal);
|
||||||
|
|
||||||
if (trace.fraction != 1)
|
if (trace.fraction < 1.0f)
|
||||||
{
|
{
|
||||||
// something is obstructing it
|
// something is obstructing it
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
float d = origin.Distance(center);
|
float d = origin.Distance(center);
|
||||||
|
attenuation *= 1.0f - d / (distance * 2.0f); // 2.0 because gzdoom's dynlights do this and we want them to match
|
||||||
curDist = 1.0f - d / (distance * 2.0f); // 2.0 because gzdoom's dynlights do this and we want them to match
|
if (attenuation > 0.0f)
|
||||||
if (curDist < 0.0f) curDist = 0.0f;
|
total += attenuation;
|
||||||
|
|
||||||
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)
|
return total / origins.Length();
|
||||||
{
|
|
||||||
*dist = curDist;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*dist *= Intensity();
|
|
||||||
return *dist > 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ public:
|
||||||
void Init(const surfaceLightDef &lightSurfaceDef, surface_t *surface, const bool bWall, const bool bNoCenterPoint);
|
void Init(const surfaceLightDef &lightSurfaceDef, surface_t *surface, const bool bWall, const bool bNoCenterPoint);
|
||||||
void Subdivide(const float divide);
|
void Subdivide(const float divide);
|
||||||
void CreateCenterOrigin();
|
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 Distance() const { return distance; }
|
||||||
const float Intensity() const { return intensity; }
|
const float Intensity() const { return intensity; }
|
||||||
|
|
Loading…
Reference in a new issue