diff --git a/docs/api/math/Matrix3.html b/docs/api/math/Matrix3.html index e19bce8ff9213786c24c0459e8f0f3fd611796d9..a542ad38357ec93efcc207e79f004de14e68edb3 100644 --- a/docs/api/math/Matrix3.html +++ b/docs/api/math/Matrix3.html @@ -1,4 +1,4 @@ - + diff --git a/docs/api/textures/Texture.html b/docs/api/textures/Texture.html index 2760371ad6cd96d9ac36711c1159b7857f37e734..d42a35a40ed583d26b4e5ce8210f7178f738d71e 100644 --- a/docs/api/textures/Texture.html +++ b/docs/api/textures/Texture.html @@ -147,15 +147,18 @@ assigned to achieve the desired repetiton. -

[property:number rotation]

+

[property:boolean matrixAutoUpdate]

- How much the texture is rotated, in radians. Postive values are counter-clockwise. Default is *0*. + Whether to update the texture's uv-transform [property:Matrix3 matrix] based on the [property:Vector2 offset] and + [property:Vector2 repeat] settings. True by default. + Set this to false if you are specifying the uv-transform matrix directly.
-

[property:Vector2 center]

+

[property:Matrix3 matrix]

- The center point of the texture -- used for both rotation and scaling. The range for each component is *0.0* to *1.0*. The default is [ *0*, *0* ], - which corresponds to the lower-left corner of the texture. + The uv-transform matrix for the texture. Used instead of [property:Vector2 offset] and [property:Vector2 repeat] + when the texture's [property:boolean matrixAutoUpdate] property is false. + Default is the indentity matrix.

[property:boolean generateMipmaps]

diff --git a/examples/webgl_materials_texture_rotation.html b/examples/webgl_materials_texture_rotation.html index a5bc493397d99371c136907c906d9afba3e8e91c..805c18a4ba4016eb44bf228ed81d88255bfba7be 100644 --- a/examples/webgl_materials_texture_rotation.html +++ b/examples/webgl_materials_texture_rotation.html @@ -87,13 +87,14 @@ var loader = new THREE.TextureLoader(); var texture = loader.load( 'textures/UV_Grid_Sm.jpg', render ); texture.wrapS = texture.wrapT = THREE.RepeatWrapping; + texture.matrixAutoUpdate = false; var material = new THREE.MeshBasicMaterial( { map: texture } ); mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); - updateTextureParams(); + updateUvTransform(); initGui(); @@ -119,17 +120,11 @@ } - function updateTextureParams() { + function updateUvTransform() { - var map = mesh.material.map; + var matrix = mesh.material.map.matrix; - map.offset.x = API.translateX; - map.offset.y = API.translateY; - map.repeat.x = API.scaleX; - map.repeat.y = API.scaleY; - map.rotation = API.rotation; - map.center.x = API.centerX; - map.center.y = API.centerY; + matrix.setUvTransform( API.translateX, API.translateY, API.scaleX, API.scaleY, API.rotation, API.centerX, API.centerY ); render(); @@ -141,13 +136,13 @@ gui = new dat.GUI(); - gui.add( API, 'translateX', 0.0, 1.0 ).name( 'offset.x' ).onChange( updateTextureParams ); - gui.add( API, 'translateY', 0.0, 1.0 ).name( 'offset.y' ).onChange( updateTextureParams ); - gui.add( API, 'scaleX', 0.25, 2.0 ).name( 'repeat.x' ).onChange( updateTextureParams ); - gui.add( API, 'scaleY', 0.25, 2.0 ).name( 'repeat.y' ).onChange( updateTextureParams ); - gui.add( API, 'rotation', - 2.0, 2.0 ).name( 'rotation' ).onChange( updateTextureParams ); - gui.add( API, 'centerX', 0.0, 1.0 ).name( 'center.x' ).onChange( updateTextureParams ); - gui.add( API, 'centerY', 0.0, 1.0 ).name( 'center.y' ).onChange( updateTextureParams ); + gui.add( API, 'translateX', 0.0, 1.0 ).name( 'offset.x' ).onChange( updateUvTransform ); + gui.add( API, 'translateY', 0.0, 1.0 ).name( 'offset.y' ).onChange( updateUvTransform ); + gui.add( API, 'scaleX', 0.25, 2.0 ).name( 'repeat.x' ).onChange( updateUvTransform ); + gui.add( API, 'scaleY', 0.25, 2.0 ).name( 'repeat.y' ).onChange( updateUvTransform ); + gui.add( API, 'rotation', - 2.0, 2.0 ).name( 'rotation' ).onChange( updateUvTransform ); + gui.add( API, 'centerX', 0.0, 1.0 ).name( 'center.x' ).onChange( updateUvTransform ); + gui.add( API, 'centerY', 0.0, 1.0 ).name( 'center.y' ).onChange( updateUvTransform ); } diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 5048e59f65250f24eac5daab35d7f4c0df19661a..57ddda1726fd969e1a097ed8eeb63a370314f5b7 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -1982,12 +1982,18 @@ function WebGLRenderer( parameters ) { } - var offset = uvScaleMap.offset; - var repeat = uvScaleMap.repeat; - var rotation = uvScaleMap.rotation; - var center = uvScaleMap.center; + if ( uvScaleMap.matrixAutoUpdate === true ) { - uniforms.uvTransform.value.setUvTransform( offset.x, offset.y, repeat.x, repeat.y, rotation, center.x, center.y ); + var offset = uvScaleMap.offset; + var repeat = uvScaleMap.repeat; + + uniforms.uvTransform.value.setUvTransform( offset.x, offset.y, repeat.x, repeat.y, 0, 0, 0 ); + + } else { + + uniforms.uvTransform.value.copy( uvScaleMap.matrix ); + + } } @@ -2019,12 +2025,18 @@ function WebGLRenderer( parameters ) { if ( material.map !== null ) { - var offset = material.map.offset; - var repeat = material.map.repeat; - var rotation = material.map.rotation; - var center = material.map.center; + if ( material.map.matrixAutoUpdate === true ) { - uniforms.uvTransform.value.setUvTransform( offset.x, offset.y, repeat.x, repeat.y, rotation, center.x, center.y ); + var offset = material.map.offset; + var repeat = material.map.repeat; + + uniforms.uvTransform.value.setUvTransform( offset.x, offset.y, repeat.x, repeat.y, 0, 0, 0 ); + + } else { + + uniforms.uvTransform.value.copy( material.map.matrix ); + + } } diff --git a/src/textures/Texture.js b/src/textures/Texture.js index e559e74969da58f3e68c542f0407983c4d59976a..48e8b7024a8ec18cd0ab444ce0a78ea18d0abef9 100644 --- a/src/textures/Texture.js +++ b/src/textures/Texture.js @@ -3,6 +3,7 @@ import { UVMapping } from '../constants'; import { MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping, LinearEncoding, UnsignedByteType, RGBAFormat, LinearMipMapLinearFilter, LinearFilter } from '../constants'; import { _Math } from '../math/Math'; import { Vector2 } from '../math/Vector2'; +import { Matrix3 } from '../math/Matrix3'; /** * @author mrdoob / http://mrdoob.com/ @@ -38,8 +39,9 @@ function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, ty this.offset = new Vector2( 0, 0 ); this.repeat = new Vector2( 1, 1 ); - this.rotation = 0; - this.center = new Vector2( 0, 0 ); + + this.matrixAutoUpdate = true; + this.matrix = new Matrix3(); this.generateMipmaps = true; this.premultiplyAlpha = false; @@ -104,8 +106,9 @@ Object.assign( Texture.prototype, EventDispatcher.prototype, { this.offset.copy( source.offset ); this.repeat.copy( source.repeat ); - this.rotation = source.rotation; - this.center.copy( source.center ); + + this.matrixAutoUpdate = source.matrixAutoUpdate; + this.matrix.copy( source.matrix ); this.generateMipmaps = source.generateMipmaps; this.premultiplyAlpha = source.premultiplyAlpha; @@ -179,8 +182,10 @@ Object.assign( Texture.prototype, EventDispatcher.prototype, { repeat: [ this.repeat.x, this.repeat.y ], offset: [ this.offset.x, this.offset.y ], - rotation: this.rotation, - center: [ this.center.x, this.center.y ], + + matrixAutoUpdate: this.matrixAutoUpdate, + matrix: this.matrix.toArray(), + wrap: [ this.wrapS, this.wrapT ], minFilter: this.minFilter,