From 8e7897233efd5f62b84c63d1e39046759612d529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Tue, 6 Dec 2022 22:51:45 -0300 Subject: [PATCH] Add Alternate Light Blending Options --- src/common/rendering/gl/gl_shader.cpp | 2 ++ .../hwrenderer/data/hw_viewpointbuffer.cpp | 2 ++ .../hwrenderer/data/hw_viewpointuniforms.h | 2 ++ .../rendering/vulkan/shaders/vk_shader.cpp | 2 ++ src/doomtype.h | 9 +++++++ src/gamedata/g_mapinfo.cpp | 25 ++++++++++++++++++- src/gamedata/g_mapinfo.h | 1 + .../hwrenderer/scene/hw_drawinfo.cpp | 2 ++ wadsrc/static/shaders/glsl/material_normal.fp | 16 +++++++++++- .../static/shaders/glsl/material_specular.fp | 20 +++++++++++++-- 10 files changed, 77 insertions(+), 4 deletions(-) diff --git a/src/common/rendering/gl/gl_shader.cpp b/src/common/rendering/gl/gl_shader.cpp index 7a8e3baae4f..2e4951f1aba 100644 --- a/src/common/rendering/gl/gl_shader.cpp +++ b/src/common/rendering/gl/gl_shader.cpp @@ -235,6 +235,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * float uClipHeight; float uClipHeightDirection; int uShadowmapFilter; + + int uLightBlendMode; }; uniform int uTextureMode; diff --git a/src/common/rendering/hwrenderer/data/hw_viewpointbuffer.cpp b/src/common/rendering/hwrenderer/data/hw_viewpointbuffer.cpp index f60cda5e102..3a9d23d9a8f 100644 --- a/src/common/rendering/hwrenderer/data/hw_viewpointbuffer.cpp +++ b/src/common/rendering/hwrenderer/data/hw_viewpointbuffer.cpp @@ -30,6 +30,7 @@ #include "hw_renderstate.h" #include "hw_viewpointbuffer.h" #include "hw_cvars.h" +#include "g_levellocals.h" static const int INITIAL_BUFFER_SIZE = 100; // 100 viewpoints per frame should nearly always be enough @@ -91,6 +92,7 @@ void HWViewpointBuffer::Set2D(FRenderState &di, int width, int height, int pll) matrices.mPalLightLevels = pll; matrices.mClipLine.X = -10000000.0f; matrices.mShadowmapFilter = gl_shadowmap_filter; + matrices.mLightBlendMode = (level.info ? (int)level.info->lightblendmode : 0); matrices.mProjectionMatrix.ortho(0, (float)width, (float)height, 0, -1.0f, 1.0f); matrices.CalcDependencies(); diff --git a/src/common/rendering/hwrenderer/data/hw_viewpointuniforms.h b/src/common/rendering/hwrenderer/data/hw_viewpointuniforms.h index 3d28f5c4afb..031bace0a52 100644 --- a/src/common/rendering/hwrenderer/data/hw_viewpointuniforms.h +++ b/src/common/rendering/hwrenderer/data/hw_viewpointuniforms.h @@ -19,6 +19,8 @@ struct HWViewpointUniforms float mClipHeightDirection = 0.f; int mShadowmapFilter = 1; + int mLightBlendMode = 0; + void CalcDependencies() { mNormalViewMatrix.computeNormalMatrix(mViewMatrix); diff --git a/src/common/rendering/vulkan/shaders/vk_shader.cpp b/src/common/rendering/vulkan/shaders/vk_shader.cpp index 753229e4118..25b585531ad 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.cpp +++ b/src/common/rendering/vulkan/shaders/vk_shader.cpp @@ -175,6 +175,8 @@ static const char *shaderBindings = R"( float uClipHeight; float uClipHeightDirection; int uShadowmapFilter; + + int uLightBlendMode; }; layout(set = 1, binding = 1, std140) uniform MatricesUBO { diff --git a/src/doomtype.h b/src/doomtype.h index 2a3fecbd0f7..edfb8df084a 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -53,4 +53,13 @@ enum class ELightMode : int8_t DoomSoftware = 16 }; +enum class ELightBlendMode : uint8_t +{ + CLAMP = 0, + CLAMP_COLOR = 1, + NOCLAMP = 2, + + DEFAULT = CLAMP, +}; + #endif diff --git a/src/gamedata/g_mapinfo.cpp b/src/gamedata/g_mapinfo.cpp index 068ad8ae2ee..37308170ce3 100644 --- a/src/gamedata/g_mapinfo.cpp +++ b/src/gamedata/g_mapinfo.cpp @@ -302,7 +302,7 @@ void level_info_t::Reset() lightadditivesurfaces = -1; skyrotatevector = FVector3(0, 0, 1); skyrotatevector2 = FVector3(0, 0, 1); - + lightblendmode = ELightBlendMode::DEFAULT; } @@ -1496,6 +1496,29 @@ DEFINE_MAP_OPTION(lightmode, false) } } +DEFINE_MAP_OPTION(lightblendmode, false) +{ + parse.ParseAssign(); + parse.sc.MustGetString(); + + if(strcmp(parse.sc.String,"DEFAULT") == 0 || strcmp(parse.sc.String,"CLAMP") == 0) + { + info->lightblendmode = ELightBlendMode::DEFAULT; + } + else if(strcmp(parse.sc.String,"COLOR_CORRECT_CLAMP") == 0) + { + info->lightblendmode = ELightBlendMode::CLAMP_COLOR; + } + else if(strcmp(parse.sc.String,"UNCLAMPED") == 0) + { + info->lightblendmode = ELightBlendMode::NOCLAMP; + } + else + { + parse.sc.ScriptMessage("Invalid light blend mode %s", parse.sc.String); + } +} + DEFINE_MAP_OPTION(notexturefill, false) { if (parse.CheckAssign()) diff --git a/src/gamedata/g_mapinfo.h b/src/gamedata/g_mapinfo.h index 9d6f0f25fa7..f052b48eaa8 100644 --- a/src/gamedata/g_mapinfo.h +++ b/src/gamedata/g_mapinfo.h @@ -409,6 +409,7 @@ struct level_info_t FString EDName; FString acsName; bool fs_nocheckposition; + ELightBlendMode lightblendmode; CutsceneDef intro, outro; diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp index 359bc7b7a99..613132ebe4d 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp @@ -48,6 +48,7 @@ #include "a_corona.h" #include "texturemanager.h" #include "actorinlines.h" +#include "g_levellocals.h" EXTERN_CVAR(Float, r_visibility) CVAR(Bool, gl_bandedswlight, false, CVAR_ARCHIVE) @@ -164,6 +165,7 @@ void HWDrawInfo::StartScene(FRenderViewpoint &parentvp, HWViewpointUniforms *uni } VPUniforms.mClipLine.X = -10000000.0f; VPUniforms.mShadowmapFilter = gl_shadowmap_filter; + VPUniforms.mLightBlendMode = (level.info ? (int)level.info->lightblendmode : 0); } mClipper->SetViewpoint(Viewpoint); diff --git a/wadsrc/static/shaders/glsl/material_normal.fp b/wadsrc/static/shaders/glsl/material_normal.fp index add12881295..01d422645b1 100644 --- a/wadsrc/static/shaders/glsl/material_normal.fp +++ b/wadsrc/static/shaders/glsl/material_normal.fp @@ -59,7 +59,21 @@ vec3 ProcessMaterialLight(Material material, vec3 color) } } - vec3 frag = material.Base.rgb * clamp(color + desaturate(dynlight).rgb, 0.0, 1.4); + vec3 frag; + + if ( uLightBlendMode == 1 ) + { // COLOR_CORRECT_CLAMPING + vec3 lightcolor = color + desaturate(dynlight).rgb; + frag = material.Base.rgb * ((lightcolor / max(max(max(lightcolor.r, lightcolor.g), lightcolor.b), 1.4) * 1.4)); + } + else if ( uLightBlendMode == 2 ) + { // UNCLAMPED + frag = material.Base.rgb * (color + desaturate(dynlight).rgb); + } + else + { + frag = material.Base.rgb * clamp(color + desaturate(dynlight).rgb, 0.0, 1.4); + } if (uLightIndex >= 0) { diff --git a/wadsrc/static/shaders/glsl/material_specular.fp b/wadsrc/static/shaders/glsl/material_specular.fp index 60a39ab1e4a..de49f505a37 100644 --- a/wadsrc/static/shaders/glsl/material_specular.fp +++ b/wadsrc/static/shaders/glsl/material_specular.fp @@ -66,9 +66,25 @@ vec3 ProcessMaterialLight(Material material, vec3 color) } } } + + if ( uLightBlendMode == 1 ) + { // COLOR_CORRECT_CLAMPING + dynlight.rgb = color + desaturate(dynlight).rgb; + specular.rgb = desaturate(specular).rgb; - dynlight.rgb = clamp(color + desaturate(dynlight).rgb, 0.0, 1.4); - specular.rgb = clamp(desaturate(specular).rgb, 0.0, 1.4); + dynlight.rgb = ((dynlight.rgb / max(max(max(dynlight.r, dynlight.g), dynlight.b), 1.4) * 1.4)); + specular.rgb = ((specular.rgb / max(max(max(specular.r, specular.g), specular.b), 1.4) * 1.4)); + } + else if ( uLightBlendMode == 2 ) + { // UNCLAMPED + dynlight.rgb = color + desaturate(dynlight).rgb; + specular.rgb = desaturate(specular).rgb; + } + else + { + dynlight.rgb = clamp(color + desaturate(dynlight).rgb, 0.0, 1.4); + specular.rgb = clamp(desaturate(specular).rgb, 0.0, 1.4); + } vec3 frag = material.Base.rgb * dynlight.rgb + material.Specular * specular.rgb;