diff --git a/CHANGES.md b/CHANGES.md index b46bdc327cb0..fb1661dc78b0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,10 @@ Change Log ========== +### 1.2 - 2014-10-01 + +* Eliminated imagery artifacts at some zoom levels due to Mercator reprojection. + ### 1.1 - 2014-09-02 * Added a new imagery provider, `WebMapTileServiceImageryProvider`, for accessing tiles on a WMTS 1.0.0 server. diff --git a/Source/Shaders/Builtin/Functions/cosineAndSine.glsl b/Source/Shaders/Builtin/Functions/cosineAndSine.glsl new file mode 100644 index 000000000000..5821de1367a5 --- /dev/null +++ b/Source/Shaders/Builtin/Functions/cosineAndSine.glsl @@ -0,0 +1,211 @@ +/** + * @private + */ +vec2 cordic(float angle) +{ +// Scale the vector by the appropriate factor for the 24 iterations to follow. + vec2 vector = vec2(6.0725293500888267e-1, 0.0); +// Iteration 1 + float sense = (angle < 0.0) ? -1.0 : 1.0; + // float factor = sense * 1.0; // 2^-0 + mat2 rotation = mat2(1.0, sense, -sense, 1.0); + vector = rotation * vector; + angle -= sense * 7.8539816339744828e-1; // atan(2^-0) +// Iteration 2 + sense = (angle < 0.0) ? -1.0 : 1.0; + float factor = sense * 5.0e-1; // 2^-1 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 4.6364760900080609e-1; // atan(2^-1) +// Iteration 3 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 2.5e-1; // 2^-2 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 2.4497866312686414e-1; // atan(2^-2) +// Iteration 4 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 1.25e-1; // 2^-3 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 1.2435499454676144e-1; // atan(2^-3) +// Iteration 5 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 6.25e-2; // 2^-4 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 6.2418809995957350e-2; // atan(2^-4) +// Iteration 6 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 3.125e-2; // 2^-5 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 3.1239833430268277e-2; // atan(2^-5) +// Iteration 7 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 1.5625e-2; // 2^-6 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 1.5623728620476831e-2; // atan(2^-6) +// Iteration 8 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 7.8125e-3; // 2^-7 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 7.8123410601011111e-3; // atan(2^-7) +// Iteration 9 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 3.90625e-3; // 2^-8 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 3.9062301319669718e-3; // atan(2^-8) +// Iteration 10 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 1.953125e-3; // 2^-9 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 1.9531225164788188e-3; // atan(2^-9) +// Iteration 11 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 9.765625e-4; // 2^-10 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 9.7656218955931946e-4; // atan(2^-10) +// Iteration 12 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 4.8828125e-4; // 2^-11 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 4.8828121119489829e-4; // atan(2^-11) +// Iteration 13 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 2.44140625e-4; // 2^-12 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 2.4414062014936177e-4; // atan(2^-12) +// Iteration 14 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 1.220703125e-4; // 2^-13 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 1.2207031189367021e-4; // atan(2^-13) +// Iteration 15 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 6.103515625e-5; // 2^-14 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 6.1035156174208773e-5; // atan(2^-14) +// Iteration 16 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 3.0517578125e-5; // 2^-15 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 3.0517578115526096e-5; // atan(2^-15) +// Iteration 17 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 1.52587890625e-5; // 2^-16 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 1.5258789061315762e-5; // atan(2^-16) +// Iteration 18 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 7.62939453125e-6; // 2^-17 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 7.6293945311019700e-6; // atan(2^-17) +// Iteration 19 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 3.814697265625e-6; // 2^-18 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 3.8146972656064961e-6; // atan(2^-18) +// Iteration 20 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 1.9073486328125e-6; // 2^-19 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 1.9073486328101870e-6; // atan(2^-19) +// Iteration 21 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 9.5367431640625e-7; // 2^-20 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 9.5367431640596084e-7; // atan(2^-20) +// Iteration 22 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 4.76837158203125e-7; // 2^-21 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 4.7683715820308884e-7; // atan(2^-21) +// Iteration 23 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 2.384185791015625e-7; // 2^-22 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; + angle -= sense * 2.3841857910155797e-7; // atan(2^-22) +// Iteration 24 + sense = (angle < 0.0) ? -1.0 : 1.0; + factor = sense * 1.1920928955078125e-7; // 2^-23 + rotation[0][1] = factor; + rotation[1][0] = -factor; + vector = rotation * vector; +// angle -= sense * 1.1920928955078068e-7; // atan(2^-23) + + return vector; +} + +/** + * Computes the cosine and sine of the provided angle using the CORDIC algorithm. + * + * @name czm_cosineAndSine + * @glslFunction + * + * @param {float} angle The angle in radians. + * + * @returns {vec2} The resulting cosine of the angle (as the x coordinate) and sine of the angle (as the y coordinate). + * + * @example + * vec2 v = czm_cosineAndSine(czm_piOverSix); + * float cosine = v.x; + * float sine = v.y; + */ +vec2 czm_cosineAndSine(float angle) +{ + if (angle < -czm_piOverTwo || angle > czm_piOverTwo) + { + if (angle < 0.0) + { + return -cordic(angle + czm_pi); + } + else + { + return -cordic(angle - czm_pi); + } + } + else + { + return cordic(angle); + } +} \ No newline at end of file diff --git a/Source/Shaders/Builtin/Functions/latitudeToWebMercatorFraction.glsl b/Source/Shaders/Builtin/Functions/latitudeToWebMercatorFraction.glsl index 2a76d5689e61..c51f7e038f22 100644 --- a/Source/Shaders/Builtin/Functions/latitudeToWebMercatorFraction.glsl +++ b/Source/Shaders/Builtin/Functions/latitudeToWebMercatorFraction.glsl @@ -15,7 +15,7 @@ */ float czm_latitudeToWebMercatorFraction(float latitude, float southMercatorYLow, float southMercatorYHigh, float oneOverMercatorHeight) { - float sinLatitude = sin(latitude); + float sinLatitude = czm_cosineAndSine(latitude).y; float mercatorY = 0.5 * log((1.0 + sinLatitude) / (1.0 - sinLatitude)); // mercatorY - southMercatorY in simulated double precision. diff --git a/Specs/Renderer/BuiltinFunctionsSpec.js b/Specs/Renderer/BuiltinFunctionsSpec.js index ca25cd882ec0..0d9112954a30 100644 --- a/Specs/Renderer/BuiltinFunctionsSpec.js +++ b/Specs/Renderer/BuiltinFunctionsSpec.js @@ -274,4 +274,18 @@ defineSuite([ '}'; verifyDraw(fs); }); + + it('has czm_cosineAndSine in all 4 quadrants', function() { + var fs = + 'bool isBounded(float value, float min, float max) { ' + + ' return ((value < max) && (value > min)); ' + + '}' + + 'void main() { ' + + ' gl_FragColor = vec4(isBounded(czm_cosineAndSine(czm_piOverFour).x, 0.707106, 0.707107) && isBounded(czm_cosineAndSine(czm_piOverFour).y, 0.707106, 0.707107), ' + + ' isBounded(czm_cosineAndSine(czm_pi - czm_piOverFour).x, -0.707107, -0.707106) && isBounded(czm_cosineAndSine(czm_pi - czm_piOverFour).y, 0.707106, 0.707107), ' + + ' isBounded(czm_cosineAndSine(-czm_piOverFour).x, 0.707106, 0.707107) && isBounded(czm_cosineAndSine(-czm_piOverFour).y, -0.707107, -0.707106), ' + + ' isBounded(czm_cosineAndSine(-czm_pi + czm_piOverFour).x, -0.707107, -0.707106) && isBounded(czm_cosineAndSine(-czm_pi + czm_piOverFour).y, -0.707107, -0.707106)); ' + + '}'; + verifyDraw(fs); + }); }, 'WebGL'); \ No newline at end of file