Allow setting light attenuation mode from mapinfo
This commit is contained in:
parent
2a3fe915a4
commit
37a7907221
9 changed files with 111 additions and 6 deletions
|
|
@ -647,6 +647,7 @@ public:
|
|||
matrices.mClipLine.X = -10000000.0f;
|
||||
matrices.mShadowFilter = gl_light_shadow_filter;
|
||||
matrices.mLightBlendMode = 0;
|
||||
matrices.mLightAttenuationMode = 0;
|
||||
matrices.mProjectionMatrix.ortho(0, (float)width, (float)height, 0, -1.0f, 1.0f);
|
||||
matrices.CalcDependencies();
|
||||
return SetViewpoint(matrices);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,14 @@ enum class ELightBlendMode : uint8_t
|
|||
DEFAULT = CLAMP,
|
||||
};
|
||||
|
||||
enum class ELightAttenuationMode : uint8_t
|
||||
{
|
||||
LINEAR = 0,
|
||||
INVERSE_SQUARE = 1,
|
||||
|
||||
DEFAULT = LINEAR,
|
||||
};
|
||||
|
||||
struct HWViewpointUniforms
|
||||
{
|
||||
VSMatrix mProjectionMatrix;
|
||||
|
|
@ -35,6 +43,8 @@ struct HWViewpointUniforms
|
|||
|
||||
int mLightTilesWidth = 0;
|
||||
|
||||
int mLightAttenuationMode = 0;
|
||||
|
||||
void CalcDependencies()
|
||||
{
|
||||
mNormalViewMatrix.computeNormalMatrix(mViewMatrix);
|
||||
|
|
|
|||
|
|
@ -325,6 +325,7 @@ void level_info_t::Reset()
|
|||
skyrotatevector = FVector3(0, 0, 1);
|
||||
skyrotatevector2 = FVector3(0, 0, 1);
|
||||
lightblendmode = ELightBlendMode::DEFAULT;
|
||||
lightattenuationmode = ELightAttenuationMode::DEFAULT;
|
||||
tonemap = ETonemapMode::None;
|
||||
}
|
||||
|
||||
|
|
@ -1596,10 +1597,14 @@ DEFINE_MAP_OPTION(lightblendmode, false)
|
|||
parse.ParseAssign();
|
||||
parse.sc.MustGetString();
|
||||
|
||||
if (parse.sc.Compare("Default") || parse.sc.Compare("Clamp"))
|
||||
if (parse.sc.Compare("Default"))
|
||||
{
|
||||
info->lightblendmode = ELightBlendMode::DEFAULT;
|
||||
}
|
||||
else if (parse.sc.Compare("Clamp"))
|
||||
{
|
||||
info->lightblendmode = ELightBlendMode::CLAMP;
|
||||
}
|
||||
else if (parse.sc.Compare("ColoredClamp"))
|
||||
{
|
||||
info->lightblendmode = ELightBlendMode::CLAMP_COLOR;
|
||||
|
|
@ -1642,6 +1647,29 @@ DEFINE_MAP_OPTION(lightblendmode, false)
|
|||
}
|
||||
}
|
||||
|
||||
DEFINE_MAP_OPTION(lightattenuationmode, false)
|
||||
{
|
||||
parse.ParseAssign();
|
||||
parse.sc.MustGetString();
|
||||
|
||||
if (parse.sc.Compare("Default"))
|
||||
{
|
||||
info->lightattenuationmode = ELightAttenuationMode::DEFAULT;
|
||||
}
|
||||
else if (parse.sc.Compare("Linear"))
|
||||
{
|
||||
info->lightattenuationmode = ELightAttenuationMode::LINEAR;
|
||||
}
|
||||
else if (parse.sc.Compare("InverseSquare"))
|
||||
{
|
||||
info->lightattenuationmode = ELightAttenuationMode::INVERSE_SQUARE;
|
||||
}
|
||||
else
|
||||
{
|
||||
parse.sc.ScriptMessage("Invalid light attenuation mode %s", parse.sc.String);
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_MAP_OPTION(notexturefill, false)
|
||||
{
|
||||
if (parse.CheckAssign())
|
||||
|
|
|
|||
|
|
@ -431,6 +431,7 @@ struct level_info_t
|
|||
FString acsName;
|
||||
bool fs_nocheckposition;
|
||||
ELightBlendMode lightblendmode;
|
||||
ELightAttenuationMode lightattenuationmode;
|
||||
ETonemapMode tonemap;
|
||||
|
||||
CutsceneDef intro, outro;
|
||||
|
|
|
|||
|
|
@ -127,7 +127,8 @@ void HWDrawInfo::StartScene(FRenderViewpoint &parentvp, HWViewpointUniforms *uni
|
|||
}
|
||||
VPUniforms.mClipLine.X = -10000000.0f;
|
||||
VPUniforms.mShadowFilter = static_cast<int>(gl_light_shadow_filter);
|
||||
VPUniforms.mLightBlendMode = (level.info ? (int)level.info->lightblendmode : 0);
|
||||
VPUniforms.mLightBlendMode = (level.info ? static_cast<int>(level.info->lightblendmode) : 0);
|
||||
VPUniforms.mLightAttenuationMode = (level.info ? static_cast<int>(level.info->lightattenuationmode) : 0);
|
||||
}
|
||||
mClipper->SetViewpoint(Viewpoint);
|
||||
vClipper->SetViewpoint(Viewpoint);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ layout(set = 1, binding = 0, std140) uniform ViewpointUBO
|
|||
int uLightBlendMode;
|
||||
|
||||
int uLightTilesWidth; // Levelmesh light tiles
|
||||
|
||||
int uLightAttenuationMode;
|
||||
};
|
||||
|
||||
layout(set = 1, binding = 1, std140) uniform MatricesUBO
|
||||
|
|
|
|||
|
|
@ -1,3 +1,28 @@
|
|||
float linearDistanceAttenuation(vec4 lightpos, float d)
|
||||
{
|
||||
return clamp((lightpos.w - d) / lightpos.w, 0.0, 1.0);
|
||||
}
|
||||
|
||||
float inverseSquareDistanceAttenuation(vec4 lightpos, float d)
|
||||
{
|
||||
float strength = 1500.0;
|
||||
float r = lightpos.w;
|
||||
float a = d / r;
|
||||
float b = clamp(1.0 - a * a * a * a, 0.0, 1.0);
|
||||
return (b * b) / (d * d + 1.0) * strength;
|
||||
}
|
||||
|
||||
float distanceAttenuation(vec4 lightpos, float d)
|
||||
{
|
||||
if ( uLightAttenuationMode == 1 )
|
||||
{
|
||||
return inverseSquareDistanceAttenuation(lightpos, d);
|
||||
}
|
||||
else
|
||||
{
|
||||
return linearDistanceAttenuation(lightpos, d);
|
||||
}
|
||||
}
|
||||
|
||||
vec3 lightContribution(int i, vec3 normal)
|
||||
{
|
||||
|
|
@ -14,7 +39,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 = clamp((lightpos.w - lightdistance) / lightpos.w, 0.0, 1.0);
|
||||
float attenuation = distanceAttenuation(lightpos, lightdistance);
|
||||
|
||||
if (lightspot1.w == 1.0)
|
||||
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
|
||||
|
|
|
|||
|
|
@ -61,6 +61,18 @@ float inverseSquareDistanceAttenuation(vec4 lightpos)
|
|||
return (b * b) / (d * d + 1.0) * strength;
|
||||
}
|
||||
|
||||
float distanceAttenuation(vec4 lightpos)
|
||||
{
|
||||
if ( uLightAttenuationMode == 1 )
|
||||
{
|
||||
return inverseSquareDistanceAttenuation(lightpos);
|
||||
}
|
||||
else
|
||||
{
|
||||
return linearDistanceAttenuation(lightpos);
|
||||
}
|
||||
}
|
||||
|
||||
vec3 ProcessMaterialLight(Material material, vec3 ambientLight)
|
||||
{
|
||||
vec3 worldpos = pixelpos.xyz;
|
||||
|
|
@ -96,7 +108,7 @@ vec3 ProcessMaterialLight(Material material, vec3 ambientLight)
|
|||
vec3 L = normalize(lightpos.xyz - worldpos);
|
||||
vec3 H = normalize(V + L);
|
||||
|
||||
float attenuation = inverseSquareDistanceAttenuation(lightpos);
|
||||
float attenuation = distanceAttenuation(lightpos);
|
||||
if (lightspot1.w == 1.0)
|
||||
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
|
||||
if (lightcolor.a < 0.0)
|
||||
|
|
@ -136,7 +148,7 @@ vec3 ProcessMaterialLight(Material material, vec3 ambientLight)
|
|||
vec3 L = normalize(lightpos.xyz - worldpos);
|
||||
vec3 H = normalize(V + L);
|
||||
|
||||
float attenuation = linearDistanceAttenuation(lightpos);
|
||||
float attenuation = distanceAttenuation(lightpos);
|
||||
if (lightspot1.w == 1.0)
|
||||
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
|
||||
if (lightcolor.a < 0.0)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,28 @@
|
|||
float linearDistanceAttenuation(vec4 lightpos, float d)
|
||||
{
|
||||
return clamp((lightpos.w - d) / lightpos.w, 0.0, 1.0);
|
||||
}
|
||||
|
||||
float inverseSquareDistanceAttenuation(vec4 lightpos, float d)
|
||||
{
|
||||
float strength = 1500.0;
|
||||
float r = lightpos.w;
|
||||
float a = d / r;
|
||||
float b = clamp(1.0 - a * a * a * a, 0.0, 1.0);
|
||||
return (b * b) / (d * d + 1.0) * strength;
|
||||
}
|
||||
|
||||
float distanceAttenuation(vec4 lightpos, float d)
|
||||
{
|
||||
if ( uLightAttenuationMode == 1 )
|
||||
{
|
||||
return inverseSquareDistanceAttenuation(lightpos, d);
|
||||
}
|
||||
else
|
||||
{
|
||||
return linearDistanceAttenuation(lightpos, d);
|
||||
}
|
||||
}
|
||||
|
||||
vec2 lightAttenuation(int i, vec3 normal, vec3 viewdir, float lightcolorA, float glossiness, float specularLevel)
|
||||
{
|
||||
|
|
@ -9,7 +34,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 = clamp((lightpos.w - lightdistance) / lightpos.w, 0.0, 1.0);
|
||||
float attenuation = distanceAttenuation(lightpos, lightdistance);
|
||||
|
||||
if (lightspot1.w == 1.0)
|
||||
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue