mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-03-10 03:02:21 +00:00
This commit is contained in:
parent
c630fd9b25
commit
b6f0bc0da3
27 changed files with 226 additions and 5 deletions
|
@ -1629,3 +1629,8 @@ FSerializer& Serialize(FSerializer& arc, const char* key, FRenderStyle& style, F
|
|||
}
|
||||
|
||||
SaveRecords saveRecords;
|
||||
|
||||
FSerializer &Serialize(FSerializer &arc, const char *key, FVector4 &value, FVector4 *defval)
|
||||
{
|
||||
return arc.Array<float>(key, &value[0], defval ? &(*defval)[0] : nullptr, 4, true);
|
||||
}
|
||||
|
|
|
@ -234,6 +234,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FName &value, FName *d
|
|||
FSerializer &Serialize(FSerializer &arc, const char *key, FSoundID &sid, FSoundID *def);
|
||||
FSerializer &Serialize(FSerializer &arc, const char *key, FString &sid, FString *def);
|
||||
FSerializer &Serialize(FSerializer &arc, const char *key, NumericValue &sid, NumericValue *def);
|
||||
FSerializer &Serialize(FSerializer &arc, const char *key, FVector4 &value, FVector4 *defval);
|
||||
|
||||
template <typename T/*, typename = std::enable_if_t<std::is_base_of_v<DObject, T>>*/>
|
||||
FSerializer &Serialize(FSerializer &arc, const char *key, T *&value, T **)
|
||||
|
|
|
@ -17,7 +17,7 @@ public:
|
|||
|
||||
virtual VSMatrix GetViewToWorldMatrix() = 0;
|
||||
|
||||
virtual void BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored) = 0;
|
||||
virtual void BeginDrawHUDModel(FRenderStyle style, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored) = 0;
|
||||
virtual void EndDrawHUDModel(FRenderStyle style) = 0;
|
||||
|
||||
virtual void SetInterpolation(double interpolation) = 0;
|
||||
|
|
|
@ -140,6 +140,7 @@ bool FGLRenderState::ApplyShader()
|
|||
activeShader->muTextureModulateColor.Set(mStreamData.uTextureModulateColor);
|
||||
activeShader->muTextureBlendColor.Set(mStreamData.uTextureBlendColor);
|
||||
activeShader->muDetailParms.Set(&mStreamData.uDetailParms.X);
|
||||
activeShader->muDirectionalLight.Set(&mStreamData.uDirectionalLight.X);
|
||||
#ifdef NPOT_EMULATION
|
||||
activeShader->muNpotEmulation.Set(&mStreamData.uNpotEmulation.X);
|
||||
#endif
|
||||
|
|
|
@ -284,6 +284,9 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
uniform mat4 NormalModelMatrix;
|
||||
uniform mat4 TextureMatrix;
|
||||
|
||||
// directional light
|
||||
uniform vec4 uDirectionalLight;
|
||||
|
||||
// light buffers
|
||||
#ifdef SHADER_STORAGE_LIGHTS
|
||||
layout(std430, binding = 1) buffer LightBufferSSO
|
||||
|
@ -600,6 +603,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
muTextureModulateColor.Init(hShader, "uTextureModulateColor");
|
||||
muTextureBlendColor.Init(hShader, "uTextureBlendColor");
|
||||
muTimer.Init(hShader, "timer");
|
||||
muDirectionalLight.Init(hShader, "uDirectionalLight");
|
||||
|
||||
lights_index = glGetUniformLocation(hShader, "lights");
|
||||
modelmatrix_index = glGetUniformLocation(hShader, "ModelMatrix");
|
||||
|
|
|
@ -266,6 +266,7 @@ class FShader
|
|||
FBufferedUniform2f muNpotEmulation;
|
||||
#endif
|
||||
|
||||
FUniform4f muDirectionalLight;
|
||||
int lights_index;
|
||||
int modelmatrix_index;
|
||||
int normalmodelmatrix_index;
|
||||
|
|
|
@ -202,6 +202,8 @@ struct StreamData
|
|||
FVector4 uDetailParms;
|
||||
FVector4 uNpotEmulation;
|
||||
FVector4 padding1, padding2, padding3;
|
||||
|
||||
FVector4 uDirectionalLight;
|
||||
};
|
||||
|
||||
class FRenderState
|
||||
|
@ -305,6 +307,7 @@ public:
|
|||
#ifdef NPOT_EMULATION
|
||||
mStreamData.uNpotEmulation = { 0,0,0,0 };
|
||||
#endif
|
||||
mStreamData.uDirectionalLight = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
mModelMatrix.loadIdentity();
|
||||
mTextureMatrix.loadIdentity();
|
||||
ClearClipSplit();
|
||||
|
@ -488,6 +491,11 @@ public:
|
|||
mStreamData.uDynLightColor.Z = b;
|
||||
}
|
||||
|
||||
void SetDirectionalLight(FVector4 dl)
|
||||
{
|
||||
mStreamData.uDirectionalLight = { dl.X, dl.Y, dl.Z, dl.W };
|
||||
}
|
||||
|
||||
void SetScreenFade(float f)
|
||||
{
|
||||
// This component is otherwise unused.
|
||||
|
|
|
@ -208,6 +208,8 @@ static const char *shaderBindings = R"(
|
|||
vec4 uDetailParms;
|
||||
vec4 uNpotEmulation;
|
||||
vec4 padding1, padding2, padding3;
|
||||
|
||||
vec4 uDirectionalLight;
|
||||
};
|
||||
|
||||
layout(set = 0, binding = 3, std140) uniform StreamUBO {
|
||||
|
@ -299,6 +301,7 @@ static const char *shaderBindings = R"(
|
|||
#define uSplitBottomPlane data[uDataIndex].uSplitBottomPlane
|
||||
#define uDetailParms data[uDataIndex].uDetailParms
|
||||
#define uNpotEmulation data[uDataIndex].uNpotEmulation
|
||||
#define uDirectionalLight data[uDataIndex].uDirectionalLight
|
||||
|
||||
#define SUPPORTS_SHADOWMAPS
|
||||
#define VULKAN_COORDINATE_SYSTEM
|
||||
|
|
|
@ -1757,6 +1757,9 @@ void FLevelLocals::Init()
|
|||
|
||||
pixelstretch = info->pixelstretch;
|
||||
|
||||
DirectionalLightMode = info->DirectionalLightMode;
|
||||
DirectionalLight = info->DirectionalLight;
|
||||
|
||||
compatflags.Callback();
|
||||
compatflags2.Callback();
|
||||
|
||||
|
|
|
@ -685,6 +685,8 @@ public:
|
|||
bool lightadditivesurfaces;
|
||||
bool notexturefill;
|
||||
int ImpactDecalCount;
|
||||
int8_t DirectionalLightMode;
|
||||
FVector4 DirectionalLight;
|
||||
|
||||
FDynamicLight *lights;
|
||||
|
||||
|
|
|
@ -290,6 +290,8 @@ void level_info_t::Reset()
|
|||
outsidefogdensity = 0;
|
||||
skyfog = 0;
|
||||
pixelstretch = 1.2f;
|
||||
DirectionalLightMode = 0;
|
||||
DirectionalLight = FVector4(0, 0, 0, 0);
|
||||
|
||||
specialactions.Clear();
|
||||
DefaultEnvironment = 0;
|
||||
|
@ -1436,6 +1438,29 @@ DEFINE_MAP_OPTION(pixelratio, false)
|
|||
info->pixelstretch = (float)parse.sc.Float;
|
||||
}
|
||||
|
||||
DEFINE_MAP_OPTION(DirectionalLightMode, false)
|
||||
{
|
||||
parse.ParseAssign();
|
||||
parse.sc.MustGetNumber();
|
||||
info->DirectionalLightMode = (int8_t)clamp(parse.sc.Number, 0, 2);
|
||||
}
|
||||
|
||||
DEFINE_MAP_OPTION(DirectionalLight, true)
|
||||
{
|
||||
parse.ParseAssign();
|
||||
parse.sc.MustGetFloat();
|
||||
info->DirectionalLight.X = (float)parse.sc.Float;
|
||||
if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(",");
|
||||
parse.sc.MustGetFloat();
|
||||
info->DirectionalLight.Y = (float)parse.sc.Float;
|
||||
if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(",");
|
||||
parse.sc.MustGetFloat();
|
||||
info->DirectionalLight.Z = (float)parse.sc.Float;
|
||||
info->DirectionalLight.MakeUnit();
|
||||
if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(",");
|
||||
parse.sc.MustGetFloat();
|
||||
info->DirectionalLight.W = (float)parse.sc.Float;
|
||||
}
|
||||
|
||||
DEFINE_MAP_OPTION(brightfog, false)
|
||||
{
|
||||
|
|
|
@ -364,6 +364,8 @@ struct level_info_t
|
|||
int outsidefogdensity;
|
||||
int skyfog;
|
||||
float pixelstretch;
|
||||
int8_t DirectionalLightMode;
|
||||
FVector4 DirectionalLight;
|
||||
|
||||
// Redirection: If any player is carrying the specified item, then
|
||||
// you go to the RedirectMap instead of this one.
|
||||
|
|
|
@ -996,7 +996,8 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload)
|
|||
("scrolls", Scrolls)
|
||||
("automap", automap)
|
||||
("interpolator", interpolator)
|
||||
("frozenstate", frozenstate);
|
||||
("frozenstate", frozenstate)
|
||||
("directionallight", DirectionalLight);
|
||||
|
||||
|
||||
// Hub transitions must keep the current total time
|
||||
|
|
|
@ -221,7 +221,7 @@ void RenderHUDModel(FModelRenderer *renderer, DPSprite *psp, float ofsX, float o
|
|||
|
||||
float orientation = smf->xscale * smf->yscale * smf->zscale;
|
||||
|
||||
renderer->BeginDrawHUDModel(playermo->RenderStyle, objectToWorldMatrix, orientation < 0);
|
||||
renderer->BeginDrawHUDModel(playermo->RenderStyle, smf, objectToWorldMatrix, orientation < 0);
|
||||
uint32_t trans = psp->GetTranslation() != 0 ? psp->GetTranslation() : 0;
|
||||
if ((psp->Flags & PSPF_PLAYERTRANSLATED)) trans = psp->Owner->mo->Translation;
|
||||
RenderFrameModels(renderer, playermo->Level, smf, psp->GetState(), psp->GetTics(), psp->Caller->GetClass(), trans);
|
||||
|
@ -783,6 +783,10 @@ static void ParseModelDefLump(int Lump)
|
|||
smf.rotationCenterY = 0.;
|
||||
smf.rotationCenterZ = 0.;
|
||||
}
|
||||
else if (sc.Compare("nodirectionallight"))
|
||||
{
|
||||
smf.flags |= MDL_NODIRECTIONALLIGHT;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptMessage("Unrecognized string \"%s\"", sc.String);
|
||||
|
|
|
@ -57,6 +57,7 @@ enum
|
|||
MDL_USEROTATIONCENTER = 512,
|
||||
MDL_NOPERPIXELLIGHTING = 1024, // forces a model to not use per-pixel lighting. useful for voxel-converted-to-model objects.
|
||||
MDL_SCALEWEAPONFOV = 2048, // scale weapon view model with higher user FOVs
|
||||
MDL_NODIRECTIONALLIGHT = 4096, // disables directional light shading
|
||||
};
|
||||
|
||||
FSpriteModelFrame * FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped);
|
||||
|
|
|
@ -67,17 +67,23 @@ void FHWModelRenderer::BeginDrawModel(FRenderStyle style, FSpriteModelFrame *smf
|
|||
|
||||
state.mModelMatrix = objectToWorldMatrix;
|
||||
state.EnableModelMatrix(true);
|
||||
|
||||
if (level.info->DirectionalLightMode >= 1 && !(smf->flags & MDL_NODIRECTIONALLIGHT))
|
||||
{
|
||||
state.SetDirectionalLight(di->GetDirectionalLight());
|
||||
}
|
||||
}
|
||||
|
||||
void FHWModelRenderer::EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf)
|
||||
{
|
||||
state.SetDirectionalLight(FVector4(0.f, 0.f, 0.f, 0.f));
|
||||
state.EnableModelMatrix(false);
|
||||
state.SetDepthFunc(DF_Less);
|
||||
if (!(style == DefaultRenderStyle()) && !(smf->flags & MDL_DONTCULLBACKFACES))
|
||||
state.SetCulling(Cull_None);
|
||||
}
|
||||
|
||||
void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored)
|
||||
void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored)
|
||||
{
|
||||
state.SetDepthFunc(DF_LEqual);
|
||||
|
||||
|
@ -91,10 +97,16 @@ void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &obj
|
|||
|
||||
state.mModelMatrix = objectToWorldMatrix;
|
||||
state.EnableModelMatrix(true);
|
||||
|
||||
if (level.info->DirectionalLightMode >= 1 && !(smf->flags & MDL_NODIRECTIONALLIGHT))
|
||||
{
|
||||
state.SetDirectionalLight(di->GetDirectionalLight());
|
||||
}
|
||||
}
|
||||
|
||||
void FHWModelRenderer::EndDrawHUDModel(FRenderStyle style)
|
||||
{
|
||||
state.SetDirectionalLight(FVector4(0.f, 0.f, 0.f, 0.f));
|
||||
state.EnableModelMatrix(false);
|
||||
|
||||
state.SetDepthFunc(DF_Less);
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
void EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf) override;
|
||||
IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) override;
|
||||
VSMatrix GetViewToWorldMatrix() override;
|
||||
void BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored) override;
|
||||
void BeginDrawHUDModel(FRenderStyle style, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored) override;
|
||||
void EndDrawHUDModel(FRenderStyle style) override;
|
||||
void SetInterpolation(double interpolation) override;
|
||||
void SetMaterial(FGameTexture *skin, bool clampNoFilter, int translation) override;
|
||||
|
|
|
@ -78,6 +78,13 @@ void HWDecal::DrawDecal(HWDrawInfo *di, FRenderState &state)
|
|||
state.SetRenderStyle(decal->RenderStyle);
|
||||
state.SetMaterial(texture, UF_Sprite, 0, CLAMP_XY, decal->Translation, -1);
|
||||
|
||||
// only enable directional lighting if the DL mode is enabled for the entire map.
|
||||
// IMO it doesn't make sense to enable DL on decals if the DL mode is set to "models only".
|
||||
if (level.info->DirectionalLightMode == 2)
|
||||
{
|
||||
state.SetDirectionalLight(di->GetDirectionalLight());
|
||||
}
|
||||
|
||||
|
||||
// If srcalpha is one it looks better with a higher alpha threshold
|
||||
if (decal->RenderStyle.SrcAlpha == STYLEALPHA_One) state.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold);
|
||||
|
@ -131,6 +138,7 @@ void HWDecal::DrawDecal(HWDrawInfo *di, FRenderState &state)
|
|||
state.SetObjectColor(0xffffffff);
|
||||
state.SetFog(fc, -1);
|
||||
state.SetDynLight(0, 0, 0);
|
||||
state.SetDirectionalLight(FVector4(0.f, 0.f, 0.f, 0.f));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -212,6 +212,7 @@ private:
|
|||
PalEntry CalcLightColor(int light, PalEntry pe, int blendfactor);
|
||||
float GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity, int blendfactor);
|
||||
bool CheckFog(sector_t *frontsector, sector_t *backsector);
|
||||
FVector4 GetDirectionalLight(void);
|
||||
WeaponLighting GetWeaponLighting(sector_t *viewsector, const DVector3 &pos, int cm, area_t in_area, const DVector3 &playerpos);
|
||||
public:
|
||||
|
||||
|
|
|
@ -334,6 +334,10 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
|
|||
{
|
||||
if (sector->special != GLSector_Skybox)
|
||||
{
|
||||
if (level.info->DirectionalLightMode == 2)
|
||||
{
|
||||
state.SetDirectionalLight(di->GetDirectionalLight());
|
||||
}
|
||||
state.SetMaterial(texture, UF_Texture, 0, CLAMP_NONE, 0, -1);
|
||||
SetPlaneTextureRotation(state, &plane, texture);
|
||||
DrawSubsectors(di, state);
|
||||
|
@ -362,6 +366,10 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
|
|||
{
|
||||
if (!texture->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
|
||||
else state.AlphaFunc(Alpha_GEqual, 0.f);
|
||||
if (level.info->DirectionalLightMode == 2)
|
||||
{
|
||||
state.SetDirectionalLight(di->GetDirectionalLight());
|
||||
}
|
||||
state.SetMaterial(texture, UF_Texture, 0, CLAMP_NONE, 0, -1);
|
||||
SetPlaneTextureRotation(state, &plane, texture);
|
||||
DrawSubsectors(di, state);
|
||||
|
@ -369,6 +377,7 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
|
|||
}
|
||||
state.SetRenderStyle(DefaultRenderStyle());
|
||||
}
|
||||
state.SetDirectionalLight(FVector4(0.f, 0.f, 0.f, 0.f));
|
||||
state.SetObjectColor(0xffffffff);
|
||||
state.SetAddColor(0);
|
||||
state.ApplyTextureManipulation(nullptr);
|
||||
|
|
|
@ -280,3 +280,7 @@ bool HWDrawInfo::CheckFog(sector_t *frontsector, sector_t *backsector)
|
|||
backsector->GetTexture(sector_t::ceiling)!=skyflatnum));
|
||||
}
|
||||
|
||||
FVector4 HWDrawInfo::GetDirectionalLight(void)
|
||||
{
|
||||
return Level->DirectionalLight;
|
||||
}
|
||||
|
|
|
@ -231,6 +231,10 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
|
|||
state.SetObjectColor2((color1 != color2) ? color2 : PalEntry(0));
|
||||
state.SetAddColor(side->GetAdditiveColor(tierndx, frontsector));
|
||||
state.ApplyTextureManipulation(&tier.TextureFx);
|
||||
if (level.info->DirectionalLightMode == 2)
|
||||
{
|
||||
state.SetDirectionalLight(di->GetDirectionalLight());
|
||||
}
|
||||
|
||||
if (color1 != color2)
|
||||
{
|
||||
|
@ -304,6 +308,7 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
|
|||
state.EnableGlow(false);
|
||||
state.EnableGradient(false);
|
||||
state.ApplyTextureManipulation(nullptr);
|
||||
state.SetDirectionalLight(FVector4(0.f, 0.f, 0.f, 0.f));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -2481,6 +2481,55 @@ DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, setFrozen, setFrozen)
|
|||
//
|
||||
//=====================================================================================
|
||||
|
||||
static void SetDirectionalLight(FLevelLocals *self, double x, double y, double z, double strength)
|
||||
{
|
||||
// normalize the vector
|
||||
DVector3 dlv = DVector3(x, y, z);
|
||||
dlv.MakeUnit();
|
||||
self->DirectionalLight = FVector4(static_cast<float>(dlv.X), static_cast<float>(dlv.Y), static_cast<float>(dlv.Z), static_cast<float>(strength));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, SetDirectionalLight, SetDirectionalLight)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
PARAM_FLOAT(z);
|
||||
PARAM_FLOAT(strength);
|
||||
SetDirectionalLight(self, x, y, z, strength);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void GetDirectionalLightVector(FLevelLocals *self, DVector3 *result)
|
||||
{
|
||||
*result = DVector3(self->DirectionalLight.X, self->DirectionalLight.Y, self->DirectionalLight.Z);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, GetDirectionalLightVector, GetDirectionalLightVector)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
DVector3 result;
|
||||
GetDirectionalLightVector(self, &result);
|
||||
ACTION_RETURN_VEC3(result);
|
||||
}
|
||||
|
||||
static double GetDirectionalLightStrength(FLevelLocals *self)
|
||||
{
|
||||
return self->DirectionalLight.W;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, GetDirectionalLightStrength, GetDirectionalLightStrength)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
ACTION_RETURN_FLOAT(GetDirectionalLightStrength(self));
|
||||
}
|
||||
|
||||
//=====================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=====================================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(_AltHUD, GetLatency, Net_GetLatency)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
|
@ -2721,6 +2770,7 @@ DEFINE_FIELD(FLevelLocals, fogdensity)
|
|||
DEFINE_FIELD(FLevelLocals, outsidefogdensity)
|
||||
DEFINE_FIELD(FLevelLocals, skyfog)
|
||||
DEFINE_FIELD(FLevelLocals, pixelstretch)
|
||||
DEFINE_FIELD(FLevelLocals, DirectionalLightMode)
|
||||
DEFINE_FIELD(FLevelLocals, MusicVolume)
|
||||
DEFINE_FIELD(FLevelLocals, deathsequence)
|
||||
DEFINE_FIELD_BIT(FLevelLocals, frozenstate, frozen, 1) // still needed for backwards compatibility.
|
||||
|
|
|
@ -35,11 +35,24 @@ vec3 lightContribution(int i, vec3 normal)
|
|||
}
|
||||
}
|
||||
|
||||
float lightDirectionalAttenuation(vec3 normal)
|
||||
{
|
||||
vec3 lightDirectionalDir = uDirectionalLight.xyz;
|
||||
return clamp(dot(lightDirectionalDir, normal), 0.0, 1.0);
|
||||
}
|
||||
|
||||
vec3 ProcessMaterialLight(Material material, vec3 color)
|
||||
{
|
||||
vec4 dynlight = uDynLightColor;
|
||||
vec3 normal = material.Normal;
|
||||
|
||||
if (uDirectionalLight.w != 0 && normal != vec3(0.0))
|
||||
{
|
||||
float lightDirectionalStrength = uDirectionalLight.w;
|
||||
dynlight.rgb += color * lightDirectionalAttenuation(normal) * lightDirectionalStrength;
|
||||
color *= 1.0 - lightDirectionalStrength;
|
||||
}
|
||||
|
||||
if (uLightIndex >= 0)
|
||||
{
|
||||
ivec4 lightRange = ivec4(lights[uLightIndex]) + ivec4(uLightIndex + 1);
|
||||
|
|
|
@ -80,6 +80,36 @@ vec3 ProcessMaterialLight(Material material, vec3 ambientLight)
|
|||
|
||||
vec3 Lo = uDynLightColor.rgb;
|
||||
|
||||
if (uDirectionalLight.w != 0 && N != vec3(0.0))
|
||||
{
|
||||
float lightDirectionalStrength = uDirectionalLight.w;
|
||||
|
||||
vec3 lightDirectionalDir = uDirectionalLight.xyz;
|
||||
float attenuation = clamp(dot(N, lightDirectionalDir), 0.0, 1.0);
|
||||
if (attenuation > 0.0)
|
||||
{
|
||||
vec3 H = normalize(V + lightDirectionalDir);
|
||||
|
||||
vec3 radiance = ambientLight.rgb * attenuation * lightDirectionalStrength;
|
||||
|
||||
// cook-torrance brdf
|
||||
float NDF = DistributionGGX(N, H, roughness);
|
||||
float G = GeometrySmith(N, V, lightDirectionalDir, roughness);
|
||||
vec3 F = fresnelSchlick(clamp(dot(H, V), 0.0, 1.0), F0);
|
||||
|
||||
vec3 kS = F;
|
||||
vec3 kD = (vec3(1.0) - kS) * (1.0 - metallic);
|
||||
|
||||
vec3 nominator = NDF * G * F;
|
||||
float denominator = 4.0 * clamp(dot(N, V), 0.0, 1.0) * clamp(dot(N, lightDirectionalDir), 0.0, 1.0);
|
||||
vec3 specular = nominator / max(denominator, 0.001);
|
||||
|
||||
Lo += (kD * albedo / PI + specular) * radiance;
|
||||
}
|
||||
|
||||
ambientLight *= 1.0 - lightDirectionalStrength;
|
||||
}
|
||||
|
||||
if (uLightIndex >= 0)
|
||||
{
|
||||
ivec4 lightRange = ivec4(lights[uLightIndex]) + ivec4(uLightIndex + 1);
|
||||
|
|
|
@ -34,6 +34,20 @@ vec2 lightAttenuation(int i, vec3 normal, vec3 viewdir, float lightcolorA)
|
|||
return vec2(attenuation, attenuation * specularLevel * pow(specAngle, phExp));
|
||||
}
|
||||
|
||||
vec2 lightDirectionalAttenuation(vec3 normal, vec3 viewdir)
|
||||
{
|
||||
vec3 lightDirectionalDir = uDirectionalLight.xyz;
|
||||
float attenuation = clamp(dot(lightDirectionalDir, normal), 0.0, 1.0);
|
||||
|
||||
float glossiness = uSpecularMaterial.x;
|
||||
float specularLevel = uSpecularMaterial.y;
|
||||
|
||||
vec3 halfdir = normalize(viewdir + lightDirectionalDir);
|
||||
float specAngle = clamp(dot(halfdir, normal), 0.0f, 1.0f);
|
||||
float phExp = glossiness * 4.0f;
|
||||
return vec2(attenuation, attenuation * specularLevel * pow(specAngle, phExp));
|
||||
}
|
||||
|
||||
vec3 ProcessMaterialLight(Material material, vec3 color)
|
||||
{
|
||||
vec4 dynlight = uDynLightColor;
|
||||
|
@ -42,6 +56,15 @@ vec3 ProcessMaterialLight(Material material, vec3 color)
|
|||
vec3 normal = material.Normal;
|
||||
vec3 viewdir = normalize(uCameraPos.xyz - pixelpos.xyz);
|
||||
|
||||
if (uDirectionalLight.w != 0 && normal != vec3(0.0))
|
||||
{
|
||||
float lightDirectionalStrength = uDirectionalLight.w;
|
||||
vec2 lightLevelAttenuation = lightDirectionalAttenuation(normal, viewdir) * lightDirectionalStrength;
|
||||
dynlight.rgb += color * lightLevelAttenuation.x;
|
||||
specular.rgb += color * lightLevelAttenuation.y;
|
||||
color *= 1.0 - lightDirectionalStrength;
|
||||
}
|
||||
|
||||
if (uLightIndex >= 0)
|
||||
{
|
||||
ivec4 lightRange = ivec4(lights[uLightIndex]) + ivec4(uLightIndex + 1);
|
||||
|
|
|
@ -442,12 +442,17 @@ struct LevelLocals native
|
|||
native readonly int outsidefogdensity;
|
||||
native readonly int skyfog;
|
||||
native readonly float pixelstretch;
|
||||
native readonly int8 DirectionalLightMode;
|
||||
native readonly float MusicVolume;
|
||||
native name deathsequence;
|
||||
native readonly int compatflags;
|
||||
native readonly int compatflags2;
|
||||
native readonly LevelInfo info;
|
||||
|
||||
native void SetDirectionalLight(double x, double y, double z, double strength);
|
||||
native Vector3 GetDirectionalLightVector(void);
|
||||
native double GetDirectionalLightStrength(void);
|
||||
|
||||
native String GetUDMFString(int type, int index, Name key);
|
||||
native int GetUDMFInt(int type, int index, Name key);
|
||||
native double GetUDMFFloat(int type, int index, Name key);
|
||||
|
|
Loading…
Reference in a new issue