提交 ae119329 编写于 作者: W WestLangley

Added support for texture rotation

上级 73309576
<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
......@@ -169,6 +169,23 @@ m.elements = [ 11, 21, 31,
<h3>[method:Matrix3 setFromMatrix4]( [page:Matrix4 m] )</h3>
<div>Set this matrx to the upper 3x3 matrix of the Matrix4 [page:Matrix4 m].</div>
<h3>
[method:Matrix3 setUvTransform](
[page:Float tx], [page:Float ty], [page:Float sx], [page:Float sy],
[page:Float rotation], [page:Float cx], [page:Float cy] )
</h3>
<div>
[page:Float tx] - translation x<br />
[page:Float ty] - translation y<br />
[page:Float sx] - scale x<br />
[page:Float sy] - scale y<br />
[page:Float rotation] - rotation (in radians)<br />
[page:Float cx] - center x of rotation<br />
[page:Float cy] - center y of rotation<br /><br />
Sets the UV transform matrix from the texture properties offset (translate), repeat (scale), rotation, and center.
</div>
<h3>[method:Array toArray]( [page:Array array], [page:Integer offset] )</h3>
<div>
[page:Array array] - (optional) array to store the resulting vector in. If not given a new array will be created.<br />
......
......@@ -147,6 +147,17 @@
assigned to achieve the desired repetiton.
</div>
<h3>[property:number rotation]</h3>
<div>
How much the texture is rotated, in radians. Postive values are counter-clockwise. Default is *0*.
</div>
<h3>[property:Vector2 center]</h3>
<div>
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.
</div>
<h3>[property:boolean generateMipmaps]</h3>
<div>
Whether to generate mipmaps (if possible) for a texture. True by default. Set this to false if you are
......
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - materials - texture - rotation</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
margin: 0px;
background-color: #050505;
color: #fff;
overflow: hidden;
}
a { color: #e00 }
#info {
position: absolute;
top: 0px; width: 100%;
color: #ffffff;
padding: 5px;
font-family: Monospace;
font-size: 13px;
text-align: center;
}
</style>
</head>
<body>
<div id="info">
<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - webgl - texture rotation
</div>
<script src="../build/three.js"></script>
<script src="js/controls/OrbitControls.js"></script>
<script src="js/libs/dat.gui.min.js"></script>
<script src="js/Detector.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var mesh, renderer, scene, camera;
var gui;
var API = {
translateX: 0,
translateY: 0,
scaleX: 0.25,
scaleY: 0.25,
rotation: Math.PI / 4, // positive is counter-clockwise
centerX: 0.5,
centerY: 0.5
};
init();
render();
function init() {
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 10, 15, 25 );
scene.add( camera );
var controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.addEventListener( 'change', render );
controls.minDistance = 20;
controls.maxDistance = 50;
controls.maxPolarAngle = Math.PI / 2;
var geometry = new THREE.BoxGeometry( 10, 10, 10 );
var loader = new THREE.TextureLoader();
var texture = loader.load( 'textures/UV_Grid_Sm.jpg', render );
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
var material = new THREE.MeshBasicMaterial( { map: texture } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
updateTextureParams();
initGui();
window.addEventListener( 'resize', onWindowResize, false );
}
function render() {
renderer.render( scene, camera );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
render();
}
function updateTextureParams() {
var map = mesh.material.map;
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;
render();
}
function initGui() {
var drop;
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 );
}
</script>
</body>
</html>
......@@ -273,6 +273,19 @@ Object.assign( Matrix3.prototype, {
},
setUvTransform: function ( tx, ty, sx, sy, rotation, cx, cy ) {
var c = Math.cos( rotation );
var s = Math.sin( rotation );
this.set(
sx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx,
- sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty,
0, 0, 0
);
},
equals: function ( matrix ) {
var te = this.elements;
......
......@@ -1984,8 +1984,10 @@ function WebGLRenderer( parameters ) {
var offset = uvScaleMap.offset;
var repeat = uvScaleMap.repeat;
var rotation = uvScaleMap.rotation;
var center = uvScaleMap.center;
uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
uniforms.uvTransform.value.setUvTransform( offset.x, offset.y, repeat.x, repeat.y, rotation, center.x, center.y );
}
......@@ -2019,8 +2021,10 @@ function WebGLRenderer( parameters ) {
var offset = material.map.offset;
var repeat = material.map.repeat;
var rotation = material.map.rotation;
var center = material.map.center;
uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
uniforms.uvTransform.value.setUvTransform( offset.x, offset.y, repeat.x, repeat.y, rotation, center.x, center.y );
}
......
#ifdef USE_MAP
vec4 mapTexel = texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );
vec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;
vec4 mapTexel = texture2D( map, uv );
diffuseColor *= mapTexelToLinear( mapTexel );
#endif
#ifdef USE_MAP
uniform vec4 offsetRepeat;
uniform mat3 uvTransform;
uniform sampler2D map;
#endif
#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )
varying vec2 vUv;
uniform vec4 offsetRepeat;
uniform mat3 uvTransform;
#endif
#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )
vUv = uv * offsetRepeat.zw + offsetRepeat.xy;
vUv = ( uvTransform * vec3( uv, 1 ) ).xy;
#endif
\ No newline at end of file
import { Vector4 } from '../../math/Vector4';
import { Color } from '../../math/Color';
import { Vector2 } from '../../math/Vector2';
import { Matrix3 } from '../../math/Matrix3';
import { DataTexture } from '../../textures/DataTexture';
/**
......@@ -15,7 +16,7 @@ var UniformsLib = {
opacity: { value: 1.0 },
map: { value: null },
offsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },
uvTransform: { value: new Matrix3() },
alphaMap: { value: null },
......@@ -180,7 +181,7 @@ var UniformsLib = {
size: { value: 1.0 },
scale: { value: 1.0 },
map: { value: null },
offsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }
uvTransform: { value: new Matrix3() }
}
......
......@@ -38,6 +38,8 @@ 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.generateMipmaps = true;
this.premultiplyAlpha = false;
......@@ -102,6 +104,8 @@ 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.generateMipmaps = source.generateMipmaps;
this.premultiplyAlpha = source.premultiplyAlpha;
......@@ -175,6 +179,8 @@ 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 ],
wrap: [ this.wrapS, this.wrapT ],
minFilter: this.minFilter,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册