From df05de67438492c269c47825aa75cf5eadc1f6a0 Mon Sep 17 00:00:00 2001 From: Shehata Date: Mon, 14 Jan 2019 17:02:25 -0500 Subject: [PATCH 01/12] Load webp if extension is found --- Source/Scene/Model.js | 4 ++++ Source/Scene/ModelUtility.js | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index b82a52fda3c..2328bca4bc4 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -1650,6 +1650,10 @@ define([ var gltfImage = images[imageId]; var extras = gltfImage.extras; + if (defined(gltfImage.extensions) && defined(gltfImage.extensions.EXT_image_webp)) { + gltfImage = gltfImage.extensions.EXT_image_webp; + } + var bufferViewId = gltfImage.bufferView; var mimeType = gltfImage.mimeType; uri = gltfImage.uri; diff --git a/Source/Scene/ModelUtility.js b/Source/Scene/ModelUtility.js index b48b831061b..1b9eb0c7619 100644 --- a/Source/Scene/ModelUtility.js +++ b/Source/Scene/ModelUtility.js @@ -491,7 +491,8 @@ define([ 'KHR_techniques_webgl' : true, 'KHR_materials_unlit' : true, 'KHR_materials_pbrSpecularGlossiness' : true, - 'WEB3D_quantized_attributes' : true + 'WEB3D_quantized_attributes' : true, + 'EXT_image_webp' : true }; ModelUtility.checkSupportedExtensions = function(extensionsRequired) { From 52806ec4b380055ea521151eff49e5f0f32aeace Mon Sep 17 00:00:00 2001 From: Shehata Date: Tue, 15 Jan 2019 11:16:11 -0500 Subject: [PATCH 02/12] Fallback if WebP is not supported --- Source/Core/FeatureDetection.js | 37 ++- Source/Scene/Model.js | 9 +- Source/Scene/ModelUtility.js | 11 + .../Box-Textured-Webp/CesiumBoxWebp.gltf | 219 ++++++++++++++++++ 4 files changed, 273 insertions(+), 3 deletions(-) create mode 100644 Specs/Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf diff --git a/Source/Core/FeatureDetection.js b/Source/Core/FeatureDetection.js index 32b7e8ec735..368d76cafc3 100644 --- a/Source/Core/FeatureDetection.js +++ b/Source/Core/FeatureDetection.js @@ -1,11 +1,15 @@ define([ './defaultValue', './defined', - './Fullscreen' + './Fullscreen', + './RuntimeError', + '../ThirdParty/when' ], function( defaultValue, defined, - Fullscreen) { + Fullscreen, + RuntimeError, + when) { 'use strict'; /*global CanvasPixelArray*/ @@ -199,6 +203,34 @@ define([ return supportsImageRenderingPixelated() ? imageRenderingValueResult : undefined; } + var supportsWebpResult; + var supportsWebpPromise; + function supportsWebp() { + // From https://developers.google.com/speed/webp/faq#how_can_i_detect_browser_support_for_webp + if (!defined(supportsWebpPromise)) { + var webpDataUri = 'UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA'; + var image = new Image(); + supportsWebpPromise = when.defer(); + image.onload = function () { + supportsWebpResult = (image.width > 0) && (image.height > 0); + supportsWebpPromise.resolve(supportsWebpResult); + } + image.onerror = function () { + supportsWebpResult = false; + supportsWebpPromise.resolve(supportsWebpResult); + } + image.src = 'data:image/webp;base64,' + webpDataUri; + + return supportsWebpPromise; + } + + if (!defined(supportsWebpResult)) { + return supportsWebpPromise; + } + + return when(supportsWebpResult); + } + var typedArrayTypes = []; if (typeof ArrayBuffer !== 'undefined') { typedArrayTypes.push(Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array); @@ -235,6 +267,7 @@ define([ hardwareConcurrency : defaultValue(theNavigator.hardwareConcurrency, 3), supportsPointerEvents : supportsPointerEvents, supportsImageRenderingPixelated: supportsImageRenderingPixelated, + supportsWebp: supportsWebp, imageRenderingValue: imageRenderingValue, typedArrayTypes: typedArrayTypes }; diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 2328bca4bc4..e81ff9e524a 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -162,6 +162,13 @@ define([ return {}; } + // Cache the value of supportsWebp since it can take up to 300 ms to resolve. + var supportsWebp; + FeatureDetection.supportsWebp() + .then(function(result) { + supportsWebp = result; + }); + var boundingSphereCartesian3Scratch = new Cartesian3(); var ModelState = ModelUtility.ModelState; @@ -1650,7 +1657,7 @@ define([ var gltfImage = images[imageId]; var extras = gltfImage.extras; - if (defined(gltfImage.extensions) && defined(gltfImage.extensions.EXT_image_webp)) { + if (defined(gltfImage.extensions) && defined(gltfImage.extensions.EXT_image_webp) && supportsWebp) { gltfImage = gltfImage.extensions.EXT_image_webp; } diff --git a/Source/Scene/ModelUtility.js b/Source/Scene/ModelUtility.js index 1b9eb0c7619..39d53d79ac8 100644 --- a/Source/Scene/ModelUtility.js +++ b/Source/Scene/ModelUtility.js @@ -45,6 +45,13 @@ define([ */ var ModelUtility = {}; + // Cache the value of supportsWebp since it can take up to 300 ms to resolve. + var supportsWebp; + FeatureDetection.supportsWebp() + .then(function(result) { + supportsWebp = result; + }); + /** * Updates the model's forward axis if the model is not a 2.0 model. * @@ -501,6 +508,10 @@ define([ if (!ModelUtility.supportedExtensions[extension]) { throw new RuntimeError('Unsupported glTF Extension: ' + extension); } + + if (extension == 'EXT_image_webp' && supportsWebp === false) { + throw new RuntimeError('Loaded model requires WebP but browser does not support it.'); + } } } }; diff --git a/Specs/Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf b/Specs/Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf new file mode 100644 index 00000000000..054a4d35165 --- /dev/null +++ b/Specs/Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf @@ -0,0 +1,219 @@ +{ + "asset": { + "generator": "COLLADA2GLTF", + "version": "2.0" + }, + "extensionsUsed": [ + "EXT_image_webp" + ], + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ], + "nodes": [ + { + "children": [ + 1 + ], + "matrix": [ + 1, + 0, + 0, + 0, + 0, + 0, + -1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1 + ] + }, + { + "mesh": 0 + } + ], + "meshes": [ + { + "primitives": [ + { + "attributes": { + "NORMAL": 1, + "POSITION": 2, + "TEXCOORD_0": 3 + }, + "indices": 0, + "mode": 4, + "material": 0 + } + ], + "name": "Mesh" + } + ], + "accessors": [ + { + "bufferView": 0, + "byteOffset": 0, + "componentType": 5123, + "count": 36, + "max": [ + 23 + ], + "min": [ + 0 + ], + "type": "SCALAR" + }, + { + "bufferView": 1, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 288, + "componentType": 5126, + "count": 24, + "max": [ + 0.5, + 0.5, + 0.5 + ], + "min": [ + -0.5, + -0.5, + -0.5 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 6, + 1 + ], + "min": [ + 0, + 0 + ], + "type": "VEC2" + } + ], + "materials": [ + { + "pbrMetallicRoughness": { + "baseColorTexture": { + "index": 0, + "texCoord": 0 + }, + "metallicFactor": 0, + "baseColorFactor": [ + 1, + 1, + 1, + 1 + ], + "roughnessFactor": 1 + }, + "name": "Texture", + "emissiveFactor": [ + 0, + 0, + 0 + ], + "alphaMode": "OPAQUE", + "doubleSided": false + } + ], + "textures": [ + { + "sampler": 0, + "source": 0 + } + ], + "images": [ + { + "extensions": { + "EXT_image_webp": { + "name": "cesium logo", + "bufferView": 3, + "mimeType": "image/webp" + } + }, + "name": "cesium logo", + "bufferView": 4, + "mimeType": "image/png" + } + ], + "samplers": [ + { + "magFilter": 9729, + "minFilter": 9986, + "wrapS": 10497, + "wrapT": 10497 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteOffset": 0, + "byteLength": 72, + "target": 34963 + }, + { + "buffer": 0, + "byteOffset": 72, + "byteLength": 576, + "byteStride": 12, + "target": 34962 + }, + { + "buffer": 0, + "byteOffset": 648, + "byteLength": 192, + "byteStride": 8, + "target": 34962 + }, + { + "buffer": 0, + "byteOffset": 840, + "byteLength": 2466 + }, + { + "buffer": 0, + "byteOffset": 3308, + "byteLength": 5383 + } + ], + "buffers": [ + { + "name": "box-textured-separate", + "byteLength": 8692, + "uri": "data:application/octet-stream;base64,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" + } + ] +} From 2bfd649243bbbf461c60c3bba25d9ec71c0a7f20 Mon Sep 17 00:00:00 2001 From: Shehata Date: Tue, 15 Jan 2019 11:23:32 -0500 Subject: [PATCH 03/12] Fix lint --- Source/Core/FeatureDetection.js | 6 ++++-- Source/Scene/ModelUtility.js | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Source/Core/FeatureDetection.js b/Source/Core/FeatureDetection.js index 368d76cafc3..841719e09e3 100644 --- a/Source/Core/FeatureDetection.js +++ b/Source/Core/FeatureDetection.js @@ -214,11 +214,13 @@ define([ image.onload = function () { supportsWebpResult = (image.width > 0) && (image.height > 0); supportsWebpPromise.resolve(supportsWebpResult); - } + }; + image.onerror = function () { supportsWebpResult = false; supportsWebpPromise.resolve(supportsWebpResult); - } + }; + image.src = 'data:image/webp;base64,' + webpDataUri; return supportsWebpPromise; diff --git a/Source/Scene/ModelUtility.js b/Source/Scene/ModelUtility.js index 39d53d79ac8..99d073c8787 100644 --- a/Source/Scene/ModelUtility.js +++ b/Source/Scene/ModelUtility.js @@ -10,6 +10,7 @@ define([ '../Core/Matrix3', '../Core/Matrix4', '../Core/Quaternion', + '../Core/FeatureDetection', '../Core/RuntimeError', '../Core/WebGLConstants', '../Renderer/ShaderSource', @@ -30,6 +31,7 @@ define([ Matrix3, Matrix4, Quaternion, + FeatureDetection, RuntimeError, WebGLConstants, ShaderSource, @@ -509,7 +511,7 @@ define([ throw new RuntimeError('Unsupported glTF Extension: ' + extension); } - if (extension == 'EXT_image_webp' && supportsWebp === false) { + if (extension === 'EXT_image_webp' && supportsWebp === false) { throw new RuntimeError('Loaded model requires WebP but browser does not support it.'); } } From 98fa0ef677d157a2f533886d691648c4d35073a4 Mon Sep 17 00:00:00 2001 From: Shehata Date: Wed, 16 Jan 2019 09:45:56 -0500 Subject: [PATCH 04/12] Update webp extension for changing draft --- Source/Scene/Model.js | 9 +++++---- .../Box-Textured-Webp/CesiumBoxWebp.gltf | 20 +++++++++++-------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index e81ff9e524a..eb712fa95bb 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -1654,13 +1654,14 @@ define([ var uri; ForEach.texture(gltf, function(texture, id) { var imageId = texture.source; - var gltfImage = images[imageId]; - var extras = gltfImage.extras; - if (defined(gltfImage.extensions) && defined(gltfImage.extensions.EXT_image_webp) && supportsWebp) { - gltfImage = gltfImage.extensions.EXT_image_webp; + if (defined(texture.extensions) && defined(texture.extensions.EXT_image_webp) && supportsWebp) { + imageId = texture.extensions.EXT_image_webp.source; } + var gltfImage = images[imageId]; + var extras = gltfImage.extras; + var bufferViewId = gltfImage.bufferView; var mimeType = gltfImage.mimeType; uri = gltfImage.uri; diff --git a/Specs/Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf b/Specs/Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf index 054a4d35165..695e17c6b57 100644 --- a/Specs/Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf +++ b/Specs/Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf @@ -152,21 +152,25 @@ "textures": [ { "sampler": 0, - "source": 0 + "source": 0, + "extensions": { + "EXT_image_webp": { + "source": 1, + "sampler": 1 + } + } } ], "images": [ { - "extensions": { - "EXT_image_webp": { - "name": "cesium logo", - "bufferView": 3, - "mimeType": "image/webp" - } - }, "name": "cesium logo", "bufferView": 4, "mimeType": "image/png" + }, + { + "name": "cesium logo", + "bufferView": 3, + "mimeType": "image/webp" } ], "samplers": [ From 90755b0a262570e2c5641e95eabf884d092533d2 Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Tue, 22 Jan 2019 15:20:24 -0500 Subject: [PATCH 05/12] Add tests for webp --- Source/Core/FeatureDetection.js | 36 +++++++++++++----------------- Source/Scene/Model.js | 22 ++++++++++-------- Source/Scene/ModelUtility.js | 11 ++------- Specs/Core/FeatureDetectionSpec.js | 8 +++++++ Specs/Scene/ModelSpec.js | 26 +++++++++++++++++++++ 5 files changed, 64 insertions(+), 39 deletions(-) diff --git a/Source/Core/FeatureDetection.js b/Source/Core/FeatureDetection.js index 841719e09e3..1819b0cecc2 100644 --- a/Source/Core/FeatureDetection.js +++ b/Source/Core/FeatureDetection.js @@ -203,34 +203,28 @@ define([ return supportsImageRenderingPixelated() ? imageRenderingValueResult : undefined; } - var supportsWebpResult; var supportsWebpPromise; function supportsWebp() { // From https://developers.google.com/speed/webp/faq#how_can_i_detect_browser_support_for_webp - if (!defined(supportsWebpPromise)) { - var webpDataUri = 'UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA'; - var image = new Image(); - supportsWebpPromise = when.defer(); - image.onload = function () { - supportsWebpResult = (image.width > 0) && (image.height > 0); - supportsWebpPromise.resolve(supportsWebpResult); - }; - - image.onerror = function () { - supportsWebpResult = false; - supportsWebpPromise.resolve(supportsWebpResult); - }; - - image.src = 'data:image/webp;base64,' + webpDataUri; - + if (defined(supportsWebpPromise)) { return supportsWebpPromise; } - if (!defined(supportsWebpResult)) { - return supportsWebpPromise; - } + var webpDataUri = 'UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA'; + var image = new Image(); + supportsWebpPromise = when.defer(); + image.onload = function () { + var success = (image.width > 0) && (image.height > 0); + supportsWebpPromise.resolve(success); + }; + + image.onerror = function () { + supportsWebpPromise.resolve(false); + }; + + image.src = 'data:image/webp;base64,' + webpDataUri; - return when(supportsWebpResult); + return supportsWebpPromise; } var typedArrayTypes = []; diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index eb712fa95bb..18ce662f2a9 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -162,13 +162,6 @@ define([ return {}; } - // Cache the value of supportsWebp since it can take up to 300 ms to resolve. - var supportsWebp; - FeatureDetection.supportsWebp() - .then(function(result) { - supportsWebp = result; - }); - var boundingSphereCartesian3Scratch = new Cartesian3(); var ModelState = ModelUtility.ModelState; @@ -695,6 +688,13 @@ define([ this._useDefaultSpecularMaps = false; this._shouldRegenerateShaders = false; + this._supportsWebp = undefined; + + var that = this; + FeatureDetection.supportsWebp() + .then(function(result) { + that._supportsWebp = result; + }); } defineProperties(Model.prototype, { @@ -1655,7 +1655,7 @@ define([ ForEach.texture(gltf, function(texture, id) { var imageId = texture.source; - if (defined(texture.extensions) && defined(texture.extensions.EXT_image_webp) && supportsWebp) { + if (defined(texture.extensions) && defined(texture.extensions.EXT_image_webp) && model._supportsWebp) { imageId = texture.extensions.EXT_image_webp.source; } @@ -4299,6 +4299,10 @@ define([ return; } + if(!defined(this._supportsWebp)) { + return; + } + var context = frameState.context; this._defaultTexture = context.defaultTexture; @@ -4373,7 +4377,7 @@ define([ if (!loadResources.initialized) { frameState.brdfLutGenerator.update(frameState); - ModelUtility.checkSupportedExtensions(this.extensionsRequired); + ModelUtility.checkSupportedExtensions(this.extensionsRequired, this._supportsWebp); ModelUtility.updateForwardAxis(this); // glTF pipeline updates, not needed if loading from cache diff --git a/Source/Scene/ModelUtility.js b/Source/Scene/ModelUtility.js index 99d073c8787..0a37c0e1b4b 100644 --- a/Source/Scene/ModelUtility.js +++ b/Source/Scene/ModelUtility.js @@ -47,13 +47,6 @@ define([ */ var ModelUtility = {}; - // Cache the value of supportsWebp since it can take up to 300 ms to resolve. - var supportsWebp; - FeatureDetection.supportsWebp() - .then(function(result) { - supportsWebp = result; - }); - /** * Updates the model's forward axis if the model is not a 2.0 model. * @@ -504,14 +497,14 @@ define([ 'EXT_image_webp' : true }; - ModelUtility.checkSupportedExtensions = function(extensionsRequired) { + ModelUtility.checkSupportedExtensions = function(extensionsRequired, browserSupportsWebp) { for (var extension in extensionsRequired) { if (extensionsRequired.hasOwnProperty(extension)) { if (!ModelUtility.supportedExtensions[extension]) { throw new RuntimeError('Unsupported glTF Extension: ' + extension); } - if (extension === 'EXT_image_webp' && supportsWebp === false) { + if (extension === 'EXT_image_webp' && browserSupportsWebp === false) { throw new RuntimeError('Loaded model requires WebP but browser does not support it.'); } } diff --git a/Specs/Core/FeatureDetectionSpec.js b/Specs/Core/FeatureDetectionSpec.js index af0087a18f9..82604ae087a 100644 --- a/Specs/Core/FeatureDetectionSpec.js +++ b/Specs/Core/FeatureDetectionSpec.js @@ -115,4 +115,12 @@ defineSuite([ expect(FeatureDetection.imageRenderingValue()).not.toBeDefined(); } }); + + it('detects WebP support', function(done) { + FeatureDetection.supportsWebp() + .then(function(supportsWebp) { + expect(typeof supportsWebp).toEqual('boolean'); + done(); + }); + }); }); diff --git a/Specs/Scene/ModelSpec.js b/Specs/Scene/ModelSpec.js index 30972eef1f4..0049deefb3f 100644 --- a/Specs/Scene/ModelSpec.js +++ b/Specs/Scene/ModelSpec.js @@ -90,6 +90,7 @@ defineSuite([ var texturedBoxCRNEmbeddedUrl = './Data/Models/Box-Textured-CRN-Embedded/CesiumTexturedBoxTest.gltf'; var texturedBoxCustomUrl = './Data/Models/Box-Textured-Custom/CesiumTexturedBoxTest.gltf'; var texturedBoxKhrBinaryUrl = './Data/Models/Box-Textured-Binary/CesiumTexturedBoxTest.glb'; + var texturedBoxWebpUrl = './Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf'; var boxRtcUrl = './Data/Models/Box-RTC/Box.gltf'; var boxEcefUrl = './Data/Models/Box-ECEF/ecef.gltf'; var boxWithUnusedMaterial = './Data/Models/BoxWithUnusedMaterial/Box.gltf'; @@ -975,6 +976,21 @@ defineSuite([ }); }); + it('Throws for EXT_image_webp if browser does not support WebP', function() { + spyOn(FeatureDetection, 'supportsWebp').and.returnValue(when.resolve(false)); + return Resource.fetchJson(texturedBoxWebpUrl).then(function(gltf) { + gltf.extensionsRequired = ['EXT_image_webp']; + var model = primitives.add(new Model({ + gltf : gltf + })); + + expect(function() { + scene.renderForSpecs(); + }).toThrowRuntimeError(); + primitives.remove(model); + }); + }); + it('loads a glTF v0.8 model', function() { return loadModel(cesiumAir_0_8Url, { minimumPixelSize : 1 @@ -1186,6 +1202,16 @@ defineSuite([ }); }); + it('renders textured box with WebP texture', function() { + return loadModel(texturedBoxWebpUrl, { + incrementallyLoadTextures : false + }).then(function(m) { + verifyRender(m); + expect(Object.keys(m._rendererResources.textures).length).toBe(1); + primitives.remove(m); + }); + }); + /////////////////////////////////////////////////////////////////////////// it('loads cesiumAir', function() { From 6a38fbf29c7c59bb6270066f15860a2fda70fef9 Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Mon, 21 Jan 2019 12:24:16 -0500 Subject: [PATCH 06/12] Stabilize cameraMoveEvent spec --- Specs/Scene/SceneSpec.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Specs/Scene/SceneSpec.js b/Specs/Scene/SceneSpec.js index 3c3bdf37179..1b373fc20bd 100644 --- a/Specs/Scene/SceneSpec.js +++ b/Specs/Scene/SceneSpec.js @@ -1099,9 +1099,11 @@ defineSuite([ var spyListener = jasmine.createSpy('listener'); s.camera.moveEnd.addEventListener(spyListener); - s.cameraEventWaitTime = 0.0; + s.cameraEventWaitTime = -1.0; s.camera.moveLeft(); + // The first render will trigger the moveStart event. s.render(); + // The second will trigger the moveEnd. s.render(); expect(spyListener.calls.count()).toBe(1); From 91ec061202f60797b9743835b68f555c54420595 Mon Sep 17 00:00:00 2001 From: Shehata Date: Mon, 28 Jan 2019 12:04:24 -0500 Subject: [PATCH 07/12] Rename extension --- Source/Scene/Model.js | 4 ++-- Source/Scene/ModelUtility.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index b3eeb993090..a831fb2e872 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -1660,8 +1660,8 @@ define([ ForEach.texture(gltf, function(texture, id) { var imageId = texture.source; - if (defined(texture.extensions) && defined(texture.extensions.EXT_image_webp) && model._supportsWebp) { - imageId = texture.extensions.EXT_image_webp.source; + if (defined(texture.extensions) && defined(texture.extensions.EXT_texture_webp) && model._supportsWebp) { + imageId = texture.extensions.EXT_texture_webp.source; } var gltfImage = images[imageId]; diff --git a/Source/Scene/ModelUtility.js b/Source/Scene/ModelUtility.js index 0a37c0e1b4b..b29376b8f5b 100644 --- a/Source/Scene/ModelUtility.js +++ b/Source/Scene/ModelUtility.js @@ -494,7 +494,7 @@ define([ 'KHR_materials_unlit' : true, 'KHR_materials_pbrSpecularGlossiness' : true, 'WEB3D_quantized_attributes' : true, - 'EXT_image_webp' : true + 'EXT_texture_webp' : true }; ModelUtility.checkSupportedExtensions = function(extensionsRequired, browserSupportsWebp) { @@ -504,7 +504,7 @@ define([ throw new RuntimeError('Unsupported glTF Extension: ' + extension); } - if (extension === 'EXT_image_webp' && browserSupportsWebp === false) { + if (extension === 'EXT_texture_webp' && browserSupportsWebp === false) { throw new RuntimeError('Loaded model requires WebP but browser does not support it.'); } } From d3567800e93a064bed0b74f9d4279883e2d41b9c Mon Sep 17 00:00:00 2001 From: Shehata Date: Thu, 31 Jan 2019 09:35:00 -0500 Subject: [PATCH 08/12] Update extension name in tests --- Specs/Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf | 4 ++-- Specs/Scene/ModelSpec.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Specs/Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf b/Specs/Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf index 695e17c6b57..3c4a3bb6d74 100644 --- a/Specs/Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf +++ b/Specs/Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf @@ -4,7 +4,7 @@ "version": "2.0" }, "extensionsUsed": [ - "EXT_image_webp" + "EXT_texture_webp" ], "scene": 0, "scenes": [ @@ -154,7 +154,7 @@ "sampler": 0, "source": 0, "extensions": { - "EXT_image_webp": { + "EXT_texture_webp": { "source": 1, "sampler": 1 } diff --git a/Specs/Scene/ModelSpec.js b/Specs/Scene/ModelSpec.js index 0049deefb3f..bd45509c246 100644 --- a/Specs/Scene/ModelSpec.js +++ b/Specs/Scene/ModelSpec.js @@ -976,10 +976,10 @@ defineSuite([ }); }); - it('Throws for EXT_image_webp if browser does not support WebP', function() { + it('Throws for EXT_texture_webp if browser does not support WebP', function() { spyOn(FeatureDetection, 'supportsWebp').and.returnValue(when.resolve(false)); return Resource.fetchJson(texturedBoxWebpUrl).then(function(gltf) { - gltf.extensionsRequired = ['EXT_image_webp']; + gltf.extensionsRequired = ['EXT_texture_webp']; var model = primitives.add(new Model({ gltf : gltf })); From 2623df33b3f667a5eb9383a8588fc19093c94434 Mon Sep 17 00:00:00 2001 From: Shehata Date: Thu, 31 Jan 2019 09:56:15 -0500 Subject: [PATCH 09/12] Fix crash on Edge --- CHANGES.md | 1 + Source/Core/FeatureDetection.js | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 2120e43de5b..11e8ff85d8f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,7 @@ Change Log * Added `EllipsoidRhumbLine` class as a rhumb line counterpart to `EllipsoidGeodesic`. [#7484](https://github.com/AnalyticalGraphicsInc/cesium/pull/7484) * Added rhumb line support to `PolygonGeometry`, `PolygonOutlineGeometry`, `PolylineGeometry`, `GroundPolylineGeometry`, and `SimplePolylineGeometry`. [#7492](https://github.com/AnalyticalGraphicsInc/cesium/pull/7492) * Improved the performance of `QuantizedMeshTerrainData.interpolateHeight`. [#7508](https://github.com/AnalyticalGraphicsInc/cesium/pull/7508) +* Added support for glTF models with WebP textures using the `EXT_texture_webp` extension. [#7486](https://github.com/AnalyticalGraphicsInc/cesium/pull/7486) ##### Fixes :wrench: * Fixed 3D Tiles performance regression. [#7482](https://github.com/AnalyticalGraphicsInc/cesium/pull/7482) diff --git a/Source/Core/FeatureDetection.js b/Source/Core/FeatureDetection.js index 1819b0cecc2..0127de5b483 100644 --- a/Source/Core/FeatureDetection.js +++ b/Source/Core/FeatureDetection.js @@ -213,6 +213,13 @@ define([ var webpDataUri = 'UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA'; var image = new Image(); supportsWebpPromise = when.defer(); + + if (isEdge()) { + // Edge's WebP support with WebGL is incomplete. + // See bug report: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/19221241/ + supportsWebpPromise.resolve(false); + } + image.onload = function () { var success = (image.width > 0) && (image.height > 0); supportsWebpPromise.resolve(success); From 6c7fa041992c954077a5e4de133df8362d0619c0 Mon Sep 17 00:00:00 2001 From: Shehata Date: Thu, 31 Jan 2019 11:27:28 -0500 Subject: [PATCH 10/12] Clean up FeatureDetection webp --- Source/Core/FeatureDetection.js | 10 ++++------ Specs/Core/FeatureDetectionSpec.js | 8 ++------ 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Source/Core/FeatureDetection.js b/Source/Core/FeatureDetection.js index 0127de5b483..cc8a5c5ec29 100644 --- a/Source/Core/FeatureDetection.js +++ b/Source/Core/FeatureDetection.js @@ -207,19 +207,17 @@ define([ function supportsWebp() { // From https://developers.google.com/speed/webp/faq#how_can_i_detect_browser_support_for_webp if (defined(supportsWebpPromise)) { - return supportsWebpPromise; + return supportsWebpPromise.promise; } - var webpDataUri = 'UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA'; - var image = new Image(); supportsWebpPromise = when.defer(); - if (isEdge()) { // Edge's WebP support with WebGL is incomplete. // See bug report: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/19221241/ supportsWebpPromise.resolve(false); } + var image = new Image(); image.onload = function () { var success = (image.width > 0) && (image.height > 0); supportsWebpPromise.resolve(success); @@ -229,9 +227,9 @@ define([ supportsWebpPromise.resolve(false); }; - image.src = 'data:image/webp;base64,' + webpDataUri; + image.src = 'data:image/webp;base64,UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA'; - return supportsWebpPromise; + return supportsWebpPromise.promise; } var typedArrayTypes = []; diff --git a/Specs/Core/FeatureDetectionSpec.js b/Specs/Core/FeatureDetectionSpec.js index 82604ae087a..2b951409c3b 100644 --- a/Specs/Core/FeatureDetectionSpec.js +++ b/Specs/Core/FeatureDetectionSpec.js @@ -116,11 +116,7 @@ defineSuite([ } }); - it('detects WebP support', function(done) { - FeatureDetection.supportsWebp() - .then(function(supportsWebp) { - expect(typeof supportsWebp).toEqual('boolean'); - done(); - }); + it('detects WebP support', function() { + return FeatureDetection.supportsWebp(); }); }); From 8190a355179576fa2410568148612ac8af0d953c Mon Sep 17 00:00:00 2001 From: Shehata Date: Thu, 31 Jan 2019 11:32:00 -0500 Subject: [PATCH 11/12] Add supportsWebp check to ClassificationModel --- Source/Scene/ClassificationModel.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Source/Scene/ClassificationModel.js b/Source/Scene/ClassificationModel.js index 9e73ebaf0c2..389611b79f9 100644 --- a/Source/Scene/ClassificationModel.js +++ b/Source/Scene/ClassificationModel.js @@ -261,6 +261,12 @@ define([ this._rtcCenterEye = undefined; // in eye coordinates this._rtcCenter3D = undefined; // in world coordinates this._rtcCenter2D = undefined; // in projected world coordinates + + var that = this; + FeatureDetection.supportsWebp() + .then(function(result) { + that._supportsWebp = result; + }); } defineProperties(ClassificationModel.prototype, { @@ -958,6 +964,10 @@ define([ return; } + if(!defined(this._supportsWebp)) { + return; + } + if ((this._state === ModelState.NEEDS_LOAD) && defined(this.gltf)) { this._state = ModelState.LOADING; if (this._state !== ModelState.FAILED) { @@ -991,7 +1001,7 @@ define([ // Transition from LOADING -> LOADED once resources are downloaded and created. // Textures may continue to stream in while in the LOADED state. if (loadResources.pendingBufferLoads === 0) { - ModelUtility.checkSupportedExtensions(this.extensionsRequired); + ModelUtility.checkSupportedExtensions(this.extensionsRequired, this._supportsWebp); addBuffersToLoadResources(this); parseBufferViews(this); From bd8be76b7707ddb9c858ae39538c18064c218f98 Mon Sep 17 00:00:00 2001 From: Shehata Date: Thu, 31 Jan 2019 13:40:12 -0500 Subject: [PATCH 12/12] Style and cleanup --- Source/Scene/ClassificationModel.js | 4 +++- Source/Scene/Model.js | 2 +- Specs/Core/FeatureDetectionSpec.js | 5 ++++- Specs/Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf | 3 +-- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Source/Scene/ClassificationModel.js b/Source/Scene/ClassificationModel.js index 389611b79f9..b263bf127dc 100644 --- a/Source/Scene/ClassificationModel.js +++ b/Source/Scene/ClassificationModel.js @@ -262,6 +262,8 @@ define([ this._rtcCenter3D = undefined; // in world coordinates this._rtcCenter2D = undefined; // in projected world coordinates + this._supportsWebp = undefined; + var that = this; FeatureDetection.supportsWebp() .then(function(result) { @@ -964,7 +966,7 @@ define([ return; } - if(!defined(this._supportsWebp)) { + if (!defined(this._supportsWebp)) { return; } diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 4a6b7e058ed..bf14b760c9f 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -4308,7 +4308,7 @@ define([ return; } - if(!defined(this._supportsWebp)) { + if (!defined(this._supportsWebp)) { return; } diff --git a/Specs/Core/FeatureDetectionSpec.js b/Specs/Core/FeatureDetectionSpec.js index 2b951409c3b..6a80304e12c 100644 --- a/Specs/Core/FeatureDetectionSpec.js +++ b/Specs/Core/FeatureDetectionSpec.js @@ -117,6 +117,9 @@ defineSuite([ }); it('detects WebP support', function() { - return FeatureDetection.supportsWebp(); + return FeatureDetection.supportsWebp() + .then(function(supportsWebp) { + expect(typeof supportsWebp).toEqual('boolean'); + }); }); }); diff --git a/Specs/Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf b/Specs/Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf index 3c4a3bb6d74..c432abefdda 100644 --- a/Specs/Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf +++ b/Specs/Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf @@ -155,8 +155,7 @@ "source": 0, "extensions": { "EXT_texture_webp": { - "source": 1, - "sampler": 1 + "source": 1 } } }