I want to make a post-effect where every second column of pixels is colored differently, and I want to implement this as a GLSL fragment shader on GLES2. The question is what is the most effective way to know if a fragment is indeed odd or even in the x direction?

My current ideas revolve around the following three approaches:

1. Integer bit-wise operator

//Pseudo code
bool even_w=((int)(viewport_pixels_width*screenspace_x))&1>0;

2. Sinus

//Pseudo code
float evenness_w=(sin(viewport_pixels_width*screenspace_x*M_PI)+1.0)*0.5;

3. Texture

//Pseudo code
bool even_w = lookupFromMyRepeating2x1CheckerTexture(viewport_pixels_width*screenspace_x);

All ideas and feedback are welcome!

  • 1
    \$\begingroup\$ use gl_FragCoord and fract \$\endgroup\$ – v.oddou Nov 6 '14 at 0:46
  • \$\begingroup\$ What can you say about the performance of this approach? Will it be fast on mobile devices? \$\endgroup\$ – Lennart Rolland Nov 6 '14 at 0:49
  • \$\begingroup\$ very fast. it will be so fast that it will be transparent. The reason for that is that any platform in existence from the past 10 years is limited by bandwidth, and not ALU/FPU. You can throw a very large amount of calculations before seeing an impact. Getting the results out to the render target is the bottleneck. (ROPs + bus bandwidth). This is already true on PC, and very very much more true on mobile, because the bandwidth is an order of magnitude lesser ! \$\endgroup\$ – v.oddou Nov 6 '14 at 3:47
  • \$\begingroup\$ :D Now if that was an answer you would have my +1, and probably a V as well if there wasn't anyone else putting in a better one.. \$\endgroup\$ – Lennart Rolland Nov 6 '14 at 3:49
  • \$\begingroup\$ I have a post on gamedev.net (gamedev.net/topic/…) that does what you need, in HLSL though, but you just need to map to GLSL parlance, using the 2 names I gave in the first comment. This is the code for column-wise discrimination: float2 txc = ScreenPosition.xy; if (fmod(txc.x, 2) < 1) { /*even columns*/ } else {} // odd \$\endgroup\$ – v.oddou Nov 6 '14 at 3:51

The way to discriminate that is to use the screen position intrinsic of GLSL gl_FragCoord (some call it a built-in variable). And pass it through a floating point function that will do the equivalent of a modulo in integers math. This way, you can use 2 as a divisor and the (floating point) alternation of the saw-dent-like ramps it will create (rising from 0 to 1.999..) will give you the factor you need, by using 1 as the cutoff. of course the ramps are not continuous, its discreete. Especially if there is no multisampling in your rendertarget (but the sample sub-position is given by another inrinsic anyway, so you get rounded coordinates for pixels).

Using this:

vec2 txc = gl_FragCoord.xy;
if (mod(txc.x, 2) < 1)
  // even
  // odd

should to the trick


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.