Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 3 of 3

Thread: Square artifacts on Nvidia GPU's[screenshots, code, win32 demo]

  1. #1
    Newbie Newbie
    Join Date
    Apr 2014
    Posts
    2

    Square artifacts on Nvidia GPU's[screenshots, code, win32 demo]

    I have encountered a problem when GLSL shader generates incorrect image on following GPU's:
    GT 430
    GT 770
    GTX 570
    GTX 760

    But works normally on these:
    Intel HD Graphics 2500
    Intel HD 4000
    Intel 4400
    GTX 740M
    Radeon HD 6310M
    Radeon HD 8850

    Shader code is as follows:

    Code :
    bool PointProjectionInsideTriangle(vec3 p1, vec3 p2, vec3 p3, vec3 point)
    {
      vec3 n = cross((p2 - p1), (p3 - p1));
     
      vec3 n1 = cross((p2 - p1), n);
      vec3 n2 = cross((p3 - p2), n);
      vec3 n3 = cross((p1 - p3), n);
     
      float proj1 = dot((point - p2), n1);
      float proj2 = dot((point - p3), n2);
      float proj3 = dot((point - p1), n3);
     
      if(proj1 > 0.0)
        return false;
      if(proj2 > 0.0)
        return false;
      if(proj3 > 0.0)
        return false;
      return true;
    }
     
    struct Intersection
    {
      vec3 point;
      vec3 norm;
      bool valid;
    };
     
    Intersection GetRayTriangleIntersection(vec3 rayPoint, vec3 rayDir, vec3 p1, vec3 p2, vec3 p3)
    {
      vec3 norm = cross(p1 - p2, p1 - p3);
      norm /= (length(norm) + 1e-5);
     
      Intersection res;
      res.norm = norm;
      res.point = vec3(rayPoint.xy, 0.0);
      res.valid = PointProjectionInsideTriangle(p1, p2, p3, res.point);
      return res;
    }
     
    #define raysCount 15
    void main(void)
    {
      vec2 radius = (gl_FragCoord.xy / vec2(800.0, 600.0)) - vec2(0.5, 0.5);
     
      struct ColoredIntersection
      {
        Intersection geomInt;
        vec4 color;
      };
      ColoredIntersection ints[raysCount];
     
      vec3 randomPoints[raysCount];
      int i, j;
     
     
      for(int i = 0; i < raysCount; i++)
      {
        float theta = 0.5 * float(i);
        float phi = 3.1415 / 2.0;
        float r = 1.0;
        randomPoints[i] = vec3(r * sin(phi) * cos(theta),  r * sin(phi)*sin(theta), r * cos(phi));
     
        vec3 tangent = cross(vec3(0.0, 0.0, 1.0), randomPoints[i]);
        tangent /= (length(tangent) + 1e-5);
        vec3 trianglePoint1 = randomPoints[i] * 2.0 + tangent * 0.2;
        vec3 trianglePoint2 = randomPoints[i] * 2.0 - tangent * 0.2;
     
        ints[i].geomInt = GetRayTriangleIntersection(vec3(radius, -10.0), vec3(0.0, 0.0, 1.0), vec3(0.0, 0.0, 0.0), trianglePoint1, trianglePoint2);
        if(ints[i].geomInt.valid) //1
        {
          float c = length(ints[i].geomInt.point);
          ints[i].color = vec4(c, c, c, 1.0);
        }
      }
     
      for(i = 0; i < raysCount; i++) //2
      {
        for(j = i + 1; j < raysCount; j++)
        {
          if(ints[i].geomInt.point.z < ints[i].geomInt.point.z - 10.0)
          {
            gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
            return;
            ColoredIntersection tmp = ints[j];
            ints[j] = ints[i];
            ints[i] = tmp;
          }
        }
      }
     
      vec4 resultColor = vec4(0.0, 0.0, 0.0, 0.0);
      for(i = 0; i < raysCount + 0; i++)
      {
        if(ints[i].geomInt.valid)
          resultColor += ints[i].color;
      }
     
      gl_FragColor = resultColor;
    }
    The code is a simplified version of an actual shader, expected image is:

    http://img.owely.com/screens/131316/...ye.?1398554177

    But what I get is:

    http://img.owely.com/screens/131315/...xu.?1398553652
    (both are direct links to images, change to http)

    Random rotations of the code remove artifacts completely. For example if I change the line

    Code :
    if(ints[i].geomInt.valid) //1
    to

    Code :
    if(ints[i].geomInt.valid == true) //1
    or completely remove double cycle that does nothing (marked as 2) artifacts vanish. Even though these code rotations do not affect logic in any way, they somehow affect the artifacts.

    Code :
    if(ints[i].geomInt.point.z < ints[i].geomInt.point.z - 10.0)
    {
      gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
      return;
      ColoredIntersection tmp = ints[j];
      ints[j] = ints[i];
      ints[i] = tmp;
    }
    Can never be satisfied(left and right sides have index i, not i, j) and there's no NaN's. This code does absolutely nothing yet somehow produces artifacts.

    You can test the shader and demo on your own using this project(full MSVS 2010 project + sources + compiled binary and a shader, uses included SFML):

    https://dl.dropboxusercontent.com/u/...ShaderTest.zip (remove space in http)

    I use sfml in this test project, but that's 100% irrelevant because the actual project I've enountered this problem does not use this lib.

    What I want to know is why these artifacts appear and how to reliably avoid them.
    Last edited by Dark Photon; 04-28-2014 at 04:54 AM.

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,117
    I can't answer your question directly; but there a few steps I take with unusual problems in shaders


    1) use vec4 rather than vec3 in structures
    2) use explicit condition in if tests ( (a==true) rather than (a))
    3) simplify statements - avoid things like a = min(fnc(a),fnc(b)) + max(a,fn2(b))
    4) delete or comment out any nop code


    Since this problem is on nVidia you could use nSight to debug the shader in real-time

  3. #3
    Newbie Newbie
    Join Date
    Apr 2014
    Posts
    2
    I have actually worked around the problem by moving bool valid; to the beginning of the structure struct Intersecion. Looks like some compiler bug that can be avoided this way.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •