mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-17 01:31:25 +00:00
Switch actors from using light probes to performing trace visibility tests
This commit is contained in:
parent
ff6d412237
commit
4701ce96d8
7 changed files with 95 additions and 52 deletions
|
@ -42,7 +42,8 @@ enum LightFlag
|
|||
LF_DONTLIGHTACTORS = 32,
|
||||
LF_SPOT = 64,
|
||||
LF_DONTLIGHTOTHERS = 128,
|
||||
LF_DONTLIGHTMAP = 256
|
||||
LF_DONTLIGHTMAP = 256,
|
||||
LF_TRACE = 512
|
||||
};
|
||||
|
||||
typedef TFlags<LightFlag> LightFlags;
|
||||
|
@ -76,6 +77,7 @@ public:
|
|||
void SetDontLightActors(bool on) { if (on) m_lightFlags |= LF_DONTLIGHTACTORS; else m_lightFlags &= ~LF_DONTLIGHTACTORS; }
|
||||
void SetDontLightOthers(bool on) { if (on) m_lightFlags |= LF_DONTLIGHTOTHERS; else m_lightFlags &= ~LF_DONTLIGHTOTHERS; }
|
||||
void SetDontLightMap(bool on) { if (on) m_lightFlags |= LF_DONTLIGHTMAP; else m_lightFlags &= ~LF_DONTLIGHTMAP; }
|
||||
void SetTrace(bool on) { if (on) m_lightFlags |= LF_TRACE; else m_lightFlags &= ~LF_TRACE; }
|
||||
void SetNoShadowmap(bool on) { if (on) m_lightFlags |= LF_NOSHADOWMAP; else m_lightFlags &= ~LF_NOSHADOWMAP; }
|
||||
void SetSpot(bool spot) { if (spot) m_lightFlags |= LF_SPOT; else m_lightFlags &= ~LF_SPOT; }
|
||||
void SetSpotInnerAngle(double angle) { m_spotInnerAngle = DAngle::fromDeg(angle); }
|
||||
|
@ -230,6 +232,7 @@ struct FDynamicLight
|
|||
bool IsAdditive() const { return !!((*pLightFlags) & LF_ADDITIVE); }
|
||||
bool IsSpot() const { return !!((*pLightFlags) & LF_SPOT); }
|
||||
bool IsAttenuated() const { return !!((*pLightFlags) & LF_ATTENUATE); }
|
||||
bool Trace() const { return !!((*pLightFlags) & (LF_TRACE)); }
|
||||
bool DontShadowmap() const { return !!((*pLightFlags) & LF_NOSHADOWMAP); }
|
||||
bool DontLightSelf() const { return !!((*pLightFlags) & (LF_DONTLIGHTSELF|LF_DONTLIGHTACTORS)); } // dontlightactors implies dontlightself.
|
||||
bool DontLightActors() const { return !!((*pLightFlags) & LF_DONTLIGHTACTORS); }
|
||||
|
|
|
@ -191,6 +191,7 @@ static const char *LightTags[]=
|
|||
"noshadowmap",
|
||||
"dontlightothers",
|
||||
"dontlightmap",
|
||||
"trace",
|
||||
nullptr
|
||||
};
|
||||
|
||||
|
@ -217,6 +218,7 @@ enum {
|
|||
LIGHTTAG_NOSHADOWMAP,
|
||||
LIGHTTAG_DONTLIGHTOTHERS,
|
||||
LIGHTTAG_DONTLIGHTMAP,
|
||||
LIGHTTAG_TRACE,
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
|
@ -523,6 +525,9 @@ class GLDefsParser
|
|||
case LIGHTTAG_DONTLIGHTMAP:
|
||||
defaults->SetDontLightMap(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_TRACE:
|
||||
defaults->SetTrace(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_SPOT:
|
||||
{
|
||||
float innerAngle = ParseFloat(sc);
|
||||
|
@ -625,6 +630,9 @@ class GLDefsParser
|
|||
case LIGHTTAG_DONTLIGHTMAP:
|
||||
defaults->SetDontLightMap(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_TRACE:
|
||||
defaults->SetTrace(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_SPOT:
|
||||
{
|
||||
float innerAngle = ParseFloat(sc);
|
||||
|
@ -730,6 +738,9 @@ class GLDefsParser
|
|||
case LIGHTTAG_DONTLIGHTMAP:
|
||||
defaults->SetDontLightMap(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_TRACE:
|
||||
defaults->SetTrace(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_SPOT:
|
||||
{
|
||||
float innerAngle = ParseFloat(sc);
|
||||
|
@ -834,6 +845,9 @@ class GLDefsParser
|
|||
case LIGHTTAG_DONTLIGHTMAP:
|
||||
defaults->SetDontLightMap(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_TRACE:
|
||||
defaults->SetTrace(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_SPOT:
|
||||
{
|
||||
float innerAngle = ParseFloat(sc);
|
||||
|
@ -935,6 +949,9 @@ class GLDefsParser
|
|||
case LIGHTTAG_DONTLIGHTMAP:
|
||||
defaults->SetDontLightMap(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_TRACE:
|
||||
defaults->SetTrace(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_SPOT:
|
||||
{
|
||||
float innerAngle = ParseFloat(sc);
|
||||
|
|
|
@ -101,6 +101,16 @@ LightProbe* FindLightProbe(FLevelLocals* level, float x, float y, float z)
|
|||
return foundprobe;
|
||||
}
|
||||
|
||||
static bool TraceLightVisbility(FLightNode* node, const FVector3& L, float dist)
|
||||
{
|
||||
FDynamicLight* light = node->lightsource;
|
||||
if (!light->Trace())
|
||||
return true;
|
||||
|
||||
FTraceResults results;
|
||||
return !Trace(light->Pos, light->Sector, DVector3(-L.X, -L.Y, -L.Z), dist, 0, ML_BLOCKING, nullptr, results);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets a single light value from all dynamic lights affecting the specified location
|
||||
|
@ -115,14 +125,6 @@ void HWDrawInfo::GetDynSpriteLight(AActor *self, float x, float y, float z, FLig
|
|||
|
||||
out[0] = out[1] = out[2] = 0.f;
|
||||
|
||||
LightProbe* probe = FindLightProbe(Level, x, y, z);
|
||||
if (probe)
|
||||
{
|
||||
out[0] = probe->Red;
|
||||
out[1] = probe->Green;
|
||||
out[2] = probe->Blue;
|
||||
}
|
||||
|
||||
// Go through both light lists
|
||||
while (node)
|
||||
{
|
||||
|
@ -156,38 +158,43 @@ void HWDrawInfo::GetDynSpriteLight(AActor *self, float x, float y, float z, FLig
|
|||
{
|
||||
dist = sqrtf(dist); // only calculate the square root if we really need it.
|
||||
|
||||
frac = 1.0f - (dist / radius);
|
||||
|
||||
if (light->IsSpot())
|
||||
{
|
||||
if (light->IsSpot() || light->Trace())
|
||||
L *= -1.0f / dist;
|
||||
DAngle negPitch = -*light->pPitch;
|
||||
DAngle Angle = light->target->Angles.Yaw;
|
||||
double xyLen = negPitch.Cos();
|
||||
double spotDirX = -Angle.Cos() * xyLen;
|
||||
double spotDirY = -Angle.Sin() * xyLen;
|
||||
double spotDirZ = -negPitch.Sin();
|
||||
double cosDir = L.X * spotDirX + L.Y * spotDirY + L.Z * spotDirZ;
|
||||
frac *= (float)smoothstep(light->pSpotOuterAngle->Cos(), light->pSpotInnerAngle->Cos(), cosDir);
|
||||
}
|
||||
|
||||
if (frac > 0 && (!light->shadowmapped || (light->GetRadius() > 0 && screen->mShadowMap.ShadowTest(light->Pos, { x, y, z }))))
|
||||
if (TraceLightVisbility(node, L, dist))
|
||||
{
|
||||
lr = light->GetRed() / 255.0f;
|
||||
lg = light->GetGreen() / 255.0f;
|
||||
lb = light->GetBlue() / 255.0f;
|
||||
if (light->IsSubtractive())
|
||||
frac = 1.0f - (dist / radius);
|
||||
|
||||
if (light->IsSpot())
|
||||
{
|
||||
float bright = (float)FVector3(lr, lg, lb).Length();
|
||||
FVector3 lightColor(lr, lg, lb);
|
||||
lr = (bright - lr) * -1;
|
||||
lg = (bright - lg) * -1;
|
||||
lb = (bright - lb) * -1;
|
||||
DAngle negPitch = -*light->pPitch;
|
||||
DAngle Angle = light->target->Angles.Yaw;
|
||||
double xyLen = negPitch.Cos();
|
||||
double spotDirX = -Angle.Cos() * xyLen;
|
||||
double spotDirY = -Angle.Sin() * xyLen;
|
||||
double spotDirZ = -negPitch.Sin();
|
||||
double cosDir = L.X * spotDirX + L.Y * spotDirY + L.Z * spotDirZ;
|
||||
frac *= (float)smoothstep(light->pSpotOuterAngle->Cos(), light->pSpotInnerAngle->Cos(), cosDir);
|
||||
}
|
||||
|
||||
out[0] += lr * frac;
|
||||
out[1] += lg * frac;
|
||||
out[2] += lb * frac;
|
||||
if (frac > 0 && (!light->shadowmapped || (light->GetRadius() > 0 && screen->mShadowMap.ShadowTest(light->Pos, { x, y, z }))))
|
||||
{
|
||||
lr = light->GetRed() / 255.0f;
|
||||
lg = light->GetGreen() / 255.0f;
|
||||
lb = light->GetBlue() / 255.0f;
|
||||
if (light->IsSubtractive())
|
||||
{
|
||||
float bright = (float)FVector3(lr, lg, lb).Length();
|
||||
FVector3 lightColor(lr, lg, lb);
|
||||
lr = (bright - lr) * -1;
|
||||
lg = (bright - lg) * -1;
|
||||
lb = (bright - lb) * -1;
|
||||
}
|
||||
|
||||
out[0] += lr * frac;
|
||||
out[1] += lg * frac;
|
||||
out[2] += lb * frac;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -249,7 +256,16 @@ void hw_GetDynModelLight(AActor *self, FDynLightData &modellightdata)
|
|||
{
|
||||
if (std::find(addedLights.begin(), addedLights.end(), light) == addedLights.end()) // Check if we already added this light from a different subsector
|
||||
{
|
||||
AddLightToList(modellightdata, group, light, true);
|
||||
FVector3 L(dx, dy, dz);
|
||||
float dist = sqrtf(distSquared);
|
||||
if (light->Trace())
|
||||
L *= 1.0f / dist;
|
||||
|
||||
if (TraceLightVisbility(node, L, dist))
|
||||
{
|
||||
AddLightToList(modellightdata, group, light, true);
|
||||
}
|
||||
|
||||
addedLights.Push(light);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -295,13 +295,6 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (actor && di->Level->LightProbes.Size() > 0)
|
||||
{
|
||||
LightProbe* probe = FindLightProbe(di->Level, actor->X(), actor->Y(), actor->Center());
|
||||
if (probe)
|
||||
state.SetDynLight(probe->Red, probe->Green, probe->Blue);
|
||||
}
|
||||
|
||||
FHWModelRenderer renderer(di, state, dynlightindex);
|
||||
RenderModel(&renderer, x, y, z, modelframe, actor, di->Viewpoint.TicFrac);
|
||||
state.SetVertexBuffer(screen->mVertexData);
|
||||
|
|
|
@ -843,13 +843,6 @@ void HWDrawInfo::PreparePlayerSprites3D(sector_t * viewsector, area_t in_area)
|
|||
{
|
||||
hw_GetDynModelLight(playermo, lightdata);
|
||||
hudsprite.lightindex = screen->mLights->UploadLights(lightdata);
|
||||
LightProbe* probe = FindLightProbe(playermo->Level, playermo->X(), playermo->Y(), playermo->Center());
|
||||
if (probe)
|
||||
{
|
||||
hudsprite.dynrgb[0] = probe->Red;
|
||||
hudsprite.dynrgb[1] = probe->Green;
|
||||
hudsprite.dynrgb[2] = probe->Blue;
|
||||
}
|
||||
}
|
||||
|
||||
// [BB] In the HUD model step we just render the model and break out.
|
||||
|
|
|
@ -136,8 +136,8 @@ DoomEdNums
|
|||
9872 = SpotLightFlickerAttenuated
|
||||
9873 = SectorSpotLightAttenuated
|
||||
9874 = SpotLightFlickerRandomAttenuated
|
||||
9876 = None // ZDRay static point light
|
||||
9881 = None // ZDRay static spotlight
|
||||
9876 = PointLightTraceAttenuated // ZDRay static point light
|
||||
9881 = SpotLightTraceAttenuated // ZDRay static spotlight
|
||||
9890 = None // ZDRayInfo
|
||||
9982 = SecActEyesAboveC
|
||||
9983 = SecActEyesBelowC
|
||||
|
|
|
@ -17,6 +17,7 @@ class DynamicLight : Actor
|
|||
flagdef spot: lightflags, 6;
|
||||
flagdef dontlightothers: lightflags, 7;
|
||||
flagdef dontlightmap: lightflags, 8;
|
||||
flagdef trace: lightflags, 9;
|
||||
|
||||
enum EArgs
|
||||
{
|
||||
|
@ -40,6 +41,7 @@ class DynamicLight : Actor
|
|||
LF_SPOT = 64,
|
||||
LF_DONTLIGHTOTHERS = 128,
|
||||
LF_DONTLIGHTMAP = 256,
|
||||
LF_TRACE = 512
|
||||
};
|
||||
|
||||
enum ELightType
|
||||
|
@ -440,6 +442,25 @@ class SpotLightFlickerRandomAttenuated : SpotLightFlickerRandom
|
|||
}
|
||||
}
|
||||
|
||||
class PointLightTraceAttenuated : PointLightAttenuated
|
||||
{
|
||||
Default
|
||||
{
|
||||
+DYNAMICLIGHT.TRACE
|
||||
+DYNAMICLIGHT.DONTLIGHTMAP
|
||||
}
|
||||
}
|
||||
|
||||
class SpotLightTraceAttenuated : SpotLightAttenuated
|
||||
{
|
||||
Default
|
||||
{
|
||||
+DYNAMICLIGHT.TRACE
|
||||
+DYNAMICLIGHT.DONTLIGHTMAP
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class VavoomLight : DynamicLight
|
||||
{
|
||||
Default
|
||||
|
|
Loading…
Reference in a new issue