123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- /**
- * Transforms a position from window to eye coordinates.
- * The transform from window to normalized device coordinates is done using components
- * of (@link czm_viewport} and {@link czm_viewportTransformation} instead of calculating
- * the inverse of <code>czm_viewportTransformation</code>. The transformation from
- * normalized device coordinates to clip coordinates is done using <code>fragmentCoordinate.w</code>,
- * which is expected to be the scalar used in the perspective divide. The transformation
- * from clip to eye coordinates is done using {@link czm_inverseProjection}.
- *
- * @name czm_windowToEyeCoordinates
- * @glslFunction
- *
- * @param {vec4} fragmentCoordinate The position in window coordinates to transform.
- *
- * @returns {vec4} The transformed position in eye coordinates.
- *
- * @see czm_modelToWindowCoordinates
- * @see czm_eyeToWindowCoordinates
- * @see czm_inverseProjection
- * @see czm_viewport
- * @see czm_viewportTransformation
- *
- * @example
- * vec4 positionEC = czm_windowToEyeCoordinates(gl_FragCoord);
- */
- vec4 czm_windowToEyeCoordinates(vec4 fragmentCoordinate)
- {
- // Reconstruct NDC coordinates
- float x = 2.0 * (fragmentCoordinate.x - czm_viewport.x) / czm_viewport.z - 1.0;
- float y = 2.0 * (fragmentCoordinate.y - czm_viewport.y) / czm_viewport.w - 1.0;
- float z = (fragmentCoordinate.z - czm_viewportTransformation[3][2]) / czm_viewportTransformation[2][2];
- vec4 q = vec4(x, y, z, 1.0);
- // Reverse the perspective division to obtain clip coordinates.
- q /= fragmentCoordinate.w;
- // Reverse the projection transformation to obtain eye coordinates.
- if (!(czm_inverseProjection == mat4(0.0))) // IE and Edge sometimes do something weird with != between mat4s
- {
- q = czm_inverseProjection * q;
- }
- else
- {
- float top = czm_frustumPlanes.x;
- float bottom = czm_frustumPlanes.y;
- float left = czm_frustumPlanes.z;
- float right = czm_frustumPlanes.w;
- float near = czm_currentFrustum.x;
- float far = czm_currentFrustum.y;
- q.x = (q.x * (right - left) + left + right) * 0.5;
- q.y = (q.y * (top - bottom) + bottom + top) * 0.5;
- q.z = (q.z * (near - far) - near - far) * 0.5;
- q.w = 1.0;
- }
- return q;
- }
- /**
- * Transforms a position given as window x/y and a depth or a log depth from window to eye coordinates.
- * This function produces more accurate results for window positions with log depth than
- * conventionally unpacking the log depth using czm_reverseLogDepth and using the standard version
- * of czm_windowToEyeCoordinates.
- *
- * @name czm_windowToEyeCoordinates
- * @glslFunction
- *
- * @param {vec2} fragmentCoordinateXY The XY position in window coordinates to transform.
- * @param {float} depthOrLogDepth A depth or log depth for the fragment.
- *
- * @see czm_modelToWindowCoordinates
- * @see czm_eyeToWindowCoordinates
- * @see czm_inverseProjection
- * @see czm_viewport
- * @see czm_viewportTransformation
- *
- * @returns {vec4} The transformed position in eye coordinates.
- */
- vec4 czm_windowToEyeCoordinates(vec2 fragmentCoordinateXY, float depthOrLogDepth)
- {
- // See reverseLogDepth.glsl. This is separate to re-use the pow.
- #ifdef LOG_DEPTH
- float near = czm_currentFrustum.x;
- float far = czm_currentFrustum.y;
- float log2Depth = depthOrLogDepth * czm_log2FarDepthFromNearPlusOne;
- float depthFromNear = pow(2.0, log2Depth) - 1.0;
- float depthFromCamera = depthFromNear + near;
- vec4 windowCoord = vec4(fragmentCoordinateXY, far * (1.0 - near / depthFromCamera) / (far - near), 1.0);
- vec4 eyeCoordinate = czm_windowToEyeCoordinates(windowCoord);
- eyeCoordinate.w = 1.0 / depthFromCamera; // Better precision
- return eyeCoordinate;
- #else
- vec4 windowCoord = vec4(fragmentCoordinateXY, depthOrLogDepth, 1.0);
- vec4 eyeCoordinate = czm_windowToEyeCoordinates(windowCoord);
- #endif
- return eyeCoordinate;
- }
|