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 2 of 2

Thread: Compute fragment's ray direction (world's coordinates)

  1. #1
    Junior Member Newbie
    Join Date
    Feb 2009
    Location
    France, Bordeaux.
    Posts
    24

    Compute fragment's ray direction (world's coordinates)

    Hello !

    I try to make a sky shader using a fullscreen quad and an equirectangular texture (http://hugin.sourceforge.net/docs/ma...rojection.html ). So for each fragment I need the "raytracing direction" in (polar) spherical coordinates. I need to someone check if the following method seems good ....

    Send vertices :

    I send directly to the vertex shader the fullscreen quad's clip coordinates :

    Code :
      glBegin(GL_QUADS);
      glVertex2i(-1,-1);
      glVertex2i(1,-1);
      glVertex2i(1, 1);
      glVertex2i(-1,1);
      glEnd();

    The vertex shaders :

    I compute de ray direction for each (four) vertex using clip coordinates. First I make inverse projection and next inverse modelview but without translation.

    Code :
    /*****************/
    /* VERTEX SHADER */
    /*****************/
     
    varying vec3 rayDirection;
     
    void main()
    {
      vec4 reverseVec;
     
      /* inverse perspective projection */
      reverseVec = vec4(gl_Vertex.xy, 0.0, 1.0);
      reverseVec *= gl_ProjectionMatrixInverse;
     
      /* inverse modelview, without translation */
      reverseVec.w = 0.0;
      reverseVec *= gl_ModelViewMatrixInverse;
     
      /* send */
      rayDirection = vec3(reverseVec);
      gl_Position = vec4(gl_Vertex.xy, 0.0, 1.0);
     
    }

    I'am not sure that I set the z and w coordinates to good values ....

    The fragment shaders :

    The rayDirection vector is interpolated, so I get the ray direction in world's coordinates. So I just need to compute the spherical direction (s, t).

    Code :
    /*******************/
    /* FRAGMENT SHADER */
    /*******************/
     
    varying vec3 rayDirection;
     
    const float PI = 3.14159265358979323846264;
     
    void main()
    {
      vec3 normalizedDirection;
      vec2 polarDirection;
     
      /* T computation */
      normalizedDirection  = normalize(rayDirection);
      polarDirection.t = acos(normalizedDirection.y);
     
      /* S computation */
      rayDirection.y = 0.0;
      normalizedDirection  = normalize(rayDirection);
     
      if(normalizedDirection.x >= 0)
        polarDirection.s = acos(-normalizedDirection.z);
      else    
        polarDirection.s = acos(normalizedDirection.z) + PI;
     
      .....
     
    }

    It seems good ??
    Last edited by prunkdump; 09-17-2012 at 03:44 AM.

  2. #2
    Junior Member Newbie
    Join Date
    Feb 2009
    Location
    France, Bordeaux.
    Posts
    24
    I finally found the error !! The problem is that
    Code :
    reverseVec *= gl_ProjectionMatrixInverse;
    is equivalent to
    Code :
    reverseVec = reverseVec * gl_ProjectionMatrixInverse;
    but not to
    Code :
    reverseVec = gl_ProjectionMatrixInverse * reverseVec ;

    The shader now works ! It display an equirectangular panoramic image with :

    Opengl side :
    Code :
      glBegin(GL_QUADS);
     
      glVertex2i(-1, -1);
      glVertex2i(1, -1);
      glVertex2i(1, 1);
      glVertex2i(-1, 1);
     
      glEnd();

    Vertex shader :

    Code :
    /*****************/
    /* VERTEX SHADER */
    /*****************/
     
    varying vec3 rayDirection;
     
    void main()
    {
      vec4 reverseVec;
     
      /* inverse perspective projection */
      reverseVec = vec4(gl_Vertex.xy, 0.0, 1.0);
      reverseVec = gl_ProjectionMatrixInverse * reverseVec;
     
      /* inverse modelview, without translation */
      reverseVec.w = 0.0;
      reverseVec = gl_ModelViewMatrixInverse * reverseVec;
     
      /* send */
      rayDirection = vec3(reverseVec);
      gl_Position = vec4(gl_Vertex.xy, 0.0, 1.0);
    }


    Fragment shader :
    Code :
    /*******************/
    /* FRAGMENT SHADER */
    /*******************/
     
    uniform sampler2D equiTex;
    varying vec3 rayDirection;
     
    const float PI = 3.14159265358979323846264;
     
    void main()
    {
      vec3 normalizedDirection;
      vec2 polarDirection;
     
      /* T computation */
      normalizedDirection  = normalize(rayDirection);
      polarDirection.t = acos(normalizedDirection.y)/PI;
     
      /* S computation */
      rayDirection.y = 0.0;
      normalizedDirection  = normalize(rayDirection);
     
      if(normalizedDirection.x >= 0)
        polarDirection.s = acos(-normalizedDirection.z)/(2*PI);
      else    
        polarDirection.s = (acos(normalizedDirection.z) + PI)/(2*PI);
     
     
      /* color */
      gl_FragColor = texture2D(equiTex, polarDirection.st);
     
    }

Posting Permissions

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