I’ve implemented a simple scanline shader into a libGDX mobile game I’m working on. Here are the vertex and fragment scripts:
vertex
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
varying vec4 v_color;
varying vec2 v_texCoords;
void main()
{
v_color = a_color;
v_texCoords = a_texCoord0;
gl_Position = u_projTrans * a_position;
}
fragment
#ifdef GL_ES
precision mediump float;
#endif
const float INTENSITY = 0.15;
varying vec2 v_texCoords;
varying vec4 v_color;
uniform sampler2D u_texture;
uniform float u_scanlineCountMultipliedByScreenHeight;
void main()
{
vec4 texture = texture2D(u_texture, v_texCoords);
float screenV = gl_FragCoord.y * u_scanlineCountMultipliedByScreenHeight;
float scanLine = INTENSITY * mod(screenV, 1.0);
gl_FragColor = v_color * vec4(texture.rgb - scanLine, texture.a);
}
Before applying this shader, I get a pretty decent 55 to 60 fps on my 6 year old ZTE-BLADE. After applying the shader, I get 30 to 40fps. I’ve already optimised the game to within an inch of its life, so the only option left is to optimise the shader, if possible. I’m willing to accept that my ancient mobile simply isn’t up to the task, in which case I will add a scanlines on/off button, but if anyone could see something obvious that could be optimised, I’d be very interested to test it out!
I’d also be interested to know if it might be more efficient to use a full screen transparency instead of a shader to achieve the scanline effect.