windowToEyeCoordinates.glsl 4.2 KB

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