diff --git a/game/graphics/opengl_renderer/DirectRenderer.cpp b/game/graphics/opengl_renderer/DirectRenderer.cpp index 64ee7716f2..6f512453f7 100644 --- a/game/graphics/opengl_renderer/DirectRenderer.cpp +++ b/game/graphics/opengl_renderer/DirectRenderer.cpp @@ -334,14 +334,20 @@ void DirectRenderer::update_gl_prim(SharedRenderState* render_state) { if (state.texture_enable) { float alpha_min = 0.0; float alpha_max = 10; + int greater = 0; if (m_test_state.alpha_test_enable) { switch (m_test_state.alpha_test) { case GsTest::AlphaTest::ALWAYS: break; case GsTest::AlphaTest::GEQUAL: - case GsTest::AlphaTest::GREATER: // todo alpha_min = m_test_state.aref / 128.f; m_double_draw_aref = alpha_min; + greater = 0; + break; + case GsTest::AlphaTest::GREATER: + alpha_min = (1 + m_test_state.aref) / 128.f; + m_double_draw_aref = alpha_min; + greater = 1; break; case GsTest::AlphaTest::NEVER: break; @@ -370,6 +376,9 @@ void DirectRenderer::update_gl_prim(SharedRenderState* render_state) { glUniform1i(glGetUniformLocation(render_state->shaders[ShaderId::DIRECT_BASIC_TEXTURED].id(), "offscreen_mode"), m_offscreen_mode); + glUniform1i(glGetUniformLocation(render_state->shaders[ShaderId::DIRECT_BASIC_TEXTURED].id(), + "greater"), + greater); glUniform1f( glGetUniformLocation(render_state->shaders[ShaderId::DIRECT_BASIC_TEXTURED].id(), "ta0"), state.ta0 / 255.f); diff --git a/game/graphics/opengl_renderer/shaders/direct_basic_textured.frag b/game/graphics/opengl_renderer/shaders/direct_basic_textured.frag index 9d3e99e95f..8503d374fc 100644 --- a/game/graphics/opengl_renderer/shaders/direct_basic_textured.frag +++ b/game/graphics/opengl_renderer/shaders/direct_basic_textured.frag @@ -13,6 +13,7 @@ uniform float alpha_mult; uniform float alpha_sub; uniform float ta0; uniform int scissor_enable; +uniform bool greater; // game width, game height, viewport width, viewport height uniform vec4 game_sizes; @@ -85,8 +86,18 @@ void main() { color *= 2; color.xyz *= color_mult; color.w *= alpha_mult; - if (color.a < alpha_min || color.a > alpha_max) { - discard; + if (greater) { + // pass if alpha > min, so discard if alpha <= min + // greater than check should use the opposite, so alpha values equal to aref are only passed once for + // any double-draw + if (color.a <= alpha_min || color.a > alpha_max) { + discard; + } + } else { + // and this is just flipped from the case above. + if (color.a < alpha_min || color.a >= alpha_max) { + discard; + } } if (tex_info.w == 1) { color.xyz = mix(color.xyz, fog_color.rgb, clamp(fog_color.a * fog, 0, 1));