title: OpenGL - Why is my ray picking not working?
body: <p>I recently setup a project that uses OpenGL (Via the C# Wrapper Library OpenTK) which should do the following:</p>
  
  <ol>
  <li>Create a perspective projection camera - this camera will be used to make the user rotate,move etc. to look at my 3d models.</li>
  <li>Draw some 3d objects.</li>
  <li>Use 3d ray picking via unproject to let the user pick points/models in the 3d view.</li>
  </ol>
  
  <p>The last step (ray picking) looks ok on my 3d preview (GLControl) but returns invalid results like Vector3d (1,86460186949617; -45,4086124979203; -45,0387025610247). I have no idea why this is the case!</p>
  
  <p>I am using the following code to setup my viewport:</p>
  
  <pre><code>        this.RenderingControl.MakeCurrent();
  
          int w = RenderingControl.Width;
          int h = RenderingControl.Height;
  
          // Use all of the glControl painting area
          GL.Viewport(0, 0, w, h);
  
          GL.MatrixMode(MatrixMode.Projection);
          GL.LoadIdentity();
          Matrix4 p = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, w / (float)h, 0.1f, 64.0f);
          GL.LoadMatrix(ref p);
  </code></pre>
  
  <p>I use this method for unprojecting:</p>
  
  <pre><code>    /// &lt;summary&gt;
      /// This methods maps screen coordinates to viewport coordinates.
      /// &lt;/summary&gt;
      /// &lt;param name="screen"&gt;&lt;/param&gt;
      /// &lt;param name="view"&gt;&lt;/param&gt;
      /// &lt;param name="projection"&gt;&lt;/param&gt;
      /// &lt;param name="view_port"&gt;&lt;/param&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      private Vector3d UnProject(Vector3d screen, Matrix4d view, Matrix4d projection, int[] view_port)
      {
          Vector4d pos = new Vector4d();
  
          // Map x and y from window coordinates, map to range -1 to 1 
          pos.X = (screen.X - (float)view_port[0]) / (float)view_port[2] * 2.0f - 1.0f;
          pos.Y = (screen.Y - (float)view_port[1]) / (float)view_port[3] * 2.0f - 1.0f;
          pos.Z = screen.Z * 2.0f - 1.0f;
          pos.W = 1.0f;
  
          Vector4d pos2 = Vector4d.Transform(pos, Matrix4d.Invert(Matrix4d.Mult(view, projection)));
          Vector3d pos_out = new Vector3d(pos2.X, pos2.Y, pos2.Z);
  
          return pos_out / pos2.W;
      }
  </code></pre>
  
  <p>I use this code to position my camera (including rotation) and do the ray picking:</p>
  
  <pre><code>        // Clear buffers
          GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
          // Apply camera
          GL.MatrixMode(MatrixMode.Modelview);
  
          Matrix4d mv = Matrix4d.LookAt(EyePosition, Vector3d.Zero, Vector3d.UnitY);
          GL.LoadMatrix(ref mv);
  
          GL.Translate(0, 0, ZoomFactor);
  
          // Rotation animation
          if (RotationAnimationActive)
          {
              CameraRotX += 0.05f;
          }
  
          if (CameraRotX &gt;= 360)
          {
              CameraRotX = 0;
          }
  
          GL.Rotate(CameraRotX, Vector3.UnitY);
          GL.Rotate(CameraRotY, Vector3.UnitX);
  
          // Apply useful rotation
          GL.Rotate(50, 90, 30, 0f);
  
          // Draw Axes
          drawAxes();
  
          // Draw vertices of my 3d objects ...
  
          // Picking Test
          int x = MouseX;
          int y = MouseY;
  
          int[] viewport = new int[4];
          Matrix4d modelviewMatrix, projectionMatrix;
          GL.GetDouble(GetPName.ModelviewMatrix, out modelviewMatrix);
          GL.GetDouble(GetPName.ProjectionMatrix, out projectionMatrix);
          GL.GetInteger(GetPName.Viewport, viewport);
  
          // get depth of clicked pixel
          float[] t = new float[1];
          GL.ReadPixels(x, RenderingControl.Height - y, 1, 1, OpenTK.Graphics.OpenGL.PixelFormat.DepthComponent, PixelType.Float, t);
  
          var res = UnProject(new Vector3d(x, viewport[3] - y, t[0]), modelviewMatrix, projectionMatrix, viewport);
  
          GL.Begin(BeginMode.Lines);
          GL.Color3(Color.Yellow);
  
          GL.Vertex3(0, 0, 0);
  
          GL.Vertex3(res);
  
          Debug.WriteLine(res.ToString());
          GL.End();
  </code></pre>
  
  <p>I get the following result from my ray picker:</p>
  
  <ul>
  <li>Clicked Position = (1,86460186949617; -45,4086124979203;
  -45,0387025610247)</li>
  </ul>
  
  <p>This vector is shown as the yellow line on the attached screenshot.</p>
  
  <p>Why is the Y and Z Position not in the range -1/+1? Where do these values like -45 come from and why is the ray rendered correctly on the screen?</p>
  
  <p>If you have only a tip about what could be broken I would also appreciate your reply!</p>
  
  <p>Screenshot:</p>
  
  <p><a href="https://i.stack.imgur.com/RwgBm.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/RwgBm.png" alt="Screenshot"></a></p>