diff --git a/ci_shadervalidator/Globals.h b/ci_shadervalidator/Globals.h index 16f85e80..e8f548dc 100644 --- a/ci_shadervalidator/Globals.h +++ b/ci_shadervalidator/Globals.h @@ -8,6 +8,7 @@ struct _global bool gfx_extraeffects; bool gfx_shadergamma; bool gfx_usegles; + int iMultisampling; }; extern _global Global; diff --git a/gl/glsl_common.cpp b/gl/glsl_common.cpp index 26c31000..a0d38de6 100644 --- a/gl/glsl_common.cpp +++ b/gl/glsl_common.cpp @@ -11,6 +11,7 @@ void gl::glsl_common_setup() "#define MOTIONBLUR_ENABLED " + std::to_string((int)Global.gfx_postfx_motionblur_enabled) + "\n" + "#define POSTFX_ENABLED " + std::to_string((int)!Global.gfx_skippipeline) + "\n" + "#define EXTRAEFFECTS_ENABLED " + std::to_string((int)Global.gfx_extraeffects) + "\n" + + "#define ALPHA_TO_COVERAGE_ENABLED " + std::to_string((int)(Global.iMultisampling > 0)) + "\n" + "#define MAX_LIGHTS " + std::to_string(MAX_LIGHTS) + "U\n" + "#define MAX_CASCADES " + std::to_string(MAX_CASCADES) + "U\n" + "#define MAX_PARAMS " + std::to_string(MAX_PARAMS) + "U\n" + @@ -110,5 +111,34 @@ void gl::glsl_common_setup() } #endif + #ifdef STAGE_FRAGMENT + // alpha tested surfaces (positive opacity, the opaque pass) get the coverage of their alpha + // test edge from GL_SAMPLE_ALPHA_TO_COVERAGE, which the renderer turns on for them with + // multisampling; otherwise the alpha test keeps or drops whole pixels and its edges stay + // jagged whatever the multisampling. the alpha is sharpened to go from 0 to 1 over about + // a pixel around the test threshold, so the edge keeps the place and sharpness the alpha + // test gave it. computed before any discard, which leaves the derivatives undefined + float alpha_coverage(float alpha) + { + #if ALPHA_TO_COVERAGE_ENABLED + if (opacity > 0.0) + return clamp((alpha - opacity) / max(fwidth(alpha), 0.0001) + 0.5, 0.0, 1.0); + #endif + return alpha; + } + + // true for the fragments the alpha test drops: below the opacity threshold in the opaque + // pass, at or above it (negative opacity) in the translucent pass. with alpha to coverage + // only the fragments which cover no sample at all + bool alpha_test_fail(float alpha, float coverage) + { + #if ALPHA_TO_COVERAGE_ENABLED + if (opacity > 0.0) + return coverage <= 0.0; + #endif + return (opacity >= 0.0 ? (alpha < opacity) : (alpha >= -opacity)); + } + #endif + )STRING"; } diff --git a/gl/shader.cpp b/gl/shader.cpp index 9160a2c9..31a3e6a8 100644 --- a/gl/shader.cpp +++ b/gl/shader.cpp @@ -175,6 +175,8 @@ std::pair gl::shader::process_source(const std::string &fil str += "vec4 FBOUT(vec4 x) { return " + (Global.gfx_shadergamma ? std::string("vec4(pow(x.rgb, vec3(1.0 / 2.2)), x.a)") : std::string("x")) + "; }\n"; str += read_file(basedir + filename); + // checked before the includes are expanded, since glsl_common defines the function + alpha_to_coverage = ( str.find( "alpha_test_fail(" ) != std::string::npos ); expand_includes(str, basedir); parse_texture_entries(str); @@ -381,6 +383,7 @@ void gl::program::attach(const gl::shader &s) texture_conf.try_emplace(texturename, std::move(textureentry)); for (auto [paramname, paramentry] : s.param_conf) param_conf.try_emplace(paramname, std::move(paramentry)); + alpha_to_coverage = alpha_to_coverage || s.alpha_to_coverage; glAttachShader(*this, *s); } diff --git a/gl/shader.h b/gl/shader.h index f1735a0e..e46c1427 100644 --- a/gl/shader.h +++ b/gl/shader.h @@ -63,6 +63,9 @@ namespace gl std::unordered_map texture_conf; std::unordered_map param_conf; std::string name; + // the shader does its alpha test with alpha_test_fail() of glsl_common, so its alpha + // output can drive GL_SAMPLE_ALPHA_TO_COVERAGE in the opaque pass + bool alpha_to_coverage{ false }; #ifndef SHADERVALIDATOR_STANDALONE private: @@ -96,6 +99,7 @@ namespace gl std::unordered_map texture_conf; std::unordered_map param_conf; + bool alpha_to_coverage{ false }; private: void init(); diff --git a/rendering/opengl33renderer.cpp b/rendering/opengl33renderer.cpp index 932ac31f..d577312b 100644 --- a/rendering/opengl33renderer.cpp +++ b/rendering/opengl33renderer.cpp @@ -1820,6 +1820,18 @@ void opengl33_renderer::setup_matrices() OpenGLMatrices.load_matrix(glm::mat4{glm::mat3{m_renderpass.pass_camera.modelview()}}); } +void opengl33_renderer::setup_alpha_to_coverage(bool const Enable) +{ + if (Enable == m_alphatocoverageenabled) + return; + + if (Enable) + glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE); + else + glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); + m_alphatocoverageenabled = Enable; +} + void opengl33_renderer::setup_drawing(bool const Alpha) { if (Alpha) @@ -1834,6 +1846,8 @@ void opengl33_renderer::setup_drawing(bool const Alpha) glDepthMask(GL_TRUE); m_blendingenabled = false; } + // turned on again per material, by the ones which need it + setup_alpha_to_coverage(false); switch (m_renderpass.draw_mode) { @@ -2374,6 +2388,16 @@ void opengl33_renderer::Bind_Material( material_handle const Material, TSubModel else model_ubs.alpha_mult = 1.0f; + // the alpha test drops or keeps whole pixels, so multisampling alone leaves its edges (e.g. sides + // of the trackbed textures) jagged. the alpha tested materials of the opaque colour pass get them + // antialiased with alpha to coverage instead; their shaders give the coverage as the alpha + setup_alpha_to_coverage( + Global.iMultisampling > 0 + && false == m_blendingenabled + && m_renderpass.draw_mode == rendermode::color + && model_ubs.opacity > 0.f + && material.shader->alpha_to_coverage ); + // materials which declare texture variants provide a different texture set per model instance, // picked from the seed of the rendered instance and the variant group of the submodel auto const &materialtextures{ diff --git a/rendering/opengl33renderer.h b/rendering/opengl33renderer.h index 1b489738..0e84761e 100644 --- a/rendering/opengl33renderer.h +++ b/rendering/opengl33renderer.h @@ -277,6 +277,8 @@ class opengl33_renderer : public gfx_renderer { void setup_pass(viewport_config &Viewport, renderpass_config &Config, rendermode const Mode, float const Znear = 0.f, float const Zfar = 1.f, bool const Ignoredebug = false); void setup_matrices(); void setup_drawing(bool const Alpha = false); + // alpha to coverage for the alpha tested materials of the opaque colour pass, when multisampled + void setup_alpha_to_coverage(bool const Enable); void setup_shadow_unbind_map(); void setup_shadow_bind_map(); void setup_shadow_color( glm::vec4 const &Shadowcolor ); @@ -560,6 +562,7 @@ class opengl33_renderer : public gfx_renderer { material_handle m_invalid_material; bool m_blendingenabled; + bool m_alphatocoverageenabled{ false }; bool m_widelines_supported; diff --git a/shaders/mat_default.frag b/shaders/mat_default.frag index bc48d939..5459f1d2 100644 --- a/shaders/mat_default.frag +++ b/shaders/mat_default.frag @@ -29,7 +29,8 @@ void main() { vec4 tex_color = texture(diffuse, f_coord); - bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); + float alphacoverage = alpha_coverage(tex_color.a); + bool alphatestfail = alpha_test_fail(tex_color.a, alphacoverage); if(alphatestfail) discard; // if (tex_color.a < opacity) @@ -42,7 +43,7 @@ void main() glossiness = abs(param[1].w); fragcolor = apply_lights(fragcolor, fragnormal, tex_color.rgb, reflectivity, 0.0, shadow_tone); - vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); + vec4 color = vec4(apply_fog(fragcolor), alphacoverage * alpha_mult); /* float distance = dot(f_pos.xyz, f_pos.xyz); if( distance <= cascade_end.x ) { color.r += 0.25; } diff --git a/shaders/mat_default_detail.frag b/shaders/mat_default_detail.frag index 63d15c7c..0f8ad7d5 100644 --- a/shaders/mat_default_detail.frag +++ b/shaders/mat_default_detail.frag @@ -35,7 +35,8 @@ void main() { vec4 tex_color = texture(diffuse, f_coord); - bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); + float alphacoverage = alpha_coverage(tex_color.a); + bool alphatestfail = alpha_test_fail(tex_color.a, alphacoverage); if(alphatestfail) discard; // if (tex_color.a < opacity) @@ -52,7 +53,7 @@ void main() glossiness = abs(param[1].w); fragcolor = apply_lights(fragcolor, fragnormal, tex_color.rgb, reflectivity, specularity, shadow_tone); - vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); + vec4 color = vec4(apply_fog(fragcolor), alphacoverage * alpha_mult); #if POSTFX_ENABLED out_color = color; #else diff --git a/shaders/mat_default_specgloss.frag b/shaders/mat_default_specgloss.frag index 254a0cc7..52d94aec 100644 --- a/shaders/mat_default_specgloss.frag +++ b/shaders/mat_default_specgloss.frag @@ -32,7 +32,8 @@ void main() { vec4 tex_color = texture(diffuse, f_coord); - bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); + float alphacoverage = alpha_coverage(tex_color.a); + bool alphatestfail = alpha_test_fail(tex_color.a, alphacoverage); if(alphatestfail) discard; // if (tex_color.a < opacity) @@ -46,7 +47,7 @@ void main() metalic = texture(specgloss, f_coord).b; fragcolor = apply_lights(fragcolor, fragnormal, tex_color.rgb, reflectivity, specularity, shadow_tone); - vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); + vec4 color = vec4(apply_fog(fragcolor), alphacoverage * alpha_mult); /* float distance = dot(f_pos.xyz, f_pos.xyz); if( distance <= cascade_end.x ) { color.r += 0.25; } diff --git a/shaders/mat_detail_normalmap.frag b/shaders/mat_detail_normalmap.frag index 85f55289..debfe3ba 100644 --- a/shaders/mat_detail_normalmap.frag +++ b/shaders/mat_detail_normalmap.frag @@ -39,7 +39,8 @@ void main() { vec4 tex_color = texture(diffuse, f_coord); - bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); + float alphacoverage = alpha_coverage(tex_color.a); + bool alphatestfail = alpha_test_fail(tex_color.a, alphacoverage); if(alphatestfail) discard; @@ -64,7 +65,7 @@ void main() float specularity = (tex_color.r + tex_color.g + tex_color.b) * 0.5; fragcolor = apply_lights(fragcolor, fragnormal, tex_color.rgb, reflectivity, specularity, shadow_tone); - vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); + vec4 color = vec4(apply_fog(fragcolor), alphacoverage * alpha_mult); #if POSTFX_ENABLED out_color = color; #else diff --git a/shaders/mat_detail_normalmap_specgloss.frag b/shaders/mat_detail_normalmap_specgloss.frag index a3799ce1..0fa9ea2e 100644 --- a/shaders/mat_detail_normalmap_specgloss.frag +++ b/shaders/mat_detail_normalmap_specgloss.frag @@ -42,7 +42,8 @@ void main() { vec4 tex_color = texture(diffuse, f_coord); - bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); + float alphacoverage = alpha_coverage(tex_color.a); + bool alphatestfail = alpha_test_fail(tex_color.a, alphacoverage); if(alphatestfail) discard; // if (tex_color.a < opacity) @@ -72,7 +73,7 @@ void main() fragcolor = apply_lights(fragcolor, fragnormal, tex_color.rgb, reflectivity, specularity, shadow_tone); - vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); + vec4 color = vec4(apply_fog(fragcolor), alphacoverage * alpha_mult); #if POSTFX_ENABLED out_color = color; #else diff --git a/shaders/mat_detail_parallax.frag b/shaders/mat_detail_parallax.frag index 75919b13..28de2509 100644 --- a/shaders/mat_detail_parallax.frag +++ b/shaders/mat_detail_parallax.frag @@ -49,7 +49,8 @@ void main() vec4 detailnormal_map = texture(detailnormalmap, f_coord_p * param[2].x); vec4 tex_color = texture(diffuse, f_coord_p); - bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); + float alphacoverage = alpha_coverage(tex_color.a); + bool alphatestfail = alpha_test_fail(tex_color.a, alphacoverage); if(alphatestfail) discard; // if (tex_color.a < opacity) @@ -72,7 +73,7 @@ void main() fragcolor = apply_lights(fragcolor, fragnormal, tex_color.rgb, reflectivity, specularity, shadow_tone); - vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); + vec4 color = vec4(apply_fog(fragcolor), alphacoverage * alpha_mult); #if POSTFX_ENABLED out_color = color; #else diff --git a/shaders/mat_detail_parallax_specgloss.frag b/shaders/mat_detail_parallax_specgloss.frag index fcc33ac3..8d1b8645 100644 --- a/shaders/mat_detail_parallax_specgloss.frag +++ b/shaders/mat_detail_parallax_specgloss.frag @@ -55,7 +55,8 @@ void main() vec4 tex_color = texture(diffuse, f_coord_p); vec4 specgloss_map = texture(specgloss, f_coord_p); - bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); + float alphacoverage = alpha_coverage(tex_color.a); + bool alphatestfail = alpha_test_fail(tex_color.a, alphacoverage); if(alphatestfail) discard; @@ -78,7 +79,7 @@ void main() fragcolor = apply_lights(fragcolor, fragnormal, tex_color.rgb, reflectivity, specularity, shadow_tone); - vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); + vec4 color = vec4(apply_fog(fragcolor), alphacoverage * alpha_mult); #if POSTFX_ENABLED out_color = color; #else diff --git a/shaders/mat_normalmap.frag b/shaders/mat_normalmap.frag index 3ef505eb..9757324d 100644 --- a/shaders/mat_normalmap.frag +++ b/shaders/mat_normalmap.frag @@ -34,7 +34,8 @@ void main() { vec4 tex_color = texture(diffuse, f_coord); - bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); + float alphacoverage = alpha_coverage(tex_color.a); + bool alphatestfail = alpha_test_fail(tex_color.a, alphacoverage); if(alphatestfail) discard; // if (tex_color.a < opacity) @@ -51,7 +52,7 @@ void main() fragcolor = apply_lights(fragcolor, fragnormal, tex_color.rgb, reflectivity, specularity, shadow_tone); - vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); + vec4 color = vec4(apply_fog(fragcolor), alphacoverage * alpha_mult); #if POSTFX_ENABLED out_color = color; #else diff --git a/shaders/mat_normalmap_specgloss.frag b/shaders/mat_normalmap_specgloss.frag index a4b18462..3f043b51 100644 --- a/shaders/mat_normalmap_specgloss.frag +++ b/shaders/mat_normalmap_specgloss.frag @@ -38,7 +38,8 @@ void main() { vec4 tex_color = texture(diffuse, f_coord); - bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); + float alphacoverage = alpha_coverage(tex_color.a); + bool alphatestfail = alpha_test_fail(tex_color.a, alphacoverage); if(alphatestfail) discard; // if (tex_color.a < opacity) @@ -57,7 +58,7 @@ void main() fragcolor = apply_lights(fragcolor, fragnormal, tex_color.rgb, reflectivity, specularity, shadow_tone); - vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); + vec4 color = vec4(apply_fog(fragcolor), alphacoverage * alpha_mult); #if POSTFX_ENABLED out_color = color; #else diff --git a/shaders/mat_parallax.frag b/shaders/mat_parallax.frag index 7adac054..49e8eb2a 100644 --- a/shaders/mat_parallax.frag +++ b/shaders/mat_parallax.frag @@ -42,7 +42,8 @@ void main() vec4 tex_color = texture(diffuse, f_coord_p); - bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); + float alphacoverage = alpha_coverage(tex_color.a); + bool alphatestfail = alpha_test_fail(tex_color.a, alphacoverage); if(alphatestfail) discard; // if (tex_color.a < opacity) @@ -59,7 +60,7 @@ void main() fragcolor = apply_lights(fragcolor, fragnormal, tex_color.rgb, reflectivity, specularity, shadow_tone); - vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); + vec4 color = vec4(apply_fog(fragcolor), alphacoverage * alpha_mult); #if POSTFX_ENABLED out_color = color; #else diff --git a/shaders/mat_parallax_specgloss.frag b/shaders/mat_parallax_specgloss.frag index 8b590fae..04349ef2 100644 --- a/shaders/mat_parallax_specgloss.frag +++ b/shaders/mat_parallax_specgloss.frag @@ -46,7 +46,8 @@ void main() vec4 tex_color = texture(diffuse, f_coord_p); - bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); + float alphacoverage = alpha_coverage(tex_color.a); + bool alphatestfail = alpha_test_fail(tex_color.a, alphacoverage); if(alphatestfail) discard; // if (tex_color.a < opacity) @@ -65,7 +66,7 @@ void main() fragcolor = apply_lights(fragcolor, fragnormal, tex_color.rgb, reflectivity, specularity, shadow_tone); - vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); + vec4 color = vec4(apply_fog(fragcolor), alphacoverage * alpha_mult); #if POSTFX_ENABLED out_color = color; #else diff --git a/shaders/mat_reflmap.frag b/shaders/mat_reflmap.frag index bd4c4ae7..1ffdd822 100644 --- a/shaders/mat_reflmap.frag +++ b/shaders/mat_reflmap.frag @@ -32,7 +32,8 @@ void main() { vec4 tex_color = texture(diffuse, f_coord); - bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); + float alphacoverage = alpha_coverage(tex_color.a); + bool alphatestfail = alpha_test_fail(tex_color.a, alphacoverage); if(alphatestfail) discard; // if (tex_color.a < opacity) @@ -49,7 +50,7 @@ void main() if(alphatestfail) fragcolor.r = 1.0; - vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); + vec4 color = vec4(apply_fog(fragcolor), alphacoverage * alpha_mult); #if POSTFX_ENABLED out_color = color; diff --git a/shaders/mat_reflmap_specgloss.frag b/shaders/mat_reflmap_specgloss.frag index 4c89083c..71ebbac2 100644 --- a/shaders/mat_reflmap_specgloss.frag +++ b/shaders/mat_reflmap_specgloss.frag @@ -36,7 +36,8 @@ void main() { vec4 tex_color = texture(diffuse, f_coord); - bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); + float alphacoverage = alpha_coverage(tex_color.a); + bool alphatestfail = alpha_test_fail(tex_color.a, alphacoverage); if(alphatestfail) discard; // if (tex_color.a < opacity) @@ -54,7 +55,7 @@ void main() if(alphatestfail) fragcolor.r = 1.0; - vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); + vec4 color = vec4(apply_fog(fragcolor), alphacoverage * alpha_mult); #if POSTFX_ENABLED out_color = color; diff --git a/shaders/mat_shadowlessnormalmap.frag b/shaders/mat_shadowlessnormalmap.frag index cb2c040e..ebf135ba 100644 --- a/shaders/mat_shadowlessnormalmap.frag +++ b/shaders/mat_shadowlessnormalmap.frag @@ -34,7 +34,8 @@ void main() { vec4 tex_color = texture(diffuse, f_coord); - bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); + float alphacoverage = alpha_coverage(tex_color.a); + bool alphatestfail = alpha_test_fail(tex_color.a, alphacoverage); if(alphatestfail) discard; // if (tex_color.a < opacity) @@ -51,7 +52,7 @@ void main() glossiness = abs(param[1].w); fragcolor = apply_lights(fragcolor, fragnormal, tex_color.rgb, reflectivity, specularity, 1.0); - vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); + vec4 color = vec4(apply_fog(fragcolor), alphacoverage * alpha_mult); #if POSTFX_ENABLED out_color = color; #else diff --git a/shaders/mat_shadowlessnormalmap_specgloss.frag b/shaders/mat_shadowlessnormalmap_specgloss.frag index adc473ff..2bd6d215 100644 --- a/shaders/mat_shadowlessnormalmap_specgloss.frag +++ b/shaders/mat_shadowlessnormalmap_specgloss.frag @@ -38,7 +38,8 @@ void main() { vec4 tex_color = texture(diffuse, f_coord); - bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); + float alphacoverage = alpha_coverage(tex_color.a); + bool alphatestfail = alpha_test_fail(tex_color.a, alphacoverage); if(alphatestfail) discard; // if (tex_color.a < opacity) @@ -56,7 +57,7 @@ void main() metalic = texture(specgloss, f_coord).b; fragcolor = apply_lights(fragcolor, fragnormal, tex_color.rgb, reflectivity, specularity, 1.0); - vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); + vec4 color = vec4(apply_fog(fragcolor), alphacoverage * alpha_mult); #if POSTFX_ENABLED out_color = color; #else diff --git a/shaders/mat_sunlessnormalmap.frag b/shaders/mat_sunlessnormalmap.frag index 0b3fc7f6..a5e97d30 100644 --- a/shaders/mat_sunlessnormalmap.frag +++ b/shaders/mat_sunlessnormalmap.frag @@ -99,7 +99,8 @@ void main() { vec4 tex_color = texture(diffuse, f_coord); - bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); + float alphacoverage = alpha_coverage(tex_color.a); + bool alphatestfail = alpha_test_fail(tex_color.a, alphacoverage); if(alphatestfail) discard; // if (tex_color.a < opacity) @@ -115,7 +116,7 @@ void main() float specularity = (tex_color.r + tex_color.g + tex_color.b) * 0.5; fragcolor = apply_lights_sunless(fragcolor, fragnormal, tex_color.rgb, reflectivity, specularity, shadow_tone); - vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); + vec4 color = vec4(apply_fog(fragcolor), alphacoverage * alpha_mult); #if POSTFX_ENABLED out_color = color; #else diff --git a/shaders/mat_sunlessnormalmap_specgloss.frag b/shaders/mat_sunlessnormalmap_specgloss.frag index 21cc9f6e..4e2abe1d 100644 --- a/shaders/mat_sunlessnormalmap_specgloss.frag +++ b/shaders/mat_sunlessnormalmap_specgloss.frag @@ -113,7 +113,8 @@ void main() { vec4 tex_color = texture(diffuse, f_coord); - bool alphatestfail = ( opacity >= 0.0 ? (tex_color.a < opacity) : (tex_color.a >= -opacity) ); + float alphacoverage = alpha_coverage(tex_color.a); + bool alphatestfail = alpha_test_fail(tex_color.a, alphacoverage); if(alphatestfail) discard; // if (tex_color.a < opacity) @@ -131,7 +132,7 @@ void main() metalic = texture(specgloss, f_coord).b; fragcolor = apply_lights_sunless(fragcolor, fragnormal, tex_color.rgb, reflectivity, specularity, shadow_tone); - vec4 color = vec4(apply_fog(fragcolor), tex_color.a * alpha_mult); + vec4 color = vec4(apply_fog(fragcolor), alphacoverage * alpha_mult); #if POSTFX_ENABLED out_color = color; #else