mathopenglgeometrydirectxpicking

Implementing Ray Picking


I have a renderer using directx and openGL, and a 3d scene. The viewport and the window are of the same dimensions.

How do I implement picking given mouse coordinates x and y in a platform independent way?


Solution

  • If you can, do the picking on the CPU by calculating a ray from the eye through the mouse pointer and intersect it with your models.

    If this isn't an option I would go with some type of ID rendering. Assign each object you want to pick a unique color, render the objects with these colors and finally read out the color from the framebuffer under the mouse pointer.

    EDIT: If the question is how to construct the ray from the mouse coordinates you need the following: a projection matrix P and the camera transform C. If the coordinates of the mouse pointer is (x, y) and the size of the viewport is (width, height) one position in clip space along the ray is:

    mouse_clip = [
      float(x) * 2 / float(width) - 1,
      1 - float(y) * 2 / float(height),
      0,
      1]
    

    (Notice that I flipped the y-axis since often the origin of the mouse coordinates are in the upper left corner)

    The following is also true:

    mouse_clip = P * C * mouse_worldspace
    

    Which gives:

    mouse_worldspace = inverse(C) * inverse(P) * mouse_clip
    

    We now have:

    p = C.position(); //origin of camera in worldspace
    n = normalize(mouse_worldspace - p); //unit vector from p through mouse pos in worldspace