Răsfoiți Sursa

Merge branch 'dev' into dev

Mr.doob 6 ani în urmă
părinte
comite
20f22382c7

+ 7 - 0
docs/api/en/materials/Material.html

@@ -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*.

+ 18 - 5
docs/api/en/renderers/WebGLRenderer.html

@@ -348,8 +348,12 @@
 		<h3>[method:RenderTarget getRenderTarget]()</h3>
 		<p>Returns the current RenderTarget, if any.</p>
 
-		<h3>[method:RenderTarget getCurrentViewport]()</h3>
-		<p>Returns the current viewport.</p>
+		<h3>[method:Vector4 getCurrentViewport]( [param:Vector4 target] )</h3>
+		<p>
+		[page:Vector4 target] — the result will be copied into this Vector4.<br /><br />
+
+		Returns the current viewport.
+		</p>
 
 		<h3>[method:Vector2 getDrawingBufferSize]( [param:Vector2 target] )</h3>
 		<p>
@@ -368,14 +372,23 @@
 		Returns the width and height of the renderer's output canvas, in pixels.
 		</p>
 
+		<h3>[method:Vector4 getViewport]( [param:Vector4 target] )</h3>
+		<p>
+		[page:Vector4 target] — the result will be copied into this Vector4.<br /><br />
+
+		Returns the viewport.
+		</p>
+
 		<h3>[method:null resetGLState]( )</h3>
 		<p>Reset the GL state to default. Called internally if the WebGL context is lost.</p>
 
-		<h3>[method:null readRenderTargetPixels]( [param:WebGLRenderTarget renderTarget], [param:Float x], [param:Float y], [param:Float width], [param:Float height], buffer )</h3>
-		<p>Reads the pixel data from the renderTarget into the buffer you pass in. This is a wrapper around [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/readPixels WebGLRenderingContext.readPixels]().<br />
-		See the [example:webgl_interactive_cubes_gpu interactive / cubes / gpu] example.
+		<h3>[method:null readRenderTargetPixels]( [param:WebGLRenderTarget renderTarget], [param:Float x], [param:Float y], [param:Float width], [param:Float height], [param:TypedArray buffer] )</h3>
+		<p>buffer - Uint8Array is the only destination type supported in all cases, other types are renderTarget and platform dependent. See [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.12 WebGL spec] for details.</p>
+		<p>Reads the pixel data from the renderTarget into the buffer you pass in. This is a wrapper around [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/readPixels WebGLRenderingContext.readPixels]().</p>
+		<p>See the [example:webgl_interactive_cubes_gpu interactive / cubes / gpu] example.
 		</p>
 
+
 		<h3>[method:null render]( [param:Scene scene], [param:Camera camera] )</h3>
 		<p>
 			Render a [page:Scene scene] using a [page:Camera camera].<br />

+ 4 - 0
docs/api/zh/materials/Material.html

@@ -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>

+ 5 - 9
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;

+ 1 - 1
examples/js/objects/Lensflare.js

@@ -162,7 +162,7 @@ THREE.Lensflare = function () {
 
 	this.onBeforeRender = function ( renderer, scene, camera ) {
 
-		viewport.copy( renderer.getCurrentViewport() );
+		renderer.getCurrentViewport( viewport );
 
 		var invAspect = viewport.w / viewport.z;
 		var halfViewportWidth = viewport.z / 2.0;

+ 12 - 0
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();

+ 1 - 1
src/core/Object3D.d.ts

@@ -306,7 +306,7 @@ export class Object3D extends EventDispatcher {
   /**
    * Updates global transform of the object and its children.
    */
-  updateMatrixWorld(force: boolean): void;
+  updateMatrixWorld(force?: boolean): void;
 
   updateWorldMatrix(updateParents: boolean, updateChildren: boolean): void;
 

+ 6 - 0
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.
    */

+ 1 - 0
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;

+ 8 - 2
src/renderers/WebGLRenderer.d.ts

@@ -214,7 +214,13 @@ export class WebGLRenderer implements Renderer {
    */
   setSize(width: number, height: number, updateStyle?: boolean): void;
 
-  getCurrentViewport(): Vector4;
+  getCurrentViewport(target: Vector4): Vector4;
+
+  /**
+   * Copies the viewport into target.
+   */
+  getViewport(target: Vector4): Vector4;
+
   /**
    * Sets the viewport to render from (x, y) to (x + width, y + height).
    */
@@ -315,7 +321,7 @@ export class WebGLRenderer implements Renderer {
    */
   render(
     scene: Scene,
-    camera: Camera,
+    camera: Camera
   ): void;
 
   /**

+ 16 - 2
src/renderers/WebGLRenderer.js

@@ -429,9 +429,23 @@ function WebGLRenderer( parameters ) {
 
 	};
 
-	this.getCurrentViewport = function () {
+	this.getCurrentViewport = function ( target ) {
 
-		return _currentViewport;
+		if ( target === undefined ) {
+
+			console.warn( 'WebGLRenderer: .getCurrentViewport() now requires a Vector4 as an argument' );
+
+			target = new Vector4();
+
+		}
+
+		return target.copy( _currentViewport );
+
+	};
+
+	this.getViewport = function ( target ) {
+
+		return target.copy( _viewport );
 
 	};
 

+ 6 - 0
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
 `;

+ 12 - 0
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
 `;

+ 14 - 0
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
 `;

+ 12 - 1
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
 

+ 6 - 0
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
 `;

+ 7 - 0
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 <common>

+ 14 - 0
src/renderers/shaders/ShaderLib/meshphysical_vert.glsl.js

@@ -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>

+ 7 - 0
src/renderers/shaders/ShaderLib/normal_frag.glsl.js

@@ -13,6 +13,13 @@ uniform float opacity;
 
 	varying vec3 vNormal;
 
+	#ifdef USE_TANGENT
+
+		varying vec3 vTangent;
+		varying vec3 vBitangent;
+
+	#endif
+
 #endif
 
 #include <packing>

+ 14 - 0
src/renderers/shaders/ShaderLib/normal_vert.glsl.js

@@ -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>

+ 10 - 0
src/renderers/webgl/WebGLProgram.js

@@ -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' : '',

+ 2 - 1
src/renderers/webgl/WebGLPrograms.js

@@ -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,