windowToEyeCoordinates.glsl 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /**
  2. * Transforms a position from window to eye coordinates.
  3. * The transform from window to normalized device coordinates is done using components
  4. * of (@link czm_viewport} and {@link czm_viewportTransformation} instead of calculating
  5. * the inverse of <code>czm_viewportTransformation</code>. The transformation from
  6. * normalized device coordinates to clip coordinates is done using <code>positionWC.w</code>,
  7. * which is expected to be the scalar used in the perspective divide. The transformation
  8. * from clip to eye coordinates is done using {@link czm_inverseProjection}.
  9. *
  10. * @name czm_windowToEyeCoordinates
  11. * @glslFunction
  12. *
  13. * @param {vec4} fragmentCoordinate The position in window coordinates to transform.
  14. *
  15. * @returns {vec4} The transformed position in eye coordinates.
  16. *
  17. * @see czm_modelToWindowCoordinates
  18. * @see czm_eyeToWindowCoordinates
  19. * @see czm_inverseProjection
  20. * @see czm_viewport
  21. * @see czm_viewportTransformation
  22. *
  23. * @example
  24. * vec4 positionEC = czm_windowToEyeCoordinates(gl_FragCoord);
  25. */
  26. vec4 czm_windowToEyeCoordinates(vec4 fragmentCoordinate)
  27. {
  28. float x = 2.0 * (fragmentCoordinate.x - czm_viewport.x) / czm_viewport.z - 1.0;
  29. float y = 2.0 * (fragmentCoordinate.y - czm_viewport.y) / czm_viewport.w - 1.0;
  30. float z = (fragmentCoordinate.z - czm_viewportTransformation[3][2]) / czm_viewportTransformation[2][2];
  31. vec4 q = vec4(x, y, z, 1.0);
  32. q /= fragmentCoordinate.w;
  33. if (!(czm_inverseProjection == mat4(0.0))) // IE and Edge sometimes do something weird with != between mat4s
  34. {
  35. q = czm_inverseProjection * q;
  36. }
  37. else
  38. {
  39. float top = czm_frustumPlanes.x;
  40. float bottom = czm_frustumPlanes.y;
  41. float left = czm_frustumPlanes.z;
  42. float right = czm_frustumPlanes.w;
  43. float near = czm_currentFrustum.x;
  44. float far = czm_currentFrustum.y;
  45. q.x = (q.x * (right - left) + left + right) * 0.5;
  46. q.y = (q.y * (top - bottom) + bottom + top) * 0.5;
  47. q.z = (q.z * (near - far) - near - far) * 0.5;
  48. q.w = 1.0;
  49. }
  50. return q;
  51. }
  52. /**
  53. * Transforms a position given as window x/y and a depth or a log depth from window to eye coordinates.
  54. * This function produces more accurate results for window positions with log depth than
  55. * conventionally unpacking the log depth using czm_reverseLogDepth and using the standard version
  56. * of czm_windowToEyeCoordinates.
  57. *
  58. * @name czm_windowToEyeCoordinates
  59. * @glslFunction
  60. *
  61. * @param {vec2} fragmentCoordinateXY The XY position in window coordinates to transform.
  62. * @param {float} depthOrLogDepth A depth or log depth for the fragment.
  63. *
  64. * @see czm_modelToWindowCoordinates
  65. * @see czm_eyeToWindowCoordinates
  66. * @see czm_inverseProjection
  67. * @see czm_viewport
  68. * @see czm_viewportTransformation
  69. *
  70. * @returns {vec4} The transformed position in eye coordinates.
  71. */
  72. vec4 czm_windowToEyeCoordinates(vec2 fragmentCoordinateXY, float depthOrLogDepth)
  73. {
  74. // See reverseLogDepth.glsl. This is separate to re-use the pow.
  75. #ifdef LOG_DEPTH
  76. float near = czm_currentFrustum.x;
  77. float far = czm_currentFrustum.y;
  78. float unscaledDepth = pow(2.0, depthOrLogDepth * czm_log2FarPlusOne) - 1.0;
  79. vec4 windowCoord = vec4(fragmentCoordinateXY, far * (1.0 - near / unscaledDepth) / (far - near), 1.0);
  80. vec4 eyeCoordinate = czm_windowToEyeCoordinates(windowCoord);
  81. eyeCoordinate.w = 1.0 / unscaledDepth; // Better precision
  82. #else
  83. vec4 windowCoord = vec4(fragmentCoordinateXY, depthOrLogDepth, 1.0);
  84. vec4 eyeCoordinate = czm_windowToEyeCoordinates(windowCoord);
  85. #endif
  86. return eyeCoordinate;
  87. }