Skip to content

Commit

Permalink
Correct alpha compare:
Browse files Browse the repository at this point in the history
- Take into account coverage flags.
  This is still not quite correct without proper coverage emulation.
- Discard pixels with zero alpha if uCvgXAlpha flag is set.
  Resulted pixel coverage is function of pixel alpha multiplied by actual
  coverage in that mode, thus pixel with zero alpha has zero coverage and discarded.

Fixed regression in BAR, issue #866
  • Loading branch information
gonetz committed Mar 12, 2016
1 parent 56f85e0 commit b7369e9
Showing 6 changed files with 50 additions and 29 deletions.
25 changes: 13 additions & 12 deletions src/GLES2/GLSLCombiner_gles2.cpp
Original file line number Diff line number Diff line change
@@ -145,7 +145,7 @@ void DestroyShaderCombiner() {

ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCombine & _combine) : m_combine(_combine)
{
char strCombiner[1024];
char strCombiner[2048];
m_nInputs = compileCombiner(_color, _alpha, strCombiner);

if (usesTexture()) {
@@ -179,6 +179,10 @@ ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCo
strFragmentShader.append(" vec_color = vec4(input_color, vShadeColor.a); \n");
strFragmentShader.append(strCombiner);

strFragmentShader.append(
" if (uCvgXAlpha != 0 && alpha2 == 0.0) discard; \n"
);

if (!g_weakGLSL) {
strFragmentShader.append(
" lowp int fogUsage = uFogUsage; \n"
@@ -253,6 +257,8 @@ void ShaderCombiner::_locateUniforms() {
LocateUniform(uFogMode);
LocateUniform(uFogUsage);
LocateUniform(uAlphaCompareMode);
LocateUniform(uCvgXAlpha);
LocateUniform(uAlphaCvgSel);
LocateUniform(uEnableAlphaTest);
LocateUniform(uEnableDepth);
LocateUniform(uEnableDepthCompare)
@@ -482,28 +488,23 @@ void ShaderCombiner::updateDepthInfo(bool _bForce) {
void ShaderCombiner::updateAlphaTestInfo(bool _bForce) {
if (gDP.otherMode.cycleType == G_CYC_FILL) {
m_uniforms.uEnableAlphaTest.set(0, _bForce);
m_uniforms.uAlphaTestValue.set(0.0f, _bForce);
} else if (gDP.otherMode.cycleType == G_CYC_COPY) {
if (gDP.otherMode.alphaCompare & G_AC_THRESHOLD) {
m_uniforms.uEnableAlphaTest.set(1, _bForce);
m_uniforms.uAlphaCvgSel.set(0, _bForce);
m_uniforms.uAlphaTestValue.set(0.5f, _bForce);
} else {
m_uniforms.uEnableAlphaTest.set(0, _bForce);
m_uniforms.uAlphaTestValue.set(0.0f, _bForce);
}
} else if (((gDP.otherMode.alphaCompare & G_AC_THRESHOLD) != 0) && (gDP.otherMode.alphaCvgSel == 0) && (gDP.otherMode.forceBlender == 0 || gDP.blendColor.a > 0)) {
} else if ((gDP.otherMode.alphaCompare & G_AC_THRESHOLD) != 0) {
m_uniforms.uEnableAlphaTest.set(1, _bForce);
m_uniforms.uAlphaTestValue.set(max(gDP.blendColor.a, 1.0f / 256.0f), _bForce);
} else if ((gDP.otherMode.alphaCompare == G_AC_DITHER) && (gDP.otherMode.alphaCvgSel == 0)) {
m_uniforms.uEnableAlphaTest.set(1, _bForce);
m_uniforms.uAlphaTestValue.set(0.0f, _bForce);
} else if (gDP.otherMode.cvgXAlpha != 0) {
m_uniforms.uEnableAlphaTest.set(1, _bForce);
m_uniforms.uAlphaTestValue.set(0.125f, _bForce);
m_uniforms.uAlphaTestValue.set(gDP.blendColor.a, _bForce);
m_uniforms.uAlphaCvgSel.set(gDP.otherMode.alphaCvgSel, _bForce);
} else {
m_uniforms.uEnableAlphaTest.set(0, _bForce);
m_uniforms.uAlphaTestValue.set(0.0f, _bForce);
}

m_uniforms.uCvgXAlpha.set(gDP.otherMode.cvgXAlpha, _bForce);
}

void SetMonochromeCombiner() {
4 changes: 4 additions & 0 deletions src/GLES2/Shaders_gles2.h
Original file line number Diff line number Diff line change
@@ -166,6 +166,8 @@ SHADER_VERSION
"uniform lowp ivec2 uFbFixedAlpha;\n"
"uniform lowp int uSpecialBlendMode;\n"
"uniform lowp int uEnableAlphaTest; \n"
"uniform lowp int uCvgXAlpha; \n"
"uniform lowp int uAlphaCvgSel; \n"
"uniform lowp float uAlphaTestValue;\n"
"uniform mediump vec2 uDepthScale; \n"
"IN lowp vec4 vShadeColor; \n"
@@ -202,6 +204,8 @@ SHADER_VERSION
"uniform lowp int uFogUsage; \n"
"uniform lowp int uSpecialBlendMode;\n"
"uniform lowp int uEnableAlphaTest; \n"
"uniform lowp int uCvgXAlpha; \n"
"uniform lowp int uAlphaCvgSel; \n"
"uniform lowp float uAlphaTestValue;\n"
"uniform mediump vec2 uDepthScale; \n"
"IN lowp vec4 vShadeColor; \n"
3 changes: 2 additions & 1 deletion src/GLSLCombiner.h
Original file line number Diff line number Diff line change
@@ -96,7 +96,8 @@ class ShaderCombiner {
uEnableDepth, uEnableDepthCompare, uEnableDepthUpdate,
uDepthMode, uDepthSource, uRenderState, uSpecialBlendMode,
uMaxTile, uTextureDetail, uTexturePersp, uTextureFilterMode, uMSAASamples,
uAlphaCompareMode, uAlphaDitherMode, uColorDitherMode;
uAlphaCompareMode, uAlphaDitherMode, uColorDitherMode,
uCvgXAlpha, uAlphaCvgSel;

fUniform uFogAlpha, uMinLod, uDeltaZ, uAlphaTestValue, uMSAAScale;

25 changes: 13 additions & 12 deletions src/OGL3X/GLSLCombiner_ogl3x.cpp
Original file line number Diff line number Diff line change
@@ -282,7 +282,7 @@ ShaderCombiner::ShaderCombiner() : m_bNeedUpdate(true)

ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCombine & _combine) : m_combine(_combine), m_bNeedUpdate(true)
{
char strCombiner[1024];
char strCombiner[2048];
m_nInputs = compileCombiner(_color, _alpha, strCombiner);

const bool bUseLod = usesLOD();
@@ -369,6 +369,10 @@ ShaderCombiner::ShaderCombiner(Combiner & _color, Combiner & _alpha, const gDPCo
strFragmentShader.append(" vec_color = vec4(input_color, vShadeColor.a); \n");
strFragmentShader.append(strCombiner);

strFragmentShader.append(
" if (uCvgXAlpha != 0 && alpha2 == 0.0) discard; \n"
);

if (config.generalEmulation.enableNoise != 0) {
strFragmentShader.append(
" if (uColorDitherMode == 2) colorNoiseDither(snoise(), color2); \n"
@@ -484,6 +488,8 @@ void ShaderCombiner::_locateUniforms() {
LocateUniform(uAlphaCompareMode);
LocateUniform(uAlphaDitherMode);
LocateUniform(uColorDitherMode);
LocateUniform(uCvgXAlpha);
LocateUniform(uAlphaCvgSel);
LocateUniform(uEnableLod);
LocateUniform(uEnableAlphaTest);
LocateUniform(uEnableDepth);
@@ -749,28 +755,23 @@ void ShaderCombiner::updateDepthInfo(bool _bForce) {
void ShaderCombiner::updateAlphaTestInfo(bool _bForce) {
if (gDP.otherMode.cycleType == G_CYC_FILL) {
m_uniforms.uEnableAlphaTest.set(0, _bForce);
m_uniforms.uAlphaTestValue.set(0.0f, _bForce);
} else if (gDP.otherMode.cycleType == G_CYC_COPY) {
if (gDP.otherMode.alphaCompare & G_AC_THRESHOLD) {
m_uniforms.uEnableAlphaTest.set(1, _bForce);
m_uniforms.uAlphaCvgSel.set(0, _bForce);
m_uniforms.uAlphaTestValue.set(0.5f, _bForce);
} else {
m_uniforms.uEnableAlphaTest.set(0, _bForce);
m_uniforms.uAlphaTestValue.set(0.0f, _bForce);
}
} else if (((gDP.otherMode.alphaCompare & G_AC_THRESHOLD) != 0) && (gDP.otherMode.alphaCvgSel == 0) && (gDP.otherMode.forceBlender == 0 || gDP.blendColor.a > 0)) {
} else if ((gDP.otherMode.alphaCompare & G_AC_THRESHOLD) != 0) {
m_uniforms.uEnableAlphaTest.set(1, _bForce);
m_uniforms.uAlphaTestValue.set(max(gDP.blendColor.a, 1.0f / 256.0f), _bForce);
} else if ((gDP.otherMode.alphaCompare == G_AC_DITHER) && (gDP.otherMode.alphaCvgSel == 0)) {
m_uniforms.uEnableAlphaTest.set(1, _bForce);
m_uniforms.uAlphaTestValue.set(0.0f, _bForce);
} else if (gDP.otherMode.cvgXAlpha != 0) {
m_uniforms.uEnableAlphaTest.set(1, _bForce);
m_uniforms.uAlphaTestValue.set(0.125f, _bForce);
m_uniforms.uAlphaTestValue.set(gDP.blendColor.a, _bForce);
m_uniforms.uAlphaCvgSel.set(gDP.otherMode.alphaCvgSel, _bForce);
} else {
m_uniforms.uEnableAlphaTest.set(0, _bForce);
m_uniforms.uAlphaTestValue.set(0.0f, _bForce);
}

m_uniforms.uCvgXAlpha.set(gDP.otherMode.cvgXAlpha, _bForce);
}

std::ostream & operator<< (std::ostream & _os, const ShaderCombiner & _combiner)
4 changes: 4 additions & 0 deletions src/OGL3X/Shaders_ogl3x.h
Original file line number Diff line number Diff line change
@@ -168,6 +168,8 @@ MAIN_SHADER_VERSION
"uniform lowp ivec2 uFbFixedAlpha;\n"
"uniform lowp int uSpecialBlendMode;\n"
"uniform lowp int uEnableAlphaTest; \n"
"uniform lowp int uCvgXAlpha; \n"
"uniform lowp int uAlphaCvgSel; \n"
"uniform lowp float uAlphaTestValue;\n"
"uniform mediump vec2 uDepthScale; \n"
"in lowp vec4 vShadeColor; \n"
@@ -215,6 +217,8 @@ MAIN_SHADER_VERSION
"uniform lowp int uFogUsage; \n"
"uniform lowp int uSpecialBlendMode;\n"
"uniform lowp int uEnableAlphaTest; \n"
"uniform lowp int uCvgXAlpha; \n"
"uniform lowp int uAlphaCvgSel; \n"
"uniform lowp float uAlphaTestValue;\n"
"uniform mediump vec2 uDepthScale; \n"
"in lowp vec4 vShadeColor; \n"
18 changes: 14 additions & 4 deletions src/ShaderUtils.cpp
Original file line number Diff line number Diff line change
@@ -253,12 +253,22 @@ int compileCombiner(Combiner & _color, Combiner & _alpha, char * _strShader)
}
strcpy(_strShader, " alpha1 = ");
int nInputs = _compileCombiner(_alpha.stage[0], AlphaInput, _strShader);

strcat(_strShader,
" if (uEnableAlphaTest != 0) { \n"
" lowp float alphaTestValue = (uAlphaCompareMode == 3 && alpha1 > 0.0) ? snoise() : uAlphaTestValue; \n"
" if (alpha1 < alphaTestValue) discard; \n"
" } \n"
" if (uEnableAlphaTest != 0) { \n"
" lowp float alphaTestValue = (uAlphaCompareMode == 3) ? snoise() : uAlphaTestValue; \n"
" lowp float alphaValue = alpha1; \n"
" if (uAlphaCvgSel == 0) { \n"
" alphaValue += 0.0078125; \n"
" alphaValue = clamp(alphaValue, 0.0, 1.0); \n"
" } else { \n"
" if (uCvgXAlpha != 0) alphaValue *= 0.5; \n"
" else alphaValue = 0.125; \n"
" } \n"
" if (alphaValue < alphaTestValue) discard; \n"
" } \n"
);

strcat(_strShader, " color1 = ");
nInputs |= _compileCombiner(_color.stage[0], ColorInput, _strShader);
strcat(_strShader, fragment_shader_blender);

0 comments on commit b7369e9

Please sign in to comment.