mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-14 08:30:49 +00:00
- Added spot light support to gl_SetDynSpriteLight
This commit is contained in:
parent
f398286162
commit
bae3620540
2 changed files with 26 additions and 6 deletions
|
@ -141,10 +141,10 @@ void gl_AddLightToList(int group, ADynamicLight * light, FDynLightData &ldata)
|
||||||
spotOuterAngle = light->SpotOuterAngle.Cos();
|
spotOuterAngle = light->SpotOuterAngle.Cos();
|
||||||
|
|
||||||
DAngle negPitch = -light->Angles.Pitch;
|
DAngle negPitch = -light->Angles.Pitch;
|
||||||
float xyLen = negPitch.Cos();
|
double xzLen = negPitch.Cos();
|
||||||
spotDirX = -light->Angles.Yaw.Cos() * xyLen;
|
spotDirX = -light->Angles.Yaw.Cos() * xzLen;
|
||||||
spotDirY = -light->Angles.Yaw.Sin() * xyLen;
|
spotDirY = -negPitch.Sin();
|
||||||
spotDirZ = -negPitch.Sin();
|
spotDirZ = -light->Angles.Yaw.Sin() * xzLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
float *data = &ldata.arrays[i][ldata.arrays[i].Reserve(16)];
|
float *data = &ldata.arrays[i][ldata.arrays[i].Reserve(16)];
|
||||||
|
|
|
@ -49,6 +49,13 @@
|
||||||
FDynLightData modellightdata;
|
FDynLightData modellightdata;
|
||||||
int modellightindex = -1;
|
int modellightindex = -1;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
T smoothstep(const T edge0, const T edge1, const T x)
|
||||||
|
{
|
||||||
|
auto t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
|
||||||
|
return t * t * (3.0 - 2.0 * t);
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Sets a single light value from all dynamic lights affecting the specified location
|
// Sets a single light value from all dynamic lights affecting the specified location
|
||||||
|
@ -70,6 +77,7 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *
|
||||||
if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->lightflags&LF_DONTLIGHTSELF) || light->target != self) && !(light->lightflags&LF_DONTLIGHTACTORS))
|
if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->lightflags&LF_DONTLIGHTSELF) || light->target != self) && !(light->lightflags&LF_DONTLIGHTACTORS))
|
||||||
{
|
{
|
||||||
float dist;
|
float dist;
|
||||||
|
FVector3 L;
|
||||||
|
|
||||||
// This is a performance critical section of code where we cannot afford to let the compiler decide whether to inline the function or not.
|
// This is a performance critical section of code where we cannot afford to let the compiler decide whether to inline the function or not.
|
||||||
// This will do the calculations explicitly rather than calling one of AActor's utility functions.
|
// This will do the calculations explicitly rather than calling one of AActor's utility functions.
|
||||||
|
@ -80,14 +88,15 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *
|
||||||
if (fromgroup == togroup || fromgroup == 0 || togroup == 0) goto direct;
|
if (fromgroup == togroup || fromgroup == 0 || togroup == 0) goto direct;
|
||||||
|
|
||||||
DVector2 offset = Displacements.getOffset(fromgroup, togroup);
|
DVector2 offset = Displacements.getOffset(fromgroup, togroup);
|
||||||
dist = FVector3(x - light->X() - offset.X, y - light->Y() - offset.Y, z - light->Z()).LengthSquared();
|
L = FVector3(x - light->X() - offset.X, y - light->Y() - offset.Y, z - light->Z());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
direct:
|
direct:
|
||||||
dist = FVector3(x - light->X(), y - light->Y(), z - light->Z()).LengthSquared();
|
L = FVector3(x - light->X(), y - light->Y(), z - light->Z());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dist = L.LengthSquared();
|
||||||
radius = light->GetRadius();
|
radius = light->GetRadius();
|
||||||
|
|
||||||
if (dist < radius * radius)
|
if (dist < radius * radius)
|
||||||
|
@ -96,6 +105,17 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *
|
||||||
|
|
||||||
frac = 1.0f - (dist / radius);
|
frac = 1.0f - (dist / radius);
|
||||||
|
|
||||||
|
if (light->IsSpot())
|
||||||
|
{
|
||||||
|
DAngle negPitch = -light->Angles.Pitch;
|
||||||
|
double xzLen = negPitch.Cos();
|
||||||
|
double spotDirX = -light->Angles.Yaw.Cos() * xzLen;
|
||||||
|
double spotDirY = -negPitch.Sin();
|
||||||
|
double spotDirZ = -light->Angles.Yaw.Sin() * xzLen;
|
||||||
|
double cosDir = L.X * spotDirX + L.Y * spotDirY + L.Z * spotDirZ;
|
||||||
|
frac *= (float)smoothstep(light->SpotOuterAngle.Cos(), light->SpotInnerAngle.Cos(), cosDir);
|
||||||
|
}
|
||||||
|
|
||||||
if (frac > 0 && GLRenderer->mShadowMap.ShadowTest(light, { x, y, z }))
|
if (frac > 0 && GLRenderer->mShadowMap.ShadowTest(light, { x, y, z }))
|
||||||
{
|
{
|
||||||
lr = light->GetRed() / 255.0f;
|
lr = light->GetRed() / 255.0f;
|
||||||
|
|
Loading…
Reference in a new issue