Search code examples
glslwebgl

Stable values in vertex shader, unstable in fragment when rendered with webgl


I'm working with an unfamiliar scene and trying to render an array of points.

In the vertex shader i have this if/else block that resizes every 6th point and the last 3. This works as expected, points render at different sizes and as i navigate the scene they remain consistent.

However, when i run the same if/else tests in the fragment shader to color points differently it melts:

enter image description here

vert block:

  gl_PointSize = uPointSize;

  if(int(vIndex) == uTrajectoryCount - 1){
    gl_PointSize = uPointSize * 2.0;
  } 
  else if(int(vIndex) == uTrajectoryCount - 2){
    gl_PointSize = uPointSize * 1.6;
  }
  else if(int(vIndex) == uTrajectoryCount - 3){
    gl_PointSize = uPointSize * 1.3;
  }
  else if( 
    abs(mod(vIndex,6.0)) < 0.01 
  ) {
    gl_PointSize = uPointSize * 2.0;
  }

frag block

  if(int(vIndex) == uTrajectoryCount - 1){
    gl_FragColor = vec4(1.,0.,0.,1.);
  } 
  else if(int(vIndex) == uTrajectoryCount - 2){
    gl_FragColor = vec4(0.,1.,0.,1.);
  }
  else if(int(vIndex) == uTrajectoryCount - 3){
    gl_FragColor = vec4(0.,0.,1.,1.);
  }
  else if( 
    abs(mod(vIndex,6.0)) < 0.01 
  ) {
    gl_FragColor = vec4(1.,1.,0.,1.);
  }

What could i look for that would make this "stable" i expect the bigger points not to flicker and stay yellow, and the last three to be r g b.


Solution

  • This appears to be a rounding issue related to floating point imprecision.Why you construct an int from a float the value is truncated. Round the value with floor(vIndex+0.5) or round(vIndex) instead of int(vIndex).