Through trial and error I've managed to come up with a scanline-ish shader I'm satisfied with. On my desktop testbed it looks like this:
Basically, every 2nd(vertical) pixel is darkened.
However, when I add the same shader to my android sprite batch the darkened lines no longer show up. I've assumed it's due to use of mod
and float comparison since GLES is lower precision than desktop GL and it probably never evaluates yPos == 0.5
to true. So to combat that I've created an EPSILON
value to give a bit of leeway for float comparison but that didn't help either. However I'm certain that I've set up the shader program correctly since simple color manipulation shaders seem to work properly, only when mod
gotten introduced into the mix things turned sour.
Here's the shader code:
scanline.vert
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
varying vec4 vColor;
varying vec2 vTexCoord;
void main() {
vColor = a_color;
vTexCoord = a_texCoord0;
gl_Position = u_projTrans * a_position;
}
scanline.frag
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 vColor;
varying vec2 vTexCoord;
uniform sampler2D u_texture;
uniform mat4 u_projTrans;
const float SCANLINE_INTENSITY = 0.7; // lower is stronger, probably should call this softness
const float SCANLINE_DENSITY = 2.0; // every 2nd pixel
const float EPSILON = 0.01;
void main() {
vec4 texColor = texture2D(u_texture, vTexCoord);
float yPos = mod(gl_FragCoord.y, SCANLINE_DENSITY);
vec4 retColor = vColor;
//if(yPos == 0.5) {
if(abs(yPos - 0.5) < EPSILON) {
retColor *= vec4(vec3(SCANLINE_INTENSITY), vColor.a);
}
gl_FragColor = texColor * retColor;
}
What am I doing wrong?