未验证 提交 f89180d3 编写于 作者: M Mr.doob 提交者: GitHub

Merge pull request #15749 from donmccurdy/feat-attribute-tangents-v2

Support stored vertex 'tangent' attribute
......@@ -261,6 +261,13 @@
Other options are [page:Materials THREE.VertexColors] and [page:Materials THREE.FaceColors].
</p>
<h3>[property:Boolean vertexTangents]</h3>
<p>
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.
</p>
<h3>[property:Boolean visible]</h3>
<p>
Defines whether this material is visible. Default is *true*.
......
......@@ -217,6 +217,10 @@
其他选项有[page:Materials THREE.VertexColors] 和 [page:Materials THREE.FaceColors]。
</p>
<h3>[property:Boolean vertexTangents]</h3>
<p> TODO.
</p>
<h3>[property:Boolean visible]</h3>
<p> 此材质是否可见。默认为*true*。
</p>
......
......@@ -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;
......
......@@ -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();
......
......@@ -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.
*/
......
......@@ -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;
......
export default /* glsl */`
vec3 objectNormal = vec3( normal );
#ifdef USE_TANGENT
vec3 objectTangent = vec3( tangent.xyz );
#endif
`;
......@@ -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
`;
......@@ -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
`;
......@@ -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
......
......@@ -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
`;
......@@ -18,6 +18,13 @@ varying vec3 vViewPosition;
varying vec3 vNormal;
#ifdef USE_TANGENT
varying vec3 vTangent;
varying vec3 vBitangent;
#endif
#endif
#include <common>
......
......@@ -7,6 +7,13 @@ varying vec3 vViewPosition;
varying vec3 vNormal;
#ifdef USE_TANGENT
varying vec3 vTangent;
varying vec3 vBitangent;
#endif
#endif
#include <common>
......@@ -37,6 +44,13 @@ void main() {
vNormal = normalize( transformedNormal );
#ifdef USE_TANGENT
vTangent = normalize( transformedTangent );
vBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );
#endif
#endif
#include <begin_vertex>
......
......@@ -13,6 +13,13 @@ uniform float opacity;
varying vec3 vNormal;
#ifdef USE_TANGENT
varying vec3 vTangent;
varying vec3 vBitangent;
#endif
#endif
#include <packing>
......
......@@ -11,6 +11,13 @@ export default /* glsl */`
varying vec3 vNormal;
#ifdef USE_TANGENT
varying vec3 vTangent;
varying vec3 vBitangent;
#endif
#endif
#include <uv_pars_vertex>
......@@ -33,6 +40,13 @@ void main() {
vNormal = normalize( transformedNormal );
#ifdef USE_TANGENT
vTangent = normalize( transformedTangent );
vBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );
#endif
#endif
#include <begin_vertex>
......
......@@ -359,6 +359,8 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
parameters.vertexTangents ? '#define USE_TANGENT' : '',
parameters.vertexColors ? '#define USE_COLOR' : '',
parameters.flatShading ? '#define FLAT_SHADED' : '',
......@@ -390,6 +392,12 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
'attribute vec3 normal;',
'attribute vec2 uv;',
'#ifdef USE_TANGENT',
' attribute vec4 tangent;',
'#endif',
'#ifdef USE_COLOR',
' attribute vec3 color;',
......@@ -466,6 +474,8 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
parameters.vertexTangents ? '#define USE_TANGENT' : '',
parameters.vertexColors ? '#define USE_COLOR' : '',
parameters.gradientMap ? '#define USE_GRADIENTMAP' : '',
......
......@@ -31,7 +31,7 @@ function WebGLPrograms( renderer, extensions, capabilities ) {
"precision", "supportsVertexTextures", "map", "mapEncoding", "matcap", "matcapEncoding", "envMap", "envMapMode", "envMapEncoding",
"lightMap", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "objectSpaceNormalMap", "displacementMap", "specularMap",
"roughnessMap", "metalnessMap", "gradientMap",
"alphaMap", "combine", "vertexColors", "fog", "useFog", "fogExp",
"alphaMap", "combine", "vertexColors", "vertexTangents", "fog", "useFog", "fogExp",
"flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning",
"maxBones", "useVertexTexture", "morphTargets", "morphNormals",
"maxMorphTargets", "maxMorphNormals", "premultipliedAlpha",
......@@ -163,6 +163,7 @@ function WebGLPrograms( renderer, extensions, capabilities ) {
combine: material.combine,
vertexTangents: material.vertexTangents,
vertexColors: material.vertexColors,
fog: !! fog,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册