Documentation
    Preparing search index...

    Function createPickRay

    • Writes the world-space picking ray through the normalized device coordinate (ndcX, ndcY) into outOrigin and outDirection (§71).

      NDC runs [-1, 1] on both axes with +Y up (§7a), so (-1, -1) is the bottom-left of the viewport and (0, 0) its centre; converting a pointer position in CSS pixels into NDC is the pointer source's job (§72), not this function's. The ray starts on the near plane and points into the scene, outDirection normalized, and it is correct for both projections: a perspective camera's rays fan out from the eye, an orthographic camera's are all parallel and start at different places on the near plane.

      const origin = new Vector3();
      const direction = new Vector3();
      createPickRay(camera, ndcX, ndcY, origin, direction);

      The camera's world matrix is resolved on demand (resolveWorldTransform), so a camera that has just moved — or that hangs off a spring arm which has just moved — produces a correct ray without the caller sequencing a resolve pass first. That walk is O(depth) and version-cached, so on the normal path (the frame already resolved the scene) it costs one comparison per ancestor.

      The camera's projection is taken as-is. inverseProjectionMatrix is written by Camera.updateProjectionMatrix, which §47/WP-3.1 make explicit: after changing a field like aspect on a resize, call it. Picking cannot do that itself without guessing the depthRange the renderer used.

      depthRange (plan D8) says which clip-space depth convention that projection was built with, and only affects where along the ray the origin lands — the near plane's NDC depth is -1 under "negative-one-to-one" and 0 under "zero-to-one". Passing the wrong one still yields the same ray line, so hits are unaffected and only reported distances shift by a constant; passing the right one makes them distances from the near plane. It defaults to "negative-one-to-one" to match updateProjectionMatrix, so WebGL 2 callers never pass it and WebGPU callers pass "zero-to-one" (decision, WP-3a.1 — a camera does not store its depth range, because it belongs to the renderer that draws the camera, and the same camera may feed two backends).

      Allocates nothing. A degenerate projection (a zero-sized view volume, near === far) leaves outDirection zero-length rather than NaN; see pick, which treats such a ray as hitting nothing.

      Parameters

      Returns void