diff --git a/src/gl/data/gl_viewpointbuffer.cpp b/src/gl/data/gl_viewpointbuffer.cpp index eb4d8c92e..611db9e40 100644 --- a/src/gl/data/gl_viewpointbuffer.cpp +++ b/src/gl/data/gl_viewpointbuffer.cpp @@ -144,7 +144,6 @@ void GLViewpointBuffer::Set2D(int width, int height) HWViewpointUniforms matrices; matrices.SetDefaults(); matrices.mProjectionMatrix.ortho(0, width, height, 0, -1.0f, 1.0f); - matrices.mFogEnabled = 3; matrices.CalcDependencies(); Map(); memcpy(mBufferPointer, &matrices, sizeof(matrices)); diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index a5de63896..e585296f6 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -119,7 +119,7 @@ bool FRenderState::ApplyShader() static uint64_t firstFrame = 0; // if firstFrame is not yet initialized, initialize it to current time // if we're going to overflow a float (after ~4.6 hours, or 24 bits), re-init to regain precision - if ((firstFrame == 0) || (screen->FrameTime - firstFrame >= 1 << 24) || level.ShaderStartTime >= firstFrame) + if ((firstFrame == 0) || (screen->FrameTime - firstFrame >= 1<<24) || level.ShaderStartTime >= firstFrame) firstFrame = screen->FrameTime; static const float nulvec[] = { 0.f, 0.f, 0.f, 0.f }; @@ -133,15 +133,31 @@ bool FRenderState::ApplyShader() activeShader->Bind(); } + int fogset = 0; + + if (mFogEnabled) + { + if (mFogEnabled == 2) + { + fogset = -3; // 2D rendering with 'foggy' overlay. + } + else if ((mFogColor & 0xffffff) == 0) + { + fogset = gl_fogmode; + } + else + { + fogset = -gl_fogmode; + } + } + glVertexAttrib4fv(VATTR_COLOR, mColor.vec); glVertexAttrib4fv(VATTR_NORMAL, mNormal.vec); activeShader->muDesaturation.Set(mDesaturation / 255.f); + activeShader->muFogEnabled.Set(fogset); activeShader->muTextureMode.Set(mTextureMode == TM_MODULATE && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode); - float fds = mLightParms[2]; - if (!mFogEnabled) mLightParms[2] = 0; activeShader->muLightParms.Set(mLightParms); - mLightParms[2] = fds; activeShader->muFogColor.Set(mFogColor); activeShader->muObjectColor.Set(mObjectColor); activeShader->muObjectColor2.Set(mObjectColor2); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 3044d4bd6..1a83521f1 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -375,7 +375,6 @@ void FDrawInfo::DrawEndScene2D(sector_t * viewsector) HWViewpointUniforms vp = VPUniforms; vp.mViewMatrix.loadIdentity(); vp.mProjectionMatrix = vrmode->GetHUDSpriteProjection(); - vp.mFogEnabled = 0; GLRenderer->mViewpoints->SetViewpoint(&vp); glDisable(GL_DEPTH_TEST); glDisable(GL_MULTISAMPLE); diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 19d30ed47..564365341 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -68,8 +68,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * int uViewHeight; // Software fuzz scaling float uClipHeight; float uClipHeightDirection; - int uFogEnabled; - + int uShadowmapFilter; }; )"; @@ -100,6 +99,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * i_data += "#define uFogDensity uLightAttr.b\n"; i_data += "#define uLightFactor uLightAttr.g\n"; i_data += "#define uLightDist uLightAttr.r\n"; + i_data += "uniform int uFogEnabled;\n"; // dynamic lights i_data += "uniform int uLightIndex;\n"; @@ -331,6 +331,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * muDesaturation.Init(hShader, "uDesaturationFactor"); + muFogEnabled.Init(hShader, "uFogEnabled"); muTextureMode.Init(hShader, "uTextureMode"); muLightParms.Init(hShader, "uLightAttr"); muClipSplit.Init(hShader, "uClipSplit"); diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index 2d1d28f76..46ba3c793 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -242,6 +242,7 @@ class FShader FName mName; FBufferedUniform1f muDesaturation; + FBufferedUniform1i muFogEnabled; FBufferedUniform1i muTextureMode; FBufferedUniform4f muLightParms; FBufferedUniform2f muClipSplit; diff --git a/src/hwrenderer/scene/hw_drawinfo.cpp b/src/hwrenderer/scene/hw_drawinfo.cpp index bf04aef6c..c72f510ae 100644 --- a/src/hwrenderer/scene/hw_drawinfo.cpp +++ b/src/hwrenderer/scene/hw_drawinfo.cpp @@ -280,6 +280,6 @@ void HWViewpointUniforms::SetDefaults() mGlobVis = (float)R_GetGlobVis(r_viewwindow, r_visibility) / 32.f; mPalLightLevels = static_cast(gl_bandedswlight) | (static_cast(gl_fogmode) << 8); mClipLine.X = -10000000.0f; - mFogEnabled = gl_fogmode; + mShadowmapFilter = gl_shadowmap_filter; } diff --git a/src/hwrenderer/scene/hw_viewpointuniforms.h b/src/hwrenderer/scene/hw_viewpointuniforms.h index 675ee71eb..1bd57faa0 100644 --- a/src/hwrenderer/scene/hw_viewpointuniforms.h +++ b/src/hwrenderer/scene/hw_viewpointuniforms.h @@ -16,7 +16,7 @@ struct HWViewpointUniforms int mViewHeight = 0; float mClipHeight = 0.f; float mClipHeightDirection = 0.f; - int mFogEnabled = 0; + int mShadowmapFilter = 1; void CalcDependencies() { diff --git a/src/hwrenderer/utility/hw_cvars.cpp b/src/hwrenderer/utility/hw_cvars.cpp index c849e62d5..f0a0f8c83 100644 --- a/src/hwrenderer/utility/hw_cvars.cpp +++ b/src/hwrenderer/utility/hw_cvars.cpp @@ -132,3 +132,8 @@ CUSTOM_CVAR(Int, gl_fuzztype, 0, CVAR_ARCHIVE) { if (self < 0 || self > 8) self = 0; } + +CUSTOM_CVAR(Int, gl_shadowmap_filter, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (self < 0 || self > 8) self = 1; +} diff --git a/src/hwrenderer/utility/hw_cvars.h b/src/hwrenderer/utility/hw_cvars.h index 440265930..8e4ebbca8 100644 --- a/src/hwrenderer/utility/hw_cvars.h +++ b/src/hwrenderer/utility/hw_cvars.h @@ -69,3 +69,5 @@ EXTERN_CVAR(Bool, gl_billboard_faces_camera) EXTERN_CVAR(Bool, gl_billboard_particles) EXTERN_CVAR(Int, gl_enhanced_nv_stealth) EXTERN_CVAR(Int, gl_fuzztype) + +EXTERN_CVAR(Int, gl_shadowmap_filter) \ No newline at end of file diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 5b74c775e..38a1962e8 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -2792,6 +2792,7 @@ GLLIGHTMNU_LIGHTSPRITES = "Lights affect sprites"; GLLIGHTMNU_LIGHTPARTICLES = "Lights affect particles"; GLLIGHTMNU_LIGHTSHADOWMAP = "Light shadowmaps"; GLLIGHTMNU_LIGHTSHADOWMAPQUALITY = "Shadowmap quality"; +GLLIGHTMNU_LIGHTSHADOWMAPFILTER = "Shadowmap filter"; // OpenGL Preferences GLPREFMNU_TITLE = "OPENGL PREFERENCES"; diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index a51bbdd61..0bd45a7d7 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -2256,6 +2256,13 @@ OptionValue ShadowMapQuality 1024, "1024" } +OptionValue ShadowMapFilter +{ + 0, "$OPTVAL_LINEAR" + 1, "PCF" +} + + OptionMenu "GLTextureGLOptions" protected { Title "$GLTEXMNU_TITLE" @@ -2293,6 +2300,7 @@ OptionMenu "GLLightOptions" protected Option "$GLLIGHTMNU_LIGHTPARTICLES", gl_light_particles, "YesNo" Option "$GLLIGHTMNU_LIGHTSHADOWMAP", gl_light_shadowmap, "YesNo" Option "$GLLIGHTMNU_LIGHTSHADOWMAPQUALITY", gl_shadowmap_quality, "ShadowMapQuality" + Option "$GLLIGHTMNU_LIGHTSHADOWMAPFILTER", gl_shadowmap_filter, "ShadowMapFilter" } OptionMenu "OpenGLOptions" protected diff --git a/wadsrc/static/shaders/glsl/fogboundary.fp b/wadsrc/static/shaders/glsl/fogboundary.fp index 81880f984..9dcdb4850 100644 --- a/wadsrc/static/shaders/glsl/fogboundary.fp +++ b/wadsrc/static/shaders/glsl/fogboundary.fp @@ -15,7 +15,7 @@ void main() // // calculate fog factor // - if (uFogEnabled == 1) + if (uFogEnabled == -1) { fogdist = pixelpos.w; } diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 5848058f3..c78bb0e02 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -215,12 +215,6 @@ float sampleShadowmapLinear(vec2 dir, float v) // //=========================================================================== -#define PCF_FILTER_STEP_COUNT 3 -#define PCF_COUNT (PCF_FILTER_STEP_COUNT * 2 + 1) - -// #define USE_LINEAR_SHADOW_FILTER -#define USE_PCF_SHADOW_FILTER 1 - float shadowmapAttenuation(vec4 lightpos, float shadowIndex) { if (shadowIndex >= 1024.0) @@ -235,23 +229,29 @@ float shadowmapAttenuation(vec4 lightpos, float shadowIndex) vec2 dir = ray / length; -#if defined(USE_LINEAR_SHADOW_FILTER) - ray -= dir * 6.0; // Shadow acne margin - return sampleShadowmapLinear(ray, v); -#elif defined(USE_PCF_SHADOW_FILTER) - ray -= dir * 2.0; // Shadow acne margin - dir = dir * min(length / 50.0, 1.0); // avoid sampling behind light - - vec2 normal = vec2(-dir.y, dir.x); - vec2 bias = dir * 10.0; - - float sum = 0.0; - for (float x = -PCF_FILTER_STEP_COUNT; x <= PCF_FILTER_STEP_COUNT; x++) + if (uShadowmapFilter <= 0) { - sum += sampleShadowmap(ray + normal * x - bias * abs(x), v); + ray -= dir * 2.0; // Shadow acne margin + return sampleShadowmapLinear(ray, v); } - return sum / PCF_COUNT; -#else // nearest shadow filter + else + { + ray -= dir * 2.0; // Shadow acne margin + dir = dir * min(length / 50.0, 1.0); // avoid sampling behind light + + vec2 normal = vec2(-dir.y, dir.x); + vec2 bias = dir * 10.0; + + float sum = 0.0; + float step_count = ((uShadowmapFilter - 1) / 2.); + + for (float x = -step_count; x <= step_count; x++) + { + sum += sampleShadowmap(ray + normal * x /*- bias * abs(x)*/, v); + } + return sum / uShadowmapFilter; + } +#if 0 // nearest shadow filter (not used) ray -= dir * 6.0; // Shadow acne margin return sampleShadowmap(ray, v); #endif @@ -358,7 +358,7 @@ vec4 getLightColor(Material material, float fogdist, float fogfactor) float newlightlevel = 1.0 - R_DoomLightingEquation(uLightLevel); color.rgb *= newlightlevel; } - else if (uFogColor.rgb == vec3(0.0)) + else if (uFogEnabled > 0) { // brightening around the player for light mode 2 if (fogdist < uLightDist) @@ -421,7 +421,7 @@ vec3 AmbientOcclusionColor() // // calculate fog factor // - if (uFogEnabled == 1) + if (uFogEnabled == -1) { fogdist = pixelpos.w; } @@ -449,17 +449,17 @@ void main() if (frag.a <= uAlphaThreshold) discard; #endif - if (uFogEnabled != 3) // check for special 2D 'fog' mode. + if (uFogEnabled != -3) // check for special 2D 'fog' mode. { float fogdist = 0.0; - float fogfactor = 1.0; + float fogfactor = 0.0; // // calculate fog factor // - if (uFogEnabled != 0 && uFogDensity != 0) + if (uFogEnabled != 0) { - if (uFogEnabled == 1) + if (uFogEnabled == 1 || uFogEnabled == -1) { fogdist = pixelpos.w; } @@ -476,7 +476,7 @@ void main() // // colored fog // - if (uFogColor.rgb != vec3(0.0)) + if (uFogEnabled < 0) { frag = applyFog(frag, fogfactor); } @@ -494,7 +494,7 @@ void main() vec4 cm = (uObjectColor + gray * (uObjectColor2 - uObjectColor)) * 2; frag = vec4(clamp(cm.rgb, 0.0, 1.0), frag.a); } - frag = frag * ProcessLight(material, vColor); + frag = frag * ProcessLight(material, vColor); frag.rgb = frag.rgb + uFogColor.rgb; } FragColor = frag; diff --git a/wadsrc_lights/static/filter/doom.doom1/gldefs.txt b/wadsrc_lights/static/filter/doom.doom1/gldefs.txt index 83c30369d..61536f97f 100644 --- a/wadsrc_lights/static/filter/doom.doom1/gldefs.txt +++ b/wadsrc_lights/static/filter/doom.doom1/gldefs.txt @@ -384,7 +384,7 @@ object TechLamp // Tall red torch flickerlight2 BIGREDTORCH { - color 1.0 0.5 0.2 + color 0.7 0.35 0.14 size 90 secondarySize 99 interval 0.1 @@ -400,7 +400,7 @@ object RedTorch // Tall green torch flickerlight2 BIGGREENTORCH { - color 0.3 1.0 0.3 + color 0.2 0.7 0.2 size 90 secondarySize 99 interval 0.1 @@ -416,7 +416,7 @@ object GreenTorch // Tall blue torch flickerlight2 BIGBLUETORCH { - color 0.3 0.3 1.0 + color 0.2 0.2 0.7 size 90 secondarySize 99 interval 0.1 @@ -432,7 +432,7 @@ object BlueTorch // Small red torch flickerlight2 SMALLREDTORCH { - color 1.0 0.5 0.2 + color 0.7 0.35 0.14 size 72 secondarySize 81 interval 0.1 @@ -448,7 +448,7 @@ object ShortRedTorch // Small green torch flickerlight2 SMALLGREENTORCH { - color 0.3 1.0 0.3 + color 0.2 0.7 0.2 size 72 secondarySize 81 interval 0.1 @@ -464,7 +464,7 @@ object ShortGreenTorch // Small blue torch flickerlight2 SMALLBLUETORCH { - color 0.3 0.3 1.0 + color 0.2 0.2 0.7 size 72 secondarySize 81 interval 0.1 diff --git a/wadsrc_lights/static/filter/doom.doom2/gldefs.txt b/wadsrc_lights/static/filter/doom.doom2/gldefs.txt index 83c30369d..61536f97f 100644 --- a/wadsrc_lights/static/filter/doom.doom2/gldefs.txt +++ b/wadsrc_lights/static/filter/doom.doom2/gldefs.txt @@ -384,7 +384,7 @@ object TechLamp // Tall red torch flickerlight2 BIGREDTORCH { - color 1.0 0.5 0.2 + color 0.7 0.35 0.14 size 90 secondarySize 99 interval 0.1 @@ -400,7 +400,7 @@ object RedTorch // Tall green torch flickerlight2 BIGGREENTORCH { - color 0.3 1.0 0.3 + color 0.2 0.7 0.2 size 90 secondarySize 99 interval 0.1 @@ -416,7 +416,7 @@ object GreenTorch // Tall blue torch flickerlight2 BIGBLUETORCH { - color 0.3 0.3 1.0 + color 0.2 0.2 0.7 size 90 secondarySize 99 interval 0.1 @@ -432,7 +432,7 @@ object BlueTorch // Small red torch flickerlight2 SMALLREDTORCH { - color 1.0 0.5 0.2 + color 0.7 0.35 0.14 size 72 secondarySize 81 interval 0.1 @@ -448,7 +448,7 @@ object ShortRedTorch // Small green torch flickerlight2 SMALLGREENTORCH { - color 0.3 1.0 0.3 + color 0.2 0.7 0.2 size 72 secondarySize 81 interval 0.1 @@ -464,7 +464,7 @@ object ShortGreenTorch // Small blue torch flickerlight2 SMALLBLUETORCH { - color 0.3 0.3 1.0 + color 0.2 0.2 0.7 size 72 secondarySize 81 interval 0.1