2
\$\begingroup\$

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:

enter image description here

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?

\$\endgroup\$
1
\$\begingroup\$

Use the almighty <! Epsilon comparsion is not needed here.

if (mod(gl_FragCoord.y, density) < 1)
    /* Draw scanline */

By the way, this

retColor *= vec4(vec3(SCANLINE_INTENSITY), vColor.a);

is incorrect because your alpha becomes squared. Use

retColor.rgb *= SCANLINE_INTENSITY;
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.