From 951ab07daae4db0373029be47161822e42b9ff62 Mon Sep 17 00:00:00 2001 From: Don McCurdy Date: Thu, 22 Feb 2018 11:25:26 -0800 Subject: [PATCH 1/6] GLTFLoader: Implement KHR_texture_transform. --- docs/examples/loaders/GLTFLoader.html | 22 +++++-- examples/js/loaders/GLTFLoader.js | 95 +++++++++++++++++++++------ 2 files changed, 91 insertions(+), 26 deletions(-) diff --git a/docs/examples/loaders/GLTFLoader.html b/docs/examples/loaders/GLTFLoader.html index 179931b2887889..7bc190a063b30f 100644 --- a/docs/examples/loaders/GLTFLoader.html +++ b/docs/examples/loaders/GLTFLoader.html @@ -32,8 +32,18 @@

Extensions

  • KHR_materials_pbrSpecularGlossiness
  • KHR_materials_unlit
  • KHR_lights_punctual (experimental)
  • +
  • KHR_texture_transform*
  • +
  • MSFT_texture_dds
  • +

    + *UV transforms are supported, with several key limitations in comparison to the + glTF specification. A transform is applied to all textures using that UV set on the current + material, and no more than one transform may be used per material. Each transform will result + in an additional GPU texture upload. See #[link:https://github.com/mrdoob/three.js/pull/13831 13831] + and #[link:https://github.com/mrdoob/three.js/issues/12788 12788]. +

    +

    Example

    @@ -85,30 +95,30 @@

    Browser compatibility

    providing a Promise replacement.

    Textures

    - +

    Textures containing color information (.map, .emissiveMap, and .specularMap) always use sRGB colorspace in glTF, while vertex colors and material properties (.color, .emissive, .specular) use linear colorspace. In a typical rendering workflow, textures are converted to linear colorspace by the renderer, lighting calculations are made, then final output is converted back to sRGB and displayed on screen. Unless you need post-processing in linear colorspace, always configure [page:WebGLRenderer] as follows when using glTF:

    - + renderer.gammaOutput = true; renderer.gammaFactor = 2.2; - +

    GLTFLoader will automatically configure textures referenced from a .gltf or .glb file correctly, with the assumption that the renderer is set up as shown above. When loading textures externally (e.g., using [page:TextureLoader]) and applying them to a glTF model, colorspace and orientation must be given:

    - + // If texture is used for color information, set colorspace. texture.encoding = THREE.sRGBEncoding; // UVs use the convention that (0, 0) corresponds to the upper left corner of a texture. texture.flipY = false; - - +
    +

    Custom extensions

    diff --git a/examples/js/loaders/GLTFLoader.js b/examples/js/loaders/GLTFLoader.js index e6ee5c78d2ddf2..56c9f650e34edd 100644 --- a/examples/js/loaders/GLTFLoader.js +++ b/examples/js/loaders/GLTFLoader.js @@ -181,7 +181,7 @@ THREE.GLTFLoader = ( function () { break; case EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: - extensions[ extensionName ] = new GLTFMaterialsPbrSpecularGlossinessExtension(); + extensions[ extensionName ] = new GLTFMaterialsPbrSpecularGlossinessExtension( json ); break; case EXTENSIONS.KHR_DRACO_MESH_COMPRESSION: @@ -189,7 +189,11 @@ THREE.GLTFLoader = ( function () { break; case EXTENSIONS.MSFT_TEXTURE_DDS: - extensions[ EXTENSIONS.MSFT_TEXTURE_DDS ] = new GLTFTextureDDSExtension(); + extensions[ EXTENSIONS.MSFT_TEXTURE_DDS ] = new GLTFTextureDDSExtension( json ); + break; + + case EXTENSIONS.KHR_TEXTURE_TRANSFORM: + extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] = new GLTFTextureTransformExtension( json ); break; default: @@ -282,6 +286,7 @@ THREE.GLTFLoader = ( function () { KHR_LIGHTS_PUNCTUAL: 'KHR_lights_punctual', KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: 'KHR_materials_pbrSpecularGlossiness', KHR_MATERIALS_UNLIT: 'KHR_materials_unlit', + KHR_TEXTURE_TRANSFORM: 'KHR_texture_transform', MSFT_TEXTURE_DDS: 'MSFT_texture_dds' }; @@ -409,7 +414,7 @@ THREE.GLTFLoader = ( function () { if ( metallicRoughness.baseColorTexture !== undefined ) { - pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture.index ) ); + pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture ) ); } @@ -563,6 +568,49 @@ THREE.GLTFLoader = ( function () { }; + /** + * Texture Transform Extension + * + * Specification: + */ + function GLTFTextureTransformExtension( json ) { + + this.name = EXTENSIONS.KHR_TEXTURE_TRANSFORM; + + } + + GLTFTextureTransformExtension.prototype.extendTexture = function ( texture, mapDef ) { + + var transform = mapDef.extensions !== undefined ? mapDef.extensions[ this.name ] : undefined; + + if ( transform === undefined ) return texture; + + texture = texture.clone(); + + if ( transform.offset !== undefined ) { + + texture.offset.fromArray( transform.offset ); + + } + + if ( transform.rotation !== undefined ) { + + texture.rotation = transform.rotation; + + } + + if ( transform.scale !== undefined ) { + + texture.repeat.fromArray( transform.scale ); + + } + + texture.needsUpdate = true; + + return texture; + + }; + /** * Specular-Glossiness Extension * @@ -692,7 +740,7 @@ THREE.GLTFLoader = ( function () { if ( pbrSpecularGlossiness.diffuseTexture !== undefined ) { - pending.push( parser.assignTexture( params, 'map', pbrSpecularGlossiness.diffuseTexture.index ) ); + pending.push( parser.assignTexture( params, 'map', pbrSpecularGlossiness.diffuseTexture ) ); } @@ -708,9 +756,9 @@ THREE.GLTFLoader = ( function () { if ( pbrSpecularGlossiness.specularGlossinessTexture !== undefined ) { - var specGlossIndex = pbrSpecularGlossiness.specularGlossinessTexture.index; - pending.push( parser.assignTexture( params, 'glossinessMap', specGlossIndex ) ); - pending.push( parser.assignTexture( params, 'specularMap', specGlossIndex ) ); + var specGlossMapDef = pbrSpecularGlossiness.specularGlossinessTexture; + pending.push( parser.assignTexture( params, 'glossinessMap', specGlossMapDef ) ); + pending.push( parser.assignTexture( params, 'specularMap', specGlossMapDef ) ); } @@ -2146,15 +2194,23 @@ THREE.GLTFLoader = ( function () { /** * Asynchronously assigns a texture to the given material parameters. * @param {Object} materialParams - * @param {string} textureName - * @param {number} textureIndex - * @return {Promise} + * @param {string} mapName + * @param {Object} mapDef + * @return {Promise} */ - GLTFParser.prototype.assignTexture = function ( materialParams, textureName, textureIndex ) { + GLTFParser.prototype.assignTexture = function ( materialParams, mapName, mapDef ) { + + var parser = this; - return this.getDependency( 'texture', textureIndex ).then( function ( texture ) { + return this.getDependency( 'texture', mapDef.index ).then( function ( texture ) { + + if ( parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] ) { + + texture = parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ].extendTexture( texture, mapDef ); + + } - materialParams[ textureName ] = texture; + materialParams[ mapName ] = texture; } ); @@ -2213,7 +2269,7 @@ THREE.GLTFLoader = ( function () { if ( metallicRoughness.baseColorTexture !== undefined ) { - pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture.index ) ); + pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture ) ); } @@ -2222,9 +2278,8 @@ THREE.GLTFLoader = ( function () { if ( metallicRoughness.metallicRoughnessTexture !== undefined ) { - var textureIndex = metallicRoughness.metallicRoughnessTexture.index; - pending.push( parser.assignTexture( materialParams, 'metalnessMap', textureIndex ) ); - pending.push( parser.assignTexture( materialParams, 'roughnessMap', textureIndex ) ); + pending.push( parser.assignTexture( materialParams, 'metalnessMap', metallicRoughness.metallicRoughnessTexture ) ); + pending.push( parser.assignTexture( materialParams, 'roughnessMap', metallicRoughness.metallicRoughnessTexture ) ); } @@ -2256,7 +2311,7 @@ THREE.GLTFLoader = ( function () { if ( materialDef.normalTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) { - pending.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture.index ) ); + pending.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture ) ); materialParams.normalScale = new THREE.Vector2( 1, 1 ); @@ -2270,7 +2325,7 @@ THREE.GLTFLoader = ( function () { if ( materialDef.occlusionTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) { - pending.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture.index ) ); + pending.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture ) ); if ( materialDef.occlusionTexture.strength !== undefined ) { @@ -2288,7 +2343,7 @@ THREE.GLTFLoader = ( function () { if ( materialDef.emissiveTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) { - pending.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture.index ) ); + pending.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture ) ); } From c747fcb6a4681da68de2479d76cb927316b232a9 Mon Sep 17 00:00:00 2001 From: Don McCurdy Date: Sat, 21 Jul 2018 15:57:40 -0700 Subject: [PATCH 2/6] GLTFLoader: Docs cleanup. --- docs/examples/loaders/GLTFLoader.html | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/examples/loaders/GLTFLoader.html b/docs/examples/loaders/GLTFLoader.html index 7bc190a063b30f..e5d378f3d53255 100644 --- a/docs/examples/loaders/GLTFLoader.html +++ b/docs/examples/loaders/GLTFLoader.html @@ -39,9 +39,10 @@

    Extensions

    *UV transforms are supported, with several key limitations in comparison to the glTF specification. A transform is applied to all textures using that UV set on the current - material, and no more than one transform may be used per material. Each transform will result - in an additional GPU texture upload. See #[link:https://github.com/mrdoob/three.js/pull/13831 13831] - and #[link:https://github.com/mrdoob/three.js/issues/12788 12788]. + material, and no more than one transform may be used per material. Each use of a texture with + a unique transform will result in an additional GPU texture upload. See + #[link:https://github.com/mrdoob/three.js/pull/13831 13831] and + #[link:https://github.com/mrdoob/three.js/issues/12788 12788].

    Example

    From 73160feba1684a24e9753bbbb05cd23108980c8b Mon Sep 17 00:00:00 2001 From: Don McCurdy Date: Tue, 7 Aug 2018 15:25:21 -0700 Subject: [PATCH 3/6] GLTFLoader: Warn on unsupported texCoord override. --- examples/js/loaders/GLTFLoader.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/js/loaders/GLTFLoader.js b/examples/js/loaders/GLTFLoader.js index 56c9f650e34edd..0ba20fa4f4238c 100644 --- a/examples/js/loaders/GLTFLoader.js +++ b/examples/js/loaders/GLTFLoader.js @@ -605,6 +605,12 @@ THREE.GLTFLoader = ( function () { } + if ( transform.texCoord !== undefined ) { + + console.warn( 'THREE.GLTFLoader: Custom UV sets in "' + this.name + '" extension not yet supported.' ); + + } + texture.needsUpdate = true; return texture; From d3e31910050da4b27dd015c53635a0216407b43e Mon Sep 17 00:00:00 2001 From: Don McCurdy Date: Mon, 20 Aug 2018 22:06:50 -0700 Subject: [PATCH 4/6] GLTFLoader: Clean up. --- examples/js/loaders/GLTFLoader.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/examples/js/loaders/GLTFLoader.js b/examples/js/loaders/GLTFLoader.js index 0ba20fa4f4238c..a684abef50f9da 100644 --- a/examples/js/loaders/GLTFLoader.js +++ b/examples/js/loaders/GLTFLoader.js @@ -579,11 +579,7 @@ THREE.GLTFLoader = ( function () { } - GLTFTextureTransformExtension.prototype.extendTexture = function ( texture, mapDef ) { - - var transform = mapDef.extensions !== undefined ? mapDef.extensions[ this.name ] : undefined; - - if ( transform === undefined ) return texture; + GLTFTextureTransformExtension.prototype.extendTexture = function ( texture, transform ) { texture = texture.clone(); @@ -2212,7 +2208,13 @@ THREE.GLTFLoader = ( function () { if ( parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] ) { - texture = parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ].extendTexture( texture, mapDef ); + var transform = mapDef.extensions !== undefined ? mapDef.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] : undefined; + + if ( transform ) { + + texture = parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ].extendTexture( texture, transform ); + + } } From 91cd51830a05824eaafb1377baf80977dcbec8e3 Mon Sep 17 00:00:00 2001 From: Don McCurdy Date: Mon, 22 Oct 2018 17:00:23 -0700 Subject: [PATCH 5/6] Improve endnote docs. --- docs/examples/loaders/GLTFLoader.html | 9 +++++---- docs/page.css | 10 ++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/docs/examples/loaders/GLTFLoader.html b/docs/examples/loaders/GLTFLoader.html index e5d378f3d53255..9d5055599215c9 100644 --- a/docs/examples/loaders/GLTFLoader.html +++ b/docs/examples/loaders/GLTFLoader.html @@ -37,10 +37,11 @@

    Extensions

    - *UV transforms are supported, with several key limitations in comparison to the - glTF specification. A transform is applied to all textures using that UV set on the current - material, and no more than one transform may be used per material. Each use of a texture with - a unique transform will result in an additional GPU texture upload. See + *UV transforms are supported, with several key limitations. Transforms applied to + a texture using the first UV slot (all textures except aoMap and lightMap) must share the same + transform, or no transfor at all. The aoMap and lightMap textures cannot be transformed. No + more than one transform may be used per material. Each use of a texture with a unique + transform will result in an additional GPU texture upload. See #[link:https://github.com/mrdoob/three.js/pull/13831 13831] and #[link:https://github.com/mrdoob/three.js/issues/12788 12788].

    diff --git a/docs/page.css b/docs/page.css index 57232a30c26531..cf080354d12b1d 100644 --- a/docs/page.css +++ b/docs/page.css @@ -130,3 +130,13 @@ span.param { a.param:hover { color: #777; } + +sup, sub { + /* prevent superscript and subscript elements from affecting line-height */ + vertical-align: baseline; + position: relative; + top: -0.4em; +} +sub { + top: 0.4em; +} \ No newline at end of file From 5e6cbc5dff31ca59ea1bfd52d029219c62091d34 Mon Sep 17 00:00:00 2001 From: Don McCurdy Date: Mon, 22 Oct 2018 17:04:55 -0700 Subject: [PATCH 6/6] Clean up. --- docs/page.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/page.css b/docs/page.css index cf080354d12b1d..e94bb16f4279f0 100644 --- a/docs/page.css +++ b/docs/page.css @@ -137,6 +137,7 @@ sup, sub { position: relative; top: -0.4em; } + sub { top: 0.4em; -} \ No newline at end of file +}