mirror of
https://github.com/ZDoom/ZDRay.git
synced 2025-02-03 13:11:04 +00:00
- Fix the light surface math so the correct angles are being used
This commit is contained in:
parent
e046e7a508
commit
c3494a045d
1 changed files with 22 additions and 47 deletions
|
@ -218,89 +218,64 @@ void kexLightSurface::Subdivide(const float divide)
|
|||
}
|
||||
}
|
||||
|
||||
float kexLightSurface::TraceSurface(FLevel *map, const surface_t *surf, const kexVec3 &origin)
|
||||
float kexLightSurface::TraceSurface(FLevel *map, const surface_t *fragmentSurface, const kexVec3 &fragmentPos)
|
||||
{
|
||||
// light surface will always be fullbright
|
||||
if (surf == surface)
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
if (fragmentSurface == surface)
|
||||
return 1.0f; // light surface will always be fullbright
|
||||
|
||||
kexVec3 lnormal = surface->plane.Normal();
|
||||
|
||||
kexVec3 normal;
|
||||
if (surf)
|
||||
{
|
||||
normal = surf->plane.Normal();
|
||||
|
||||
if (normal.Dot(lnormal) > 0)
|
||||
{
|
||||
// not facing the light surface
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
normal = kexVec3::vecUp;
|
||||
}
|
||||
kexVec3 lightSurfaceNormal = surface->plane.Normal();
|
||||
kexVec3 fragmentNormal = fragmentSurface->plane.Normal();
|
||||
|
||||
float gzdoomRadiusScale = 2.0f; // 2.0 because gzdoom's dynlights do this and we want them to match
|
||||
|
||||
float total = 0.0f;
|
||||
int count = 0;
|
||||
float closestDistance = distance * gzdoomRadiusScale;
|
||||
float maxDistanceSqr = closestDistance * closestDistance;
|
||||
for (size_t i = 0; i < origins.size(); ++i)
|
||||
{
|
||||
kexVec3 center = origins[i];
|
||||
|
||||
if ((surface->type == ST_CEILING && origin.z > center.z) || (surface->type == ST_FLOOR && origin.z < center.z))
|
||||
{
|
||||
// origin is not going to seen or traced by the light surface
|
||||
// so don't even bother. this also fixes some bizzare light
|
||||
// bleeding issues
|
||||
continue;
|
||||
}
|
||||
|
||||
float dsqr = origin.DistanceSq(center);
|
||||
kexVec3 lightPos = origins[i];
|
||||
kexVec3 lightDir = (lightPos - fragmentPos);
|
||||
|
||||
float dsqr = kexVec3::Dot(lightDir, lightDir);
|
||||
if (dsqr > maxDistanceSqr)
|
||||
continue; // out of range
|
||||
|
||||
float d = std::sqrt(dsqr);
|
||||
float id = 1.0f / d;
|
||||
|
||||
kexVec3 dir = (origin - center) * id;
|
||||
float attenuation = dir.Dot(lnormal);
|
||||
count++;
|
||||
|
||||
float attenuation = kexVec3::Dot(lightDir, fragmentNormal);
|
||||
if (attenuation <= 0.0f)
|
||||
continue; // not even facing the light surface
|
||||
|
||||
float d = std::sqrt(dsqr);
|
||||
attenuation /= d;
|
||||
|
||||
if (surface->type != ST_CEILING && surface->type != ST_FLOOR)
|
||||
{
|
||||
if (origin.z >= surface->verts[0].z && origin.z <= surface->verts[2].z)
|
||||
if (fragmentPos.z >= surface->verts[0].z && fragmentPos.z <= surface->verts[2].z)
|
||||
{
|
||||
// since walls are always vertically straight, we can cheat a little by adjusting
|
||||
// the sampling point height. this also allows us to do accurate light emitting
|
||||
// while just using one sample point
|
||||
center.z = origin.z;
|
||||
lightPos.z = fragmentPos.z;
|
||||
}
|
||||
}
|
||||
|
||||
// trace the origin to the center of the light surface. nudge by the normals in
|
||||
// case the start/end points are directly on or inside the surface
|
||||
LevelTraceHit trace = map->Trace(center + lnormal, origin + normal);
|
||||
LevelTraceHit trace = map->Trace(lightPos + lightSurfaceNormal, fragmentPos + fragmentNormal);
|
||||
|
||||
if (trace.fraction < 1.0f)
|
||||
{
|
||||
// something is obstructing it
|
||||
continue;
|
||||
}
|
||||
continue; // something is obstructing it
|
||||
|
||||
if (d < closestDistance)
|
||||
closestDistance = d;
|
||||
total += attenuation;
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
return 0.0f;
|
||||
|
||||
float attenuation = 1.0f - closestDistance / (distance * gzdoomRadiusScale);
|
||||
return attenuation * total / origins.size();
|
||||
return attenuation * total / count;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue