Texture.js 6.5 KB
Newer Older
M
Mr.doob 已提交
1
/**
M
Mr.doob 已提交
2
 * @author mrdoob / http://mrdoob.com/
3
 * @author alteredq / http://alteredqualia.com/
4
 * @author szimek / https://github.com/szimek/
M
Mr.doob 已提交
5 6
 */

B
bentok 已提交
7
import { EventDispatcher } from '../core/EventDispatcher.js';
M
Mr.doob 已提交
8 9 10 11 12 13 14
import {
	MirroredRepeatWrapping,
	ClampToEdgeWrapping,
	RepeatWrapping,
	LinearEncoding,
	UnsignedByteType,
	RGBAFormat,
W
WestLangley 已提交
15
	LinearMipmapLinearFilter,
M
Mr.doob 已提交
16 17 18
	LinearFilter,
	UVMapping
} from '../constants.js';
B
bentok 已提交
19 20 21
import { _Math } from '../math/Math.js';
import { Vector2 } from '../math/Vector2.js';
import { Matrix3 } from '../math/Matrix3.js';
22
import { ImageUtils } from '../extras/ImageUtils.js';
R
Rich Harris 已提交
23

24 25
var textureId = 0;

M
Mr.doob 已提交
26
function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {
M
Mr.doob 已提交
27

28
	Object.defineProperty( this, 'id', { value: textureId ++ } );
M
Mr.doob 已提交
29

R
Rich Harris 已提交
30
	this.uuid = _Math.generateUUID();
M
Mr.doob 已提交
31

32 33
	this.name = '';

R
Rich Harris 已提交
34
	this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;
35
	this.mipmaps = [];
36

R
Rich Harris 已提交
37
	this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;
38

R
Rich Harris 已提交
39 40
	this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;
	this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;
M
Mr.doob 已提交
41

R
Rich Harris 已提交
42
	this.magFilter = magFilter !== undefined ? magFilter : LinearFilter;
W
WestLangley 已提交
43
	this.minFilter = minFilter !== undefined ? minFilter : LinearMipmapLinearFilter;
44

45 46
	this.anisotropy = anisotropy !== undefined ? anisotropy : 1;

R
Rich Harris 已提交
47
	this.format = format !== undefined ? format : RGBAFormat;
48
	this.internalFormat = null;
R
Rich Harris 已提交
49
	this.type = type !== undefined ? type : UnsignedByteType;
50

R
Rich Harris 已提交
51 52
	this.offset = new Vector2( 0, 0 );
	this.repeat = new Vector2( 1, 1 );
T
Tentone 已提交
53
	this.center = new Vector2( 0, 0 );
54
	this.rotation = 0;
W
WestLangley 已提交
55 56 57

	this.matrixAutoUpdate = true;
	this.matrix = new Matrix3();
58

59
	this.generateMipmaps = true;
60
	this.premultiplyAlpha = false;
61
	this.flipY = true;
62
	this.unpackAlignment = 4;	// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)
63

M
Mr.doob 已提交
64 65
	this.blurriness = 0;

66 67 68
	// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.
	//
	// Also changing the encoding after already used by a Material will not automatically make the Material
M
Mugen87 已提交
69
	// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.
70
	this.encoding = encoding !== undefined ? encoding : LinearEncoding;
71

72
	this.version = 0;
73
	this.onUpdate = null;
74

M
Mr.doob 已提交
75
}
M
Mr.doob 已提交
76

R
Rich Harris 已提交
77 78
Texture.DEFAULT_IMAGE = undefined;
Texture.DEFAULT_MAPPING = UVMapping;
79

80
Texture.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
M
Mr.doob 已提交
81

T
Tristan VALCKE 已提交
82
	constructor: Texture,
M
Mr.doob 已提交
83

T
Tristan VALCKE 已提交
84
	isTexture: true,
M
Mr.doob 已提交
85

W
WestLangley 已提交
86 87 88 89 90 91
	updateMatrix: function () {

		this.matrix.setUvTransform( this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y );

	},

92
	clone: function () {
93

94
		return new this.constructor().copy( this );
95

96 97
	},

D
dubejf 已提交
98
	copy: function ( source ) {
99

100
		this.name = source.name;
101

102
		this.image = source.image;
103
		this.mipmaps = source.mipmaps.slice( 0 );
M
Mr.doob 已提交
104 105 106 107 108 109 110 111 112 113 114

		this.mapping = source.mapping;

		this.wrapS = source.wrapS;
		this.wrapT = source.wrapT;

		this.magFilter = source.magFilter;
		this.minFilter = source.minFilter;

		this.anisotropy = source.anisotropy;

M
Mr.doob 已提交
115
		this.format = source.format;
116
		this.internalFormat = source.internalFormat;
117
		this.type = source.type;
118

119 120
		this.offset.copy( source.offset );
		this.repeat.copy( source.repeat );
121
		this.center.copy( source.center );
122
		this.rotation = source.rotation;
W
WestLangley 已提交
123 124 125

		this.matrixAutoUpdate = source.matrixAutoUpdate;
		this.matrix.copy( source.matrix );
M
Mr.doob 已提交
126

127 128 129 130
		this.generateMipmaps = source.generateMipmaps;
		this.premultiplyAlpha = source.premultiplyAlpha;
		this.flipY = source.flipY;
		this.unpackAlignment = source.unpackAlignment;
131
		this.encoding = source.encoding;
M
Mr.doob 已提交
132

133
		return this;
134

135 136
	},

137 138
	toJSON: function ( meta ) {

139 140 141
		var isRootObject = ( meta === undefined || typeof meta === 'string' );

		if ( ! isRootObject && meta.textures[ this.uuid ] !== undefined ) {
142 143 144 145

			return meta.textures[ this.uuid ];

		}
E
elephantatwork 已提交
146 147

		var output = {
148

E
elephantatwork 已提交
149
			metadata: {
150
				version: 4.5,
E
elephantatwork 已提交
151
				type: 'Texture',
152
				generator: 'Texture.toJSON'
E
elephantatwork 已提交
153
			},
154

155
			uuid: this.uuid,
156 157 158 159 160 161
			name: this.name,

			mapping: this.mapping,

			repeat: [ this.repeat.x, this.repeat.y ],
			offset: [ this.offset.x, this.offset.y ],
162
			center: [ this.center.x, this.center.y ],
163
			rotation: this.rotation,
W
WestLangley 已提交
164

165 166
			wrap: [ this.wrapS, this.wrapT ],

167
			format: this.format,
168 169 170
			type: this.type,
			encoding: this.encoding,

171 172
			minFilter: this.minFilter,
			magFilter: this.magFilter,
M
Mr.doob 已提交
173 174
			anisotropy: this.anisotropy,

175
			flipY: this.flipY,
M
Mr.doob 已提交
176

177 178
			premultiplyAlpha: this.premultiplyAlpha,
			unpackAlignment: this.unpackAlignment
179

E
elephantatwork 已提交
180 181
		};

182
		if ( this.image !== undefined ) {
E
elephantatwork 已提交
183

184
			// TODO: Move to THREE.Image
E
elephantatwork 已提交
185

186
			var image = this.image;
E
elephantatwork 已提交
187

188
			if ( image.uuid === undefined ) {
E
elephantatwork 已提交
189

R
Rich Harris 已提交
190
				image.uuid = _Math.generateUUID(); // UGH
E
elephantatwork 已提交
191

192
			}
E
elephantatwork 已提交
193

194
			if ( ! isRootObject && meta.images[ image.uuid ] === undefined ) {
195

196 197 198 199 200 201 202 203 204 205
				var url;

				if ( Array.isArray( image ) ) {

					// process array of images e.g. CubeTexture

					url = [];

					for ( var i = 0, l = image.length; i < l; i ++ ) {

206
						url.push( ImageUtils.getDataURL( image[ i ] ) );
207 208 209 210 211 212 213

					}

				} else {

					// process single image

214
					url = ImageUtils.getDataURL( image );
215 216 217

				}

218 219
				meta.images[ image.uuid ] = {
					uuid: image.uuid,
220
					url: url
221
				};
222 223 224 225

			}

			output.image = image.uuid;
E
elephantatwork 已提交
226 227 228

		}

229 230 231 232 233
		if ( ! isRootObject ) {

			meta.textures[ this.uuid ] = output;

		}
234

E
elephantatwork 已提交
235
		return output;
236

E
elephantatwork 已提交
237 238
	},

239
	dispose: function () {
240

241
		this.dispatchEvent( { type: 'dispose' } );
242

243 244 245 246
	},

	transformUv: function ( uv ) {

247
		if ( this.mapping !== UVMapping ) return uv;
248

249
		uv.applyMatrix3( this.matrix );
250 251

		if ( uv.x < 0 || uv.x > 1 ) {
R
rfm1201 已提交
252

253
			switch ( this.wrapS ) {
R
rfm1201 已提交
254

R
Rich Harris 已提交
255
				case RepeatWrapping:
R
rfm1201 已提交
256

257 258
					uv.x = uv.x - Math.floor( uv.x );
					break;
R
rfm1201 已提交
259

R
Rich Harris 已提交
260
				case ClampToEdgeWrapping:
R
rfm1201 已提交
261

262 263
					uv.x = uv.x < 0 ? 0 : 1;
					break;
R
rfm1201 已提交
264

R
Rich Harris 已提交
265
				case MirroredRepeatWrapping:
R
rfm1201 已提交
266 267 268

					if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {

269
						uv.x = Math.ceil( uv.x ) - uv.x;
R
rfm1201 已提交
270

271
					} else {
R
rfm1201 已提交
272

273
						uv.x = uv.x - Math.floor( uv.x );
R
rfm1201 已提交
274

275
					}
R
rfm1201 已提交
276 277
					break;

278
			}
R
rfm1201 已提交
279

280 281 282
		}

		if ( uv.y < 0 || uv.y > 1 ) {
R
rfm1201 已提交
283

284
			switch ( this.wrapT ) {
R
rfm1201 已提交
285

R
Rich Harris 已提交
286
				case RepeatWrapping:
R
rfm1201 已提交
287

288 289
					uv.y = uv.y - Math.floor( uv.y );
					break;
R
rfm1201 已提交
290

R
Rich Harris 已提交
291
				case ClampToEdgeWrapping:
R
rfm1201 已提交
292

293 294
					uv.y = uv.y < 0 ? 0 : 1;
					break;
R
rfm1201 已提交
295

R
Rich Harris 已提交
296
				case MirroredRepeatWrapping:
R
rfm1201 已提交
297

298
					if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {
R
rfm1201 已提交
299

300
						uv.y = Math.ceil( uv.y ) - uv.y;
R
rfm1201 已提交
301

302
					} else {
R
rfm1201 已提交
303

304
						uv.y = uv.y - Math.floor( uv.y );
R
rfm1201 已提交
305

306 307
					}
					break;
R
rfm1201 已提交
308

309
			}
R
rfm1201 已提交
310

311 312 313
		}

		if ( this.flipY ) {
R
rfm1201 已提交
314

315
			uv.y = 1 - uv.y;
R
rfm1201 已提交
316

317
		}
R
rfm1201 已提交
318

319 320
		return uv;

321
	}
M
Mr.doob 已提交
322

323
} );
324

T
Takahiro 已提交
325 326 327 328 329 330 331 332 333 334
Object.defineProperty( Texture.prototype, "needsUpdate", {

	set: function ( value ) {

		if ( value === true ) this.version ++;

	}

} );

R
Rich Harris 已提交
335

336
export { Texture };