diff --git a/docs/api/en/materials/Material.html b/docs/api/en/materials/Material.html index 3da14df4bbfd3f..c4fe7d942fc2f1 100644 --- a/docs/api/en/materials/Material.html +++ b/docs/api/en/materials/Material.html @@ -261,6 +261,13 @@
+ Defines whether precomputed vertex tangents, which must be provided in a vec4 "tangent" attribute, + are used. When disabled, tangents are derived automatically. Using precomputed tangents will give + more accurate normal map details in some cases, such as with mirrored UVs. Default is false. +
+Defines whether this material is visible. Default is *true*. diff --git a/docs/api/zh/materials/Material.html b/docs/api/zh/materials/Material.html index c9ab32be01d709..96ae0d7299d464 100644 --- a/docs/api/zh/materials/Material.html +++ b/docs/api/zh/materials/Material.html @@ -217,6 +217,10 @@
TODO. +
+此材质是否可见。默认为*true*。
diff --git a/examples/js/loaders/GLTFLoader.js b/examples/js/loaders/GLTFLoader.js index 11ce8917abfced..38273829b31336 100644 --- a/examples/js/loaders/GLTFLoader.js +++ b/examples/js/loaders/GLTFLoader.js @@ -1202,6 +1202,7 @@ THREE.GLTFLoader = ( function () { var ATTRIBUTES = { POSITION: 'position', NORMAL: 'normal', + TANGENT: 'tangent', TEXCOORD_0: 'uv', TEXCOORD_1: 'uv2', COLOR_0: 'color', @@ -2409,14 +2410,6 @@ THREE.GLTFLoader = ( function () { if ( materialDef.name !== undefined ) material.name = materialDef.name; - // Normal map textures use OpenGL conventions: - // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#materialnormaltexture - if ( material.normalScale ) { - - material.normalScale.y = - material.normalScale.y; - - } - // baseColorTexture, emissiveTexture, and specularGlossinessTexture use sRGB encoding. if ( material.map ) material.map.encoding = THREE.sRGBEncoding; if ( material.emissiveMap ) material.emissiveMap.encoding = THREE.sRGBEncoding; @@ -2774,6 +2767,7 @@ THREE.GLTFLoader = ( function () { var materials = isMultiMaterial ? mesh.material : [ mesh.material ]; + var useVertexTangents = geometry.attributes.tangent !== undefined; var useVertexColors = geometry.attributes.color !== undefined; var useFlatShading = geometry.attributes.normal === undefined; var useSkinning = mesh.isSkinnedMesh === true; @@ -2826,12 +2820,13 @@ THREE.GLTFLoader = ( function () { } // Clone the material if it will be modified - if ( useVertexColors || useFlatShading || useSkinning || useMorphTargets ) { + if ( useVertexTangents || useVertexColors || useFlatShading || useSkinning || useMorphTargets ) { var cacheKey = 'ClonedMaterial:' + material.uuid + ':'; if ( material.isGLTFSpecularGlossinessMaterial ) cacheKey += 'specular-glossiness:'; if ( useSkinning ) cacheKey += 'skinning:'; + if ( useVertexTangents ) cacheKey += 'vertex-tangents:'; if ( useVertexColors ) cacheKey += 'vertex-colors:'; if ( useFlatShading ) cacheKey += 'flat-shading:'; if ( useMorphTargets ) cacheKey += 'morph-targets:'; @@ -2846,6 +2841,7 @@ THREE.GLTFLoader = ( function () { : material.clone(); if ( useSkinning ) cachedMaterial.skinning = true; + if ( useVertexTangents ) cachedMaterial.vertexTangents = true; if ( useVertexColors ) cachedMaterial.vertexColors = THREE.VertexColors; if ( useFlatShading ) cachedMaterial.flatShading = true; if ( useMorphTargets ) cachedMaterial.morphTargets = true; diff --git a/src/core/BufferGeometry.js b/src/core/BufferGeometry.js index c196dbdf6787b4..5a1ec264505aa9 100644 --- a/src/core/BufferGeometry.js +++ b/src/core/BufferGeometry.js @@ -154,6 +154,18 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy } + var tangent = this.attributes.tangent; + + if ( tangent !== undefined ) { + + var normalMatrix = new Matrix3().getNormalMatrix( matrix ); + + // Tangent is vec4, but the '.w' component is a sign value (+1/-1). + normalMatrix.applyToBufferAttribute( tangent ); + tangent.needsUpdate = true; + + } + if ( this.boundingBox !== null ) { this.computeBoundingBox(); diff --git a/src/materials/Material.d.ts b/src/materials/Material.d.ts index 52f8061dd53645..5f704b8233f5ff 100644 --- a/src/materials/Material.d.ts +++ b/src/materials/Material.d.ts @@ -44,6 +44,7 @@ export interface MaterialParameters { side?: Side; transparent?: boolean; vertexColors?: Colors; + vertexTangents?: boolean; visible?: boolean; } @@ -234,6 +235,11 @@ export class Material extends EventDispatcher { */ vertexColors: Colors; + /** + * Defines whether precomputed vertex tangents are used. Default is false. + */ + vertexTangents: boolean; + /** * Defines whether this material is visible. Default is true. */ diff --git a/src/materials/Material.js b/src/materials/Material.js index b099f3753d4caa..97f4a2d11ad8c2 100644 --- a/src/materials/Material.js +++ b/src/materials/Material.js @@ -24,6 +24,7 @@ function Material() { this.blending = NormalBlending; this.side = FrontSide; this.flatShading = false; + this.vertexTangents = false; this.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors this.opacity = 1; diff --git a/src/renderers/shaders/ShaderChunk/beginnormal_vertex.glsl.js b/src/renderers/shaders/ShaderChunk/beginnormal_vertex.glsl.js index f76965917952a0..7286cbaa5e7332 100644 --- a/src/renderers/shaders/ShaderChunk/beginnormal_vertex.glsl.js +++ b/src/renderers/shaders/ShaderChunk/beginnormal_vertex.glsl.js @@ -1,3 +1,9 @@ export default /* glsl */` vec3 objectNormal = vec3( normal ); + +#ifdef USE_TANGENT + + vec3 objectTangent = vec3( tangent.xyz ); + +#endif `; diff --git a/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl.js b/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl.js index 671f9328b7ba39..7e02c01a7191bd 100644 --- a/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl.js +++ b/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl.js @@ -5,5 +5,17 @@ vec3 transformedNormal = normalMatrix * objectNormal; transformedNormal = - transformedNormal; +#endif + +#ifdef USE_TANGENT + + vec3 transformedTangent = normalMatrix * objectTangent; + + #ifdef FLIP_SIDED + + transformedTangent = - transformedTangent; + + #endif + #endif `; diff --git a/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js b/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js index 4cbfb3d388063f..3d6d128e4338e4 100644 --- a/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js +++ b/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js @@ -17,5 +17,19 @@ export default /* glsl */` #endif + #ifdef USE_TANGENT + + vec3 tangent = normalize( vTangent ); + vec3 bitangent = normalize( vBitangent ); + + #ifdef DOUBLE_SIDED + + tangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 ); + bitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 ); + + #endif + + #endif + #endif `; diff --git a/src/renderers/shaders/ShaderChunk/normal_fragment_maps.glsl.js b/src/renderers/shaders/ShaderChunk/normal_fragment_maps.glsl.js index cdcfc9e522e960..9ec57d6327b110 100644 --- a/src/renderers/shaders/ShaderChunk/normal_fragment_maps.glsl.js +++ b/src/renderers/shaders/ShaderChunk/normal_fragment_maps.glsl.js @@ -21,7 +21,18 @@ export default /* glsl */` #else // tangent-space normal map - normal = perturbNormal2Arb( -vViewPosition, normal ); + #ifdef USE_TANGENT + + mat3 vTBN = mat3( tangent, bitangent, normal ); + vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0; + mapN.xy = normalScale * mapN.xy; + normal = normalize( vTBN * mapN ); + + #else + + normal = perturbNormal2Arb( -vViewPosition, normal ); + + #endif #endif diff --git a/src/renderers/shaders/ShaderChunk/skinnormal_vertex.glsl.js b/src/renderers/shaders/ShaderChunk/skinnormal_vertex.glsl.js index 5b833c4e33ed71..2b8e5cc84c7e51 100644 --- a/src/renderers/shaders/ShaderChunk/skinnormal_vertex.glsl.js +++ b/src/renderers/shaders/ShaderChunk/skinnormal_vertex.glsl.js @@ -10,5 +10,11 @@ export default /* glsl */` objectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz; + #ifdef USE_TANGENT + + objectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz; + + #endif + #endif `; diff --git a/src/renderers/shaders/ShaderLib/meshphysical_frag.glsl.js b/src/renderers/shaders/ShaderLib/meshphysical_frag.glsl.js index 4a5dde0bd7ee7b..d909ad10d82793 100644 --- a/src/renderers/shaders/ShaderLib/meshphysical_frag.glsl.js +++ b/src/renderers/shaders/ShaderLib/meshphysical_frag.glsl.js @@ -18,6 +18,13 @@ varying vec3 vViewPosition; varying vec3 vNormal; + #ifdef USE_TANGENT + + varying vec3 vTangent; + varying vec3 vBitangent; + + #endif + #endif #include