Search code examples
openglglslinteltrigonometry

sin(x) only returns 4 different values for moderately large input on GLSL fragment shader, Intel HD4000


I have a simple OpenGL 3.3 fragment shader written in GLSL. Essentially, I'm evaluating sin(x) for moderately large x (between 10,000 and 2,000,000), something like this:

#version 330
out vec4 fColor;
void main() {
  fColor = vec4(sin(gl_FragCoord.x * gl_FragCoord.y));
}

It works fine on my NVidia graphics card, but on my Intel HD4000 the sine only returns four different values (+/- 1.0 and around +/- 0.3) above an input of about 10,000.

System: Windows 64bit, (Intel) driver version 15.28.20.64.3347.

My questions: is this a bug? or is it part of the vendors freedom to implement the sine this way?


Solution

  • This is a fairly common "bug" in fast trigonometric implementations -- it's common to use an approximation that works well for values in the range (-π, π), but poorly for large values.

    Since the GLSL spec does not require any particular level of accuracy or precision for these functions, it can be argued that long as the error in sin(x) is much less than |x| it is ok, but this level of error seems excessive.