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,