I have a shader using dFdx and dFdy to produce pseudo anti-aliasing. This is necessary because the shader draws curved edges which are not effected by hardware anti-aliasing methods. While this looks great when hardware anti-aliasing, settings.setSamples(1), is turned off, it produces artifacts when hardware anti-aliasing is turned on and I’m not sure why.
settings.setSamples(1):
settings.setSamples(8)
Any thoughts? I tried padding the mesh with extra space around the edges and just discarding those pixels, but that didn’t make any difference.
Fragment shader:
#ifdef USEAA
#ifdef ISMOBILE
#extension GL_OES_standard_derivatives:enable
#endif
#endif
uniform vec4 m_brdr1;
uniform vec4 m_brdr2;
uniform vec4 m_brdr3;
uniform vec4 m_brdr4;
uniform float m_brdrstp1;
uniform float m_brdrstp2;
uniform float m_brdrstp3;
uniform float m_brdrstp4;
uniform float m_Radius;
uniform vec4 m_col1;
uniform vec4 m_col2;
uniform vec4 m_col3;
uniform vec4 m_col4;
uniform vec4 m_col5;
uniform vec4 m_col6;
uniform vec4 m_col7;
uniform vec4 m_col8;
uniform float m_stop1;
uniform float m_stop2;
uniform float m_stop3;
uniform float m_stop4;
uniform float m_stop5;
uniform float m_stop6;
uniform float m_stop7;
uniform float m_stop8;
uniform float m_Alpha;
uniform bool m_useAA;
uniform bool m_isCircle;
varying vec2 texCoord;
varying vec2 texCoord2;
varying vec2 borderCoord;
#ifdef USEAA
float AA(in float r) {
vec2 px = vec2(dFdx(texCoord.x), dFdx(texCoord.y));
vec2 py = vec2(dFdy(texCoord.x), dFdy(texCoord.y));
float fx = (2*texCoord.x)*px.x - px.y;
float fy = (2*texCoord.y)*py.x - py.y;
float sd = r/sqrt(fx*fx + fy*fy);
return clamp(0.25 + sd, 0.0, 1.0);
}
#endif
void fadeColor(inout vec4 color, in vec4 color2, in float percent) {
color *= percent;
color += color2 * (1.0 - percent);
}
vec4 panelColor(inout vec4 color) {
color = m_col1;
float perc = clamp((m_stop1 - texCoord2.y) / min(m_stop1 - m_stop2, -0.00001), 0.0, 1.0);
fadeColor(color, m_col2, 1.0 - perc);
#ifdef HAS_COL3
perc = clamp((m_stop2 - texCoord2.y) / min(m_stop2 - m_stop3, -0.00001), 0.0, 1.0);
fadeColor(color, m_col3, 1.0 - perc);
#endif
#ifdef HAS_COL4
perc = clamp((m_stop3 - texCoord2.y) / min(m_stop3 - m_stop4, -0.00001), 0.0, 1.0);
fadeColor(color, m_col4, 1.0 - perc);
#endif
#ifdef HAS_COL5
perc = clamp((m_stop4 - texCoord2.y) / min(m_stop4 - m_stop5, -0.00001), 0.0, 1.0);
fadeColor(color, m_col5, 1.0 - perc);
#endif
#ifdef HAS_COL6
perc = clamp((m_stop5 - texCoord2.y) / min(m_stop5 - m_stop6, -0.00001), 0.0, 1.0);
fadeColor(color, m_col6, 1.0 - perc);
#endif
#ifdef HAS_COL7
perc = clamp((m_stop6 - texCoord2.y) / min(m_stop6 - m_stop7, -0.00001), 0.0, 1.0);
fadeColor(color, m_col7, 1.0 - perc);
#endif
#ifdef HAS_COL8
perc = clamp((m_stop7 - texCoord2.y) / min(m_stop7 - m_stop8, -0.00001), 0.0, 1.0);
fadeColor(color, m_col8, 1.0 - perc);
#endif
return color;
}
vec4 radialPanelColor(inout vec4 color) {
color = m_col1;
float r = sqrt((texCoord2.x*texCoord2.x) + (texCoord2.y*texCoord2.y));
float perc = clamp((r - m_stop1) / max(m_stop2 - m_stop1, 0.00001), 0.0, 1.0);
fadeColor(color, m_col2, 1.0 - perc);
#ifdef HAS_COL3
perc = clamp((r - m_stop2) / max(m_stop3 - m_stop2, 0.00001), 0.0, 1.0);
fadeColor(color, m_col3, 1.0 - perc);
#endif
#ifdef HAS_COL4
perc = clamp((r - m_stop3) / max(m_stop4 - m_stop3, 0.00001), 0.0, 1.0);
fadeColor(color, m_col4, 1.0 - perc);
#endif
#ifdef HAS_COL5
perc = clamp((r - m_stop4) / max(m_stop5 - m_stop4, 0.00001), 0.0, 1.0);
fadeColor(color, m_col5, 1.0 - perc);
#endif
#ifdef HAS_COL6
perc = clamp((r - m_stop5) / max(m_stop6 - m_stop5, 0.00001), 0.0, 1.0);
fadeColor(color, m_col6, 1.0 - perc);
#endif
#ifdef HAS_COL7
perc = clamp((r - m_stop6) / max(m_stop7 - m_stop6, 0.00001), 0.0, 1.0);
fadeColor(color, m_col7, 1.0 - perc);
#endif
#ifdef HAS_COL8
perc = clamp((r - m_stop7) / max(m_stop8 - m_stop7, 0.00001), 0.0, 1.0);
fadeColor(color, m_col8, 1.0 - perc);
#endif
return color;
}
void border(inout vec4 color) {
color = m_brdr1;
#ifdef HAS_BRDR2
float perc = clamp((m_brdrstp1 - borderCoord.y) / min(m_brdrstp1 - m_brdrstp2, -0.00001), 0.0, 1.0);
fadeColor(color, m_brdr2, 1.0 - perc);
#ifdef HAS_BRDR3
perc = clamp((m_brdrstp2 - borderCoord.y) / min(m_brdrstp2 - m_brdrstp3, -0.00001), 0.0, 1.0);
fadeColor(color, m_brdr3, 1.0 - perc);
#endif
#ifdef HAS_BRDR4
perc = clamp((m_brdrstp3 - borderCoord.y) / min(m_brdrstp3 - m_brdrstp4, -0.00001), 0.0, 1.0);
fadeColor(color, m_brdr4, 1.0 - perc);
#endif
#endif
}
void roundedBorder(inout vec4 color, inout float alpha) {
float c = sqrt((texCoord.x*texCoord.x) + (texCoord.y*texCoord.y));
float r = 1.0 - c;
#ifdef USEAA
alpha *= AA(r);
#else
alpha = step(0.0001, r);
#endif
float f = 1.0 - (c * (1.0 / max(m_Radius, 0.00001)));
#ifdef USEAA
f = AA(f);
#else
f = step(0.0001, f);
#endif
border(color);
#ifdef HAS_COLFADE
vec4 pCol = vec4(0);
#ifdef IS_CIRCLE
fadeColor(color, radialPanelColor(pCol), 1.0 - f);
#else
fadeColor(color, panelColor(pCol), 1.0 - f);
#endif
#else
fadeColor(color, m_col1, 1.0 - f);
#endif
}
void main() {
float alpha = m_Alpha;
vec4 col = vec4(0);
if (texCoord.x < 2.0) {
#ifdef HAS_BORDER
#ifdef IS_ROUNDED
roundedBorder(col, alpha);
#else
border(col);
#endif
#else
#ifdef IS_ROUNDED
float c = sqrt((texCoord.x*texCoord.x) + (texCoord.y*texCoord.y));
float r = 1.0 - c;
#ifdef USEAA
alpha *= AA(r);
#else
alpha = step(0.0001, r);
#endif
#ifdef HAS_COLFADE
#ifdef IS_CIRCLE
radialPanelColor(col);
#else
panelColor(col);
#endif
#else
col = m_col1;
#endif
#else
alpha = 0.0;
#endif
#endif
} else {
#ifdef HAS_COLFADE
#ifdef IS_CIRCLE
radialPanelColor(col);
#else
panelColor(col);
#endif
#else
col = m_col1;
#endif
}
if (alpha <= 0.0) {
discard;
} else {
gl_FragColor = vec4(col.rgb, alpha * col.a);
}
}