Add LightStrength to UDMF, move SoftShadowRadius from AActor to DynamicLight
This commit is contained in:
parent
159ae02a2a
commit
56787bbc17
15 changed files with 88 additions and 20 deletions
|
|
@ -429,6 +429,9 @@ Note: All <bool> fields default to false unless mentioned otherwise.
|
|||
lm_suncolor = <int>; // ZDRay lightmap sun color. Default is white (0xFFFFFF).
|
||||
|
||||
light_softshadowradius = <float>; // ZDRay lightmap light and raytraced dynamic light soft shadow amount. Higher values produce softer shadows. Default = 5.0
|
||||
|
||||
light_strength = <float>; // Light strenght for Inverse-square falloff lights. Default = 0.0 (auto)
|
||||
|
||||
|
||||
friendlyseeblocks = <int>; // How far (in block units) a friendly monster can see other monsters. Default 10
|
||||
|
||||
|
|
|
|||
|
|
@ -384,6 +384,7 @@ struct FMapThing
|
|||
int friendlyseeblocks;
|
||||
FName arg0str;
|
||||
double SoftShadowRadius;
|
||||
double LightStrength;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -793,7 +793,11 @@ public:
|
|||
break;
|
||||
|
||||
case NAME_light_softshadowradius:
|
||||
th->SoftShadowRadius = (float)CheckFloat(key);
|
||||
th->SoftShadowRadius = CheckFloat(key);
|
||||
break;
|
||||
|
||||
case NAME_light_strength:
|
||||
th->LightStrength = CheckFloat(key);
|
||||
break;
|
||||
|
||||
case NAME_lm_suncolor:
|
||||
|
|
|
|||
|
|
@ -320,6 +320,8 @@ xx(RedSkull)
|
|||
xx(DynamicLight)
|
||||
xx(SpotInnerAngle)
|
||||
xx(SpotOuterAngle)
|
||||
xx(SoftShadowRadius)
|
||||
xx(LightStrength)
|
||||
xx(lightflags)
|
||||
xx(lighttype)
|
||||
xx(InternalDynamicLight)
|
||||
|
|
@ -869,6 +871,7 @@ xx(lm_suncolor)
|
|||
|
||||
// Light keywords
|
||||
xx(light_softshadowradius)
|
||||
xx(light_strength)
|
||||
|
||||
xx(skew_bottom_type)
|
||||
xx(skew_middle_type)
|
||||
|
|
|
|||
|
|
@ -99,6 +99,12 @@ static FDynamicLight *GetLight(FLevelLocals *Level)
|
|||
}
|
||||
|
||||
|
||||
static inline constexpr float calcStrength(float radius)
|
||||
{
|
||||
radius *= 2; // radius in shaders is actualy diameter, so multiply it here to match
|
||||
return std::min(1500.0f, (radius * radius) / 10);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Attaches a dynamic light descriptor to a dynamic light actor.
|
||||
|
|
@ -115,7 +121,14 @@ void AttachLight(AActor *self)
|
|||
light->pPitch = &self->Angles.Pitch;
|
||||
light->pLightFlags = (LightFlags*)&self->IntVar(NAME_lightflags);
|
||||
light->pArgs = self->args;
|
||||
light->pSoftShadowRadius = &self->SoftShadowRadius;
|
||||
light->pSoftShadowRadius = &self->FloatVar(NAME_SoftShadowRadius);
|
||||
light->pStrength = &self->FloatVar(NAME_LightStrength);
|
||||
|
||||
if(*light->pStrength <= 0)
|
||||
{
|
||||
*light->pStrength = -calcStrength(light->m_currentRadius);
|
||||
}
|
||||
|
||||
light->specialf1 = DAngle::fromDeg(double(self->SpawnAngle)).Normalized360().Degrees();
|
||||
light->Sector = self->Sector;
|
||||
light->target = self;
|
||||
|
|
@ -213,7 +226,6 @@ void FDynamicLight::ReleaseLight()
|
|||
FreeList.Push(this);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// [TS]
|
||||
|
|
@ -237,6 +249,11 @@ void FDynamicLight::Activate()
|
|||
m_currentRadius = float(m_cycler.GetVal());
|
||||
}
|
||||
if (m_currentRadius <= 0) m_currentRadius = 1;
|
||||
|
||||
if(pStrength && *pStrength <= 0)
|
||||
{
|
||||
*pStrength = -calcStrength(m_currentRadius);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -254,6 +271,8 @@ void FDynamicLight::Tick()
|
|||
return;
|
||||
}
|
||||
|
||||
int oldradius = m_currentRadius;
|
||||
|
||||
if (owned)
|
||||
{
|
||||
if (!target->state || !target->ShouldRenderLocally())
|
||||
|
|
@ -345,8 +364,9 @@ void FDynamicLight::Tick()
|
|||
|
||||
intensity = Sector? Sector->lightlevel * scale : 0;
|
||||
intensity = clamp<float>(intensity, 0.f, 255.f);
|
||||
|
||||
|
||||
m_currentRadius = intensity;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -355,6 +375,12 @@ void FDynamicLight::Tick()
|
|||
break;
|
||||
}
|
||||
if (m_currentRadius <= 0) m_currentRadius = 1;
|
||||
|
||||
|
||||
if(pStrength && *pStrength <= 0 && oldradius != m_currentRadius)
|
||||
{
|
||||
*pStrength = -calcStrength(m_currentRadius);
|
||||
}
|
||||
UpdateLocation();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -131,6 +131,7 @@ protected:
|
|||
DAngle m_spotOuterAngle = DAngle::fromDeg(25.0);
|
||||
DAngle m_pitch = nullAngle;
|
||||
double SoftShadowRadius = 5.0;
|
||||
double Strength = 0.0;
|
||||
|
||||
friend FSerializer &Serialize(FSerializer &arc, const char *key, FLightDefaults &value, FLightDefaults *def);
|
||||
};
|
||||
|
|
@ -224,6 +225,7 @@ struct FDynamicLight
|
|||
bool IsActive() const { return m_active; }
|
||||
float GetRadius() const { return (IsActive() ? m_currentRadius * 2.f : 0.f); }
|
||||
float GetSoftShadowRadius() const { return (float)(*pSoftShadowRadius); }
|
||||
float GetStrength() const { return std::abs((float)*pStrength); }
|
||||
int GetRed() const { return pArgs[LIGHT_RED]; }
|
||||
int GetGreen() const { return pArgs[LIGHT_GREEN]; }
|
||||
int GetBlue() const { return pArgs[LIGHT_BLUE]; }
|
||||
|
|
@ -272,6 +274,8 @@ public:
|
|||
const LightFlags *pLightFlags;
|
||||
const double* pSoftShadowRadius; // Softshadows. Physical size of the light source
|
||||
|
||||
double* pStrength; // Softshadows. Physical size of the light source
|
||||
|
||||
double specialf1;
|
||||
FDynamicLight *next, *prev;
|
||||
sector_t *Sector;
|
||||
|
|
@ -292,6 +296,8 @@ public:
|
|||
bool swapped;
|
||||
bool explicitpitch;
|
||||
|
||||
double tmpStrength;
|
||||
|
||||
// Locations in the level mesh light list. Ends with index = 0 or all entries used
|
||||
enum { max_levelmesh_entries = 4 };
|
||||
struct
|
||||
|
|
|
|||
|
|
@ -1375,8 +1375,6 @@ public:
|
|||
// (note: this is put into AActor instead of the PlayerPawn because non-players also use the value)
|
||||
double LandingSpeed;
|
||||
|
||||
double SoftShadowRadius = 5.0; // Light source's soft shadow radius
|
||||
|
||||
// ThingIDs
|
||||
void SetTID (int newTID);
|
||||
|
||||
|
|
|
|||
|
|
@ -6181,8 +6181,6 @@ AActor *FLevelLocals::SpawnMapThing (FMapThing *mthing, int position)
|
|||
if (mthing->fillcolor)
|
||||
mobj->fillcolor = (mthing->fillcolor & 0xffffff) | (ColorMatcher.Pick((mthing->fillcolor & 0xff0000) >> 16,
|
||||
(mthing->fillcolor & 0xff00) >> 8, (mthing->fillcolor & 0xff)) << 24);
|
||||
if (mthing->SoftShadowRadius >= 0.0)
|
||||
mobj->SoftShadowRadius = mthing->SoftShadowRadius;
|
||||
|
||||
// allow color strings for lights and reshuffle the args for spot lights
|
||||
if (i->IsDescendantOf(NAME_DynamicLight))
|
||||
|
|
@ -6206,6 +6204,20 @@ AActor *FLevelLocals::SpawnMapThing (FMapThing *mthing, int position)
|
|||
mobj->AngleVar(NAME_SpotInnerAngle) = DAngle::fromDeg(mthing->args[1]);
|
||||
mobj->AngleVar(NAME_SpotOuterAngle) = DAngle::fromDeg(mthing->args[2]);
|
||||
}
|
||||
|
||||
if (mthing->SoftShadowRadius >= 0.0)
|
||||
{
|
||||
mobj->FloatVar(NAME_SoftShadowRadius) = mthing->SoftShadowRadius;
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj->FloatVar(NAME_SoftShadowRadius) = 5.0;
|
||||
}
|
||||
|
||||
if (mthing->LightStrength > 0.0)
|
||||
{
|
||||
mobj->FloatVar(NAME_LightStrength) = mthing->LightStrength;
|
||||
}
|
||||
}
|
||||
|
||||
mobj->CallBeginPlay ();
|
||||
|
|
|
|||
|
|
@ -127,6 +127,17 @@ void FLightDefaults::ApplyProperties(FDynamicLight * light) const
|
|||
light->specialf1 = m_Param;
|
||||
light->pArgs = m_Args;
|
||||
light->pSoftShadowRadius = &SoftShadowRadius;
|
||||
|
||||
if(Strength > 0.0)
|
||||
{
|
||||
light->pStrength = const_cast<double*>(&Strength); // casting const to non-const, but positive strength values will not be modified
|
||||
}
|
||||
else
|
||||
{
|
||||
light->tmpStrength = 0.0;
|
||||
light->pStrength = &light->tmpStrength;
|
||||
}
|
||||
|
||||
light->pLightFlags = &m_lightFlags;
|
||||
if (m_lightFlags & LF_SPOT)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include"hw_cvars.h"
|
||||
#include "v_video.h"
|
||||
#include "hwrenderer/scene/hw_drawstructs.h"
|
||||
#include "g_levellocals.h"
|
||||
|
||||
// If we want to share the array to avoid constant allocations it needs to be thread local unless it'd be littered with expensive synchronization.
|
||||
thread_local FDynLightData lightdata;
|
||||
|
|
@ -140,6 +141,8 @@ void AddLightToList(FDynLightData &dld, int group, FDynamicLight * light, bool f
|
|||
}
|
||||
float softShadowRadius = light->GetSoftShadowRadius();
|
||||
|
||||
float strength = light->GetStrength();
|
||||
|
||||
float *data = &dld.arrays[i][dld.arrays[i].Reserve(16)];
|
||||
data[0] = float(pos.X);
|
||||
data[1] = float(pos.Z);
|
||||
|
|
@ -156,7 +159,7 @@ void AddLightToList(FDynLightData &dld, int group, FDynamicLight * light, bool f
|
|||
data[12] = spotInnerAngle;
|
||||
data[13] = spotOuterAngle;
|
||||
data[14] = softShadowRadius;
|
||||
data[15] = 0.0f; // unused
|
||||
data[15] = strength;
|
||||
}
|
||||
|
||||
void AddSunLightToList(FDynLightData& dld, float x, float y, float z, const FVector3& sundir, const FVector3& suncolor)
|
||||
|
|
@ -177,6 +180,8 @@ void AddSunLightToList(FDynLightData& dld, float x, float y, float z, const FVec
|
|||
float spotDirZ = 0.0f;
|
||||
float shadowIndex = -1025.f; // Note: 1025 disables shadowmap and the attenuate flag is in the sign bit of the float
|
||||
|
||||
float strength = 1500.0f;
|
||||
|
||||
float* data = &dld.arrays[i][dld.arrays[i].Reserve(16)];
|
||||
data[0] = float(x);
|
||||
data[1] = float(z);
|
||||
|
|
@ -193,5 +198,5 @@ void AddSunLightToList(FDynLightData& dld, float x, float y, float z, const FVec
|
|||
data[12] = spotInnerAngle;
|
||||
data[13] = spotOuterAngle;
|
||||
data[14] = 0.0f; // unused
|
||||
data[15] = 0.0f; // unused
|
||||
data[15] = strength;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ vec3 lightContribution(int i, vec3 normal)
|
|||
float dotprod = dot(normal, lightdir);
|
||||
if (dotprod < -0.0001) return vec3(0.0); // light hits from the backside. This can happen with full sector light lists and must be rejected for all cases. Note that this can cause precision issues.
|
||||
|
||||
float attenuation = distanceAttenuation(lightdistance, lightpos.w);
|
||||
float attenuation = distanceAttenuation(lightdistance, lightpos.w, lightspot2.w);
|
||||
|
||||
if (lightspot1.w == 1.0)
|
||||
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ vec3 ProcessMaterialLight(Material material, vec3 ambientLight)
|
|||
vec3 L = normalize(lightpos.xyz - worldpos);
|
||||
vec3 H = normalize(V + L);
|
||||
|
||||
float attenuation = distanceAttenuation(distance(lightpos.xyz, pixelpos.xyz), lightpos.w);
|
||||
float attenuation = distanceAttenuation(distance(lightpos.xyz, pixelpos.xyz), lightpos.w, lightspot2.w);
|
||||
if (lightspot1.w == 1.0)
|
||||
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
|
||||
if (lightcolor.a < 0.0)
|
||||
|
|
@ -119,7 +119,7 @@ vec3 ProcessMaterialLight(Material material, vec3 ambientLight)
|
|||
vec3 L = normalize(lightpos.xyz - worldpos);
|
||||
vec3 H = normalize(V + L);
|
||||
|
||||
float attenuation = distanceAttenuation(distance(lightpos.xyz, pixelpos.xyz), lightpos.w);
|
||||
float attenuation = distanceAttenuation(distance(lightpos.xyz, pixelpos.xyz), lightpos.w, lightspot2.w);
|
||||
if (lightspot1.w == 1.0)
|
||||
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
|
||||
if (lightcolor.a < 0.0)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
|
||||
#ifdef LIGHT_ATTENUATION_INVERSE_SQUARE
|
||||
|
||||
float distanceAttenuation(float dist, float radius)
|
||||
float distanceAttenuation(float dist, float radius, float strength)
|
||||
{
|
||||
float strength = min(1500.0, (radius * radius) / 10);
|
||||
float a = dist / radius;
|
||||
float b = clamp(1.0 - a * a * a * a, 0.0, 1.0);
|
||||
return (b * b) / (dist * dist + 1.0) * strength;
|
||||
|
|
@ -10,9 +10,6 @@ float distanceAttenuation(float dist, float radius)
|
|||
|
||||
#else //elif defined(LIGHT_ATTENUATION_LINEAR)
|
||||
|
||||
float distanceAttenuation(float dist, float radius)
|
||||
{
|
||||
return clamp((radius - dist) / radius, 0.0, 1.0);
|
||||
}
|
||||
#define distanceAttenuation(dist, radius, strength) clamp((radius - dist) / radius, 0.0, 1.0)
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ vec2 lightAttenuation(int i, vec3 normal, vec3 viewdir, float lightcolorA, float
|
|||
if (lightpos.w < lightdistance)
|
||||
return vec2(0.0); // Early out lights touching surface but not this fragment
|
||||
|
||||
float attenuation = distanceAttenuation(lightdistance, lightpos.w);
|
||||
float attenuation = distanceAttenuation(lightdistance, lightpos.w, lightspot2.w);
|
||||
|
||||
if (lightspot1.w == 1.0)
|
||||
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ class DynamicLight : Actor
|
|||
{
|
||||
double SpotInnerAngle;
|
||||
double SpotOuterAngle;
|
||||
double SoftShadowRadius;
|
||||
double LightStrength; // used for Inverse-square falloff lights
|
||||
private int lighttype;
|
||||
private int lightflags;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue