diff --git a/CHANGES.md b/CHANGES.md
index cd1d736cbe81..721374cf53b6 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -3,8 +3,10 @@ Change Log
### 1.57 - 2019-05-01
-##### Fixes :wrench:
+##### Additions :tada:
+* Added support for the `KHR_texture_transform` glTF extension. [#7549](https://github.com/AnalyticalGraphicsInc/cesium/pull/7549)
+##### Fixes :wrench:
* Fixed an error where `clampToHeightMostDetailed` or `sampleHeightMostDetailed` would crash if entities were created when the promise resolved. [#7690](https://github.com/AnalyticalGraphicsInc/cesium/pull/7690)
### 1.56.1 - 2019-04-02
diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js
index 09ae462f5652..d32bdf8cfea5 100644
--- a/Source/Scene/Model.js
+++ b/Source/Scene/Model.js
@@ -252,6 +252,8 @@ define([
* {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit/README.md|KHR_materials_unlit}
*
* {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/README.md|KHR_materials_pbrSpecularGlossiness}
+ *
+ * {@link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md|KHR_texture_transform}
*
*
*
@@ -1296,6 +1298,8 @@ define([
* {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit/README.md|KHR_materials_unlit}
*
* {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/README.md|KHR_materials_pbrSpecularGlossiness}
+ *
+ * {@link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md|KHR_texture_transform}
*
*
*
@@ -2379,24 +2383,67 @@ define([
var rendererSamplers = model._rendererResources.samplers;
var sampler = rendererSamplers[texture.sampler];
- sampler = defaultValue(sampler, new Sampler({
- wrapS : TextureWrap.REPEAT,
- wrapT : TextureWrap.REPEAT
- }));
+ if (!defined(sampler)) {
+ sampler = new Sampler({
+ wrapS : TextureWrap.REPEAT,
+ wrapT : TextureWrap.REPEAT
+ });
+ }
+
+ var usesTextureTransform = false;
+ var materials = model.gltf.materials;
+ var materialsLength = materials.length;
+ for (var i = 0; i < materialsLength; ++i) {
+ var material = materials[i];
+ if (defined(material.extensions) && defined(material.extensions.KHR_techniques_webgl)) {
+ var values = material.extensions.KHR_techniques_webgl.values;
+ for (var valueName in values) {
+ if (values.hasOwnProperty(valueName) && valueName.indexOf('Texture') !== -1) {
+ var value = values[valueName];
+ if (value.index === gltfTexture.id && defined(value.extensions) && defined(value.extensions.KHR_texture_transform)) {
+ usesTextureTransform = true;
+ break;
+ }
+ }
+ }
+ }
+ if (usesTextureTransform) {
+ break;
+ }
+ }
+
+ var wrapS = sampler.wrapS;
+ var wrapT = sampler.wrapT;
+ var minFilter = sampler.minificationFilter;
+
+ if (usesTextureTransform && minFilter !== TextureMinificationFilter.LINEAR && minFilter !== TextureMinificationFilter.NEAREST) {
+ if (minFilter === TextureMinificationFilter.NEAREST_MIPMAP_NEAREST || minFilter === TextureMinificationFilter.NEAREST_MIPMAP_LINEAR) {
+ minFilter = TextureMinificationFilter.NEAREST;
+ } else {
+ minFilter = TextureMinificationFilter.LINEAR;
+ }
+
+ sampler = new Sampler({
+ wrapS : sampler.wrapS,
+ wrapT : sampler.wrapT,
+ textureMinificationFilter : minFilter,
+ textureMagnificationFilter : sampler.magnificationFilter
+ });
+ }
var internalFormat = gltfTexture.internalFormat;
var mipmap =
(!(defined(internalFormat) && PixelFormat.isCompressedFormat(internalFormat))) &&
- ((sampler.minificationFilter === TextureMinificationFilter.NEAREST_MIPMAP_NEAREST) ||
- (sampler.minificationFilter === TextureMinificationFilter.NEAREST_MIPMAP_LINEAR) ||
- (sampler.minificationFilter === TextureMinificationFilter.LINEAR_MIPMAP_NEAREST) ||
- (sampler.minificationFilter === TextureMinificationFilter.LINEAR_MIPMAP_LINEAR));
+ ((minFilter === TextureMinificationFilter.NEAREST_MIPMAP_NEAREST) ||
+ (minFilter === TextureMinificationFilter.NEAREST_MIPMAP_LINEAR) ||
+ (minFilter === TextureMinificationFilter.LINEAR_MIPMAP_NEAREST) ||
+ (minFilter === TextureMinificationFilter.LINEAR_MIPMAP_LINEAR));
var requiresNpot = mipmap ||
- (sampler.wrapS === TextureWrap.REPEAT) ||
- (sampler.wrapS === TextureWrap.MIRRORED_REPEAT) ||
- (sampler.wrapT === TextureWrap.REPEAT) ||
- (sampler.wrapT === TextureWrap.MIRRORED_REPEAT);
+ (wrapS === TextureWrap.REPEAT) ||
+ (wrapS === TextureWrap.MIRRORED_REPEAT) ||
+ (wrapT === TextureWrap.REPEAT) ||
+ (wrapT === TextureWrap.MIRRORED_REPEAT);
var tx;
var source = gltfTexture.image;
diff --git a/Source/Scene/ModelUtility.js b/Source/Scene/ModelUtility.js
index 391ce8ee8efd..53a517e95c67 100644
--- a/Source/Scene/ModelUtility.js
+++ b/Source/Scene/ModelUtility.js
@@ -493,6 +493,7 @@ define([
'KHR_techniques_webgl' : true,
'KHR_materials_unlit' : true,
'KHR_materials_pbrSpecularGlossiness' : true,
+ 'KHR_texture_transform' : true,
'WEB3D_quantized_attributes' : true,
'EXT_texture_webp' : true
};
diff --git a/Source/Scene/processPbrMaterials.js b/Source/Scene/processPbrMaterials.js
index ca2f77f6943f..d772999bc0ab 100644
--- a/Source/Scene/processPbrMaterials.js
+++ b/Source/Scene/processPbrMaterials.js
@@ -87,6 +87,43 @@ define([
defined(material.extensions.KHR_materials_pbrSpecularGlossiness);
}
+ function addTextureCoordinates(gltf, textureName, generatedMaterialValues, defaultTexCoord, result) {
+ var texCoord;
+ if (defined(generatedMaterialValues[textureName + 'Offset'])) {
+ var textureIndex = generatedMaterialValues[textureName].index;
+ var sampler = gltf.samplers[gltf.textures[textureIndex].sampler];
+
+ var repeatS = sampler.wrapS === WebGLConstants.REPEAT ? 'true' : 'false';
+ var repeatT = sampler.wrapT === WebGLConstants.REPEAT ? 'true' : 'false';
+
+ texCoord = textureName + 'Coord';
+ result.fragmentShaderMain += ' vec2 ' + texCoord + ' = computeTexCoord(' + defaultTexCoord + ', ' + textureName + 'Offset, ' + textureName + 'Rotation, ' + textureName + 'Scale, ' + repeatS + ', ' + repeatT + ');\n';
+ } else {
+ texCoord = defaultTexCoord;
+ }
+ return texCoord;
+ }
+
+ var DEFAULT_TEXTURE_OFFSET = [0.0, 0.0];
+ var DEFAULT_TEXTURE_ROTATION = [0.0];
+ var DEFAULT_TEXTURE_SCALE = [1.0, 1.0];
+
+ function handleKHRTextureTransform(parameterName, value, generatedMaterialValues) {
+ if (parameterName.indexOf('Texture') === -1 || !defined(value.extensions) || !defined(value.extensions.KHR_texture_transform)) {
+ return;
+ }
+
+ var uniformName = 'u_' + parameterName;
+ var extension = value.extensions.KHR_texture_transform;
+ generatedMaterialValues[uniformName + 'Offset'] = defaultValue(extension.offset, DEFAULT_TEXTURE_OFFSET);
+ generatedMaterialValues[uniformName + 'Rotation'] = defaultValue(extension.rotation, DEFAULT_TEXTURE_ROTATION);
+ generatedMaterialValues[uniformName + 'Scale'] = defaultValue(extension.scale, DEFAULT_TEXTURE_SCALE);
+
+ if (defined(value.texCoord) && defined(extension.texCoord)) {
+ generatedMaterialValues[uniformName].texCoord = extension.texCoord;
+ }
+ }
+
function generateTechnique(gltf, material, materialIndex, generatedMaterialValues, primitiveByMaterial, options) {
var addBatchIdToGeneratedShaders = defaultValue(options.addBatchIdToGeneratedShaders, false);
@@ -99,12 +136,15 @@ define([
var uniformName;
var parameterName;
+ var value;
var pbrMetallicRoughness = material.pbrMetallicRoughness;
if (defined(pbrMetallicRoughness) && !useSpecGloss) {
for (parameterName in pbrMetallicRoughness) {
if (pbrMetallicRoughness.hasOwnProperty(parameterName)) {
+ value = pbrMetallicRoughness[parameterName];
uniformName = 'u_' + parameterName;
- generatedMaterialValues[uniformName] = pbrMetallicRoughness[parameterName];
+ generatedMaterialValues[uniformName] = value;
+ handleKHRTextureTransform(parameterName, value, generatedMaterialValues);
}
}
}
@@ -113,16 +153,20 @@ define([
var pbrSpecularGlossiness = material.extensions.KHR_materials_pbrSpecularGlossiness;
for (parameterName in pbrSpecularGlossiness) {
if (pbrSpecularGlossiness.hasOwnProperty(parameterName)) {
+ value = pbrSpecularGlossiness[parameterName];
uniformName = 'u_' + parameterName;
- generatedMaterialValues[uniformName] = pbrSpecularGlossiness[parameterName];
+ generatedMaterialValues[uniformName] = value;
+ handleKHRTextureTransform(parameterName, value, generatedMaterialValues);
}
}
}
for (var additional in material) {
if (material.hasOwnProperty(additional) && ((additional.indexOf('Texture') >= 0) || additional.indexOf('Factor') >= 0)) {
+ value = material[additional];
uniformName = 'u_' + additional;
- generatedMaterialValues[uniformName] = material[additional];
+ generatedMaterialValues[uniformName] = value;
+ handleKHRTextureTransform(additional, value, generatedMaterialValues);
}
}
@@ -371,19 +415,42 @@ define([
fragmentShader += 'varying vec4 v_tangent;\n';
}
+ var fragmentShaderMain = '';
+
// Add texture coordinates if the material uses them
- var v_texcoord;
+ var v_texCoord;
+ var normalTexCoord;
+ var baseColorTexCoord;
+ var specularGlossinessTexCoord;
+ var diffuseTexCoord;
+ var metallicRoughnessTexCoord;
+ var occlusionTexCoord;
+ var emissiveTexCoord;
+
if (hasTexCoords) {
techniqueAttributes.a_texcoord_0 = {
semantic : 'TEXCOORD_0'
};
- v_texcoord = 'v_texcoord_0';
+ v_texCoord = 'v_texcoord_0';
vertexShader += 'attribute vec2 a_texcoord_0;\n';
- vertexShader += 'varying vec2 ' + v_texcoord + ';\n';
- vertexShaderMain += ' ' + v_texcoord + ' = a_texcoord_0;\n';
+ vertexShader += 'varying vec2 ' + v_texCoord + ';\n';
+ vertexShaderMain += ' ' + v_texCoord + ' = a_texcoord_0;\n';
+
+ fragmentShader += 'varying vec2 ' + v_texCoord + ';\n';
+
+ var result = {
+ fragmentShaderMain : fragmentShaderMain
+ };
+ normalTexCoord = addTextureCoordinates(gltf, 'u_normalTexture', generatedMaterialValues, v_texCoord, result);
+ baseColorTexCoord = addTextureCoordinates(gltf, 'u_baseColorTexture', generatedMaterialValues, v_texCoord, result);
+ specularGlossinessTexCoord = addTextureCoordinates(gltf, 'u_specularGlossinessTexture', generatedMaterialValues, v_texCoord, result);
+ diffuseTexCoord = addTextureCoordinates(gltf, 'u_diffuseTexture', generatedMaterialValues, v_texCoord, result);
+ metallicRoughnessTexCoord = addTextureCoordinates(gltf, 'u_metallicRoughnessTexture', generatedMaterialValues, v_texCoord, result);
+ occlusionTexCoord = addTextureCoordinates(gltf, 'u_occlusionTexture', generatedMaterialValues, v_texCoord, result);
+ emissiveTexCoord = addTextureCoordinates(gltf, 'u_emmissiveTexture', generatedMaterialValues, v_texCoord, result);
- fragmentShader += 'varying vec2 ' + v_texcoord + ';\n';
+ fragmentShaderMain = result.fragmentShaderMain;
}
// Add skinning information if available
@@ -488,6 +555,20 @@ define([
'#endif \n' +
'}\n\n';
+ fragmentShader +=
+ 'vec2 computeTexCoord(vec2 texCoords, vec2 offset, float rotation, vec2 scale, bool repeatS, bool repeatT) \n' +
+ '{\n' +
+ ' rotation = -rotation; \n' +
+ ' mat3 transform = mat3(\n' +
+ ' cos(rotation) * scale.x, sin(rotation) * scale.x, 0.0, \n' +
+ ' -sin(rotation) * scale.y, cos(rotation) * scale.y, 0.0, \n' +
+ ' offset.x, offset.y, 1.0); \n' +
+ ' vec2 transformedTexCoords = (transform * vec3(fract(texCoords), 1.0)).xy; \n' +
+ ' transformedTexCoords.x = repeatS ? fract(transformedTexCoords.x) : clamp(transformedTexCoords.x, 0.0, 1.0); \n' +
+ ' transformedTexCoords.y = repeatT ? fract(transformedTexCoords.y) : clamp(transformedTexCoords.y, 0.0, 1.0); \n' +
+ ' return transformedTexCoords; \n' +
+ '}\n\n';
+
fragmentShader += '#ifdef USE_IBL_LIGHTING \n';
fragmentShader += 'uniform vec2 gltf_iblFactor; \n';
fragmentShader += '#endif \n';
@@ -496,6 +577,7 @@ define([
fragmentShader += '#endif \n';
fragmentShader += 'void main(void) \n{\n';
+ fragmentShader += fragmentShaderMain;
// Add normal mapping to fragment shader
if (hasNormals) {
@@ -506,7 +588,7 @@ define([
fragmentShader += ' vec3 t = normalize(v_tangent.xyz);\n';
fragmentShader += ' vec3 b = normalize(cross(ng, t) * v_tangent.w);\n';
fragmentShader += ' mat3 tbn = mat3(t, b, ng);\n';
- fragmentShader += ' vec3 n = texture2D(u_normalTexture, ' + v_texcoord + ').rgb;\n';
+ fragmentShader += ' vec3 n = texture2D(u_normalTexture, ' + normalTexCoord + ').rgb;\n';
fragmentShader += ' n = normalize(tbn * (2.0 * n - 1.0));\n';
} else {
// Add standard derivatives extension
@@ -518,13 +600,13 @@ define([
fragmentShader += '#ifdef GL_OES_standard_derivatives\n';
fragmentShader += ' vec3 pos_dx = dFdx(v_positionEC);\n';
fragmentShader += ' vec3 pos_dy = dFdy(v_positionEC);\n';
- fragmentShader += ' vec3 tex_dx = dFdx(vec3(' + v_texcoord + ',0.0));\n';
- fragmentShader += ' vec3 tex_dy = dFdy(vec3(' + v_texcoord + ',0.0));\n';
+ fragmentShader += ' vec3 tex_dx = dFdx(vec3(' + normalTexCoord + ',0.0));\n';
+ fragmentShader += ' vec3 tex_dy = dFdy(vec3(' + normalTexCoord + ',0.0));\n';
fragmentShader += ' vec3 t = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t);\n';
fragmentShader += ' t = normalize(t - ng * dot(ng, t));\n';
fragmentShader += ' vec3 b = normalize(cross(ng, t));\n';
fragmentShader += ' mat3 tbn = mat3(t, b, ng);\n';
- fragmentShader += ' vec3 n = texture2D(u_normalTexture, ' + v_texcoord + ').rgb;\n';
+ fragmentShader += ' vec3 n = texture2D(u_normalTexture, ' + normalTexCoord + ').rgb;\n';
fragmentShader += ' n = normalize(tbn * (2.0 * n - 1.0));\n';
fragmentShader += '#else\n';
fragmentShader += ' vec3 n = ng;\n';
@@ -543,7 +625,7 @@ define([
// Add base color to fragment shader
if (defined(generatedMaterialValues.u_baseColorTexture)) {
- fragmentShader += ' vec4 baseColorWithAlpha = SRGBtoLINEAR4(texture2D(u_baseColorTexture, ' + v_texcoord + '));\n';
+ fragmentShader += ' vec4 baseColorWithAlpha = SRGBtoLINEAR4(texture2D(u_baseColorTexture, ' + baseColorTexCoord + '));\n';
if (defined(generatedMaterialValues.u_baseColorFactor)) {
fragmentShader += ' baseColorWithAlpha *= u_baseColorFactor;\n';
}
@@ -562,7 +644,7 @@ define([
if (hasNormals) {
if (useSpecGloss) {
if (defined(generatedMaterialValues.u_specularGlossinessTexture)) {
- fragmentShader += ' vec4 specularGlossiness = SRGBtoLINEAR4(texture2D(u_specularGlossinessTexture, ' + v_texcoord + '));\n';
+ fragmentShader += ' vec4 specularGlossiness = SRGBtoLINEAR4(texture2D(u_specularGlossinessTexture, ' + specularGlossinessTexCoord + '));\n';
fragmentShader += ' vec3 specular = specularGlossiness.rgb;\n';
fragmentShader += ' float glossiness = specularGlossiness.a;\n';
if (defined(generatedMaterialValues.u_specularFactor)) {
@@ -584,7 +666,7 @@ define([
}
}
if (defined(generatedMaterialValues.u_diffuseTexture)) {
- fragmentShader += ' vec4 diffuse = SRGBtoLINEAR4(texture2D(u_diffuseTexture, ' + v_texcoord + '));\n';
+ fragmentShader += ' vec4 diffuse = SRGBtoLINEAR4(texture2D(u_diffuseTexture, ' + diffuseTexCoord + '));\n';
if (defined(generatedMaterialValues.u_diffuseFactor)) {
fragmentShader += ' diffuse *= u_diffuseFactor;\n';
}
@@ -594,7 +676,7 @@ define([
fragmentShader += ' vec4 diffuse = vec4(1.0);\n';
}
} else if (defined(generatedMaterialValues.u_metallicRoughnessTexture)) {
- fragmentShader += ' vec3 metallicRoughness = texture2D(u_metallicRoughnessTexture, ' + v_texcoord + ').rgb;\n';
+ fragmentShader += ' vec3 metallicRoughness = texture2D(u_metallicRoughnessTexture, ' + metallicRoughnessTexCoord + ').rgb;\n';
fragmentShader += ' float metalness = clamp(metallicRoughness.b, 0.0, 1.0);\n';
fragmentShader += ' float roughness = clamp(metallicRoughness.g, 0.04, 1.0);\n';
if (defined(generatedMaterialValues.u_metallicFactor)) {
@@ -763,10 +845,10 @@ define([
// Ignore occlusion and emissive when unlit
if (!isUnlit) {
if (defined(generatedMaterialValues.u_occlusionTexture)) {
- fragmentShader += ' color *= texture2D(u_occlusionTexture, ' + v_texcoord + ').r;\n';
+ fragmentShader += ' color *= texture2D(u_occlusionTexture, ' + occlusionTexCoord + ').r;\n';
}
if (defined(generatedMaterialValues.u_emissiveTexture)) {
- fragmentShader += ' vec3 emissive = SRGBtoLINEAR3(texture2D(u_emissiveTexture, ' + v_texcoord + ').rgb);\n';
+ fragmentShader += ' vec3 emissive = SRGBtoLINEAR3(texture2D(u_emissiveTexture, ' + emissiveTexCoord + ').rgb);\n';
if (defined(generatedMaterialValues.u_emissiveFactor)) {
fragmentShader += ' emissive *= u_emissiveFactor;\n';
}
@@ -831,6 +913,16 @@ define([
}
function getPBRValueType(paramName) {
+ if (paramName.indexOf('Offset') !== -1) {
+ return WebGLConstants.FLOAT_VEC2;
+ } else if (paramName.indexOf('Rotation') !== -1) {
+ return WebGLConstants.FLOAT;
+ } else if (paramName.indexOf('Scale') !== -1) {
+ return WebGLConstants.FLOAT_VEC2;
+ } else if (paramName.indexOf('Texture') !== -1) {
+ return WebGLConstants.SAMPLER_2D;
+ }
+
switch (paramName) {
case 'u_baseColorFactor':
return WebGLConstants.FLOAT_VEC4;
@@ -838,16 +930,6 @@ define([
return WebGLConstants.FLOAT;
case 'u_roughnessFactor':
return WebGLConstants.FLOAT;
- case 'u_baseColorTexture':
- return WebGLConstants.SAMPLER_2D;
- case 'u_metallicRoughnessTexture':
- return WebGLConstants.SAMPLER_2D;
- case 'u_normalTexture':
- return WebGLConstants.SAMPLER_2D;
- case 'u_occlusionTexture':
- return WebGLConstants.SAMPLER_2D;
- case 'u_emissiveTexture':
- return WebGLConstants.SAMPLER_2D;
case 'u_emissiveFactor':
return WebGLConstants.FLOAT_VEC3;
// Specular Glossiness Types
@@ -857,10 +939,6 @@ define([
return WebGLConstants.FLOAT_VEC3;
case 'u_glossinessFactor':
return WebGLConstants.FLOAT;
- case 'u_diffuseTexture':
- return WebGLConstants.SAMPLER_2D;
- case 'u_specularGlossinessTexture':
- return WebGLConstants.SAMPLER_2D;
}
}
diff --git a/Specs/Data/Models/Box-Texture-Transform/CesiumTexturedBoxTest.gltf b/Specs/Data/Models/Box-Texture-Transform/CesiumTexturedBoxTest.gltf
new file mode 100644
index 000000000000..c16c964666b9
--- /dev/null
+++ b/Specs/Data/Models/Box-Texture-Transform/CesiumTexturedBoxTest.gltf
@@ -0,0 +1,188 @@
+{
+ "asset": {
+ "generator": "COLLADA2GLTF",
+ "version": "2.0"
+ },
+ "scenes": [
+ {
+ "nodes": [
+ 0
+ ]
+ }
+ ],
+ "scene": 0,
+ "nodes": [
+ {
+ "children": [
+ 1
+ ],
+ "matrix": [
+ 1.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ -1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0
+ ],
+ "name": "Z_UP"
+ },
+ {
+ "mesh": 0,
+ "name": "Mesh"
+ }
+ ],
+ "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.0,
+ 1.0,
+ 1.0
+ ],
+ "min": [
+ -1.0,
+ -1.0,
+ -1.0
+ ],
+ "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.0,
+ 1.0
+ ],
+ "min": [
+ 0.0,
+ 0.0
+ ],
+ "type": "VEC2"
+ }
+ ],
+ "materials": [
+ {
+ "pbrMetallicRoughness": {
+ "baseColorTexture": {
+ "index": 0,
+ "extensions": {
+ "KHR_texture_transform": {
+ "scale": [5.0, 3.0]
+ }
+ }
+ },
+ "metallicFactor": 0.0
+ },
+ "name": "Texture"
+ }
+ ],
+ "textures": [
+ {
+ "sampler": 0,
+ "source": 0
+ }
+ ],
+ "images": [
+ {
+ "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANMAAADTCAIAAACUZbGOAAAACXBIWXMAAAsTAAALEwEAmpwYAAA4JmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMwMTQgNzkuMTU2Nzk3LCAyMDE0LzA4LzIwLTA5OjUzOjAyICAgICAgICAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNCAoV2luZG93cyk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTUtMDMtMDJUMDg6NDc6NTQtMDU6MDA8L3htcDpDcmVhdGVEYXRlPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxNS0wMy0wMlQwODo1MTo1Mi0wNTowMDwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6TWV0YWRhdGFEYXRlPjIwMTUtMDMtMDJUMDg6NTE6NTItMDU6MDA8L3htcDpNZXRhZGF0YURhdGU+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6ZmFhN2VhN2MtN2ZlZS0yZTQ3LWExNmUtMGVjNTc2YTkzZmY2PC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD54bXAuZGlkOmZhYTdlYTdjLTdmZWUtMmU0Ny1hMTZlLTBlYzU3NmE5M2ZmNjwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOmZhYTdlYTdjLTdmZWUtMmU0Ny1hMTZlLTBlYzU3NmE5M2ZmNjwveG1wTU06T3JpZ2luYWxEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06SGlzdG9yeT4KICAgICAgICAgICAgPHJkZjpTZXE+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmNyZWF0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDpmYWE3ZWE3Yy03ZmVlLTJlNDctYTE2ZS0wZWM1NzZhOTNmZjY8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTUtMDMtMDJUMDg6NDc6NTQtMDU6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE0IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAgPC94bXBNTTpIaXN0b3J5PgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj43MjAwMDAvMTAwMDA8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOllSZXNvbHV0aW9uPjcyMDAwMC8xMDAwMDwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT42NTUzNTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+MjExPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjIxMTwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAg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"
+ }
+ ],
+ "samplers": [
+ {
+ "magFilter": 9729,
+ "minFilter": 9986,
+ "wrapS": 10497,
+ "wrapT": 10497
+ }
+ ],
+ "bufferViews": [
+ {
+ "buffer": 0,
+ "byteOffset": 768,
+ "byteLength": 72,
+ "target": 34963
+ },
+ {
+ "buffer": 0,
+ "byteOffset": 0,
+ "byteLength": 576,
+ "byteStride": 12,
+ "target": 34962
+ },
+ {
+ "buffer": 0,
+ "byteOffset": 576,
+ "byteLength": 192,
+ "byteStride": 8,
+ "target": 34962
+ }
+ ],
+ "buffers": [
+ {
+ "byteLength": 840,
+ "uri": "data:application/octet-stream;base64,AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAPwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAPwAAAL8AAAA/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAPwAAAD8AAAC/AADAQAAAAAAAAKBAAAAAAAAAwED+/38/AACgQP7/fz8AAIBAAAAAAAAAoEAAAAAAAACAQAAAgD8AAKBAAACAPwAAAEAAAAAAAACAPwAAAAAAAABAAACAPwAAgD8AAIA/AABAQAAAAAAAAIBAAAAAAAAAQEAAAIA/AACAQAAAgD8AAEBAAAAAAAAAAEAAAAAAAABAQAAAgD8AAABAAACAPwAAAAAAAAAAAAAAAP7/fz8AAIA/AAAAAAAAgD/+/38/AAABAAIAAwACAAEABAAFAAYABwAGAAUACAAJAAoACwAKAAkADAANAA4ADwAOAA0AEAARABIAEwASABEAFAAVABYAFwAWABUA"
+ }
+ ]
+}
diff --git a/Specs/Scene/ModelSpec.js b/Specs/Scene/ModelSpec.js
index 890c5c3db4ea..7beafda1a432 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 texturedBoxTextureTransformUrl = './Data/Models/Box-Texture-Transform/CesiumTexturedBoxTest.gltf';
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';
@@ -1208,6 +1209,16 @@ defineSuite([
});
});
+ it('renders textured box with KHR_texture_transform extension', function() {
+ return loadModel(texturedBoxTextureTransformUrl, {
+ incrementallyLoadTextures : false
+ }).then(function(m) {
+ verifyRender(m);
+ expect(Object.keys(m._rendererResources.textures).length).toBe(1);
+ primitives.remove(m);
+ });
+ });
+
it('renders textured box with WebP texture', function() {
if (!FeatureDetection.supportsWebP()) {
return;