WebGLRenderer.js 83.1 KB
Newer Older
M
Mr.doob 已提交
1 2 3 4 5 6 7 8 9
/**
 * @author supereggbert / http://www.paulbrunt.co.uk/
 * @author mrdoob / http://mrdoob.com/
 * @author alteredq / http://alteredqualia.com/
 * @author szimek / https://github.com/szimek/
 */

THREE.WebGLRenderer = function ( parameters ) {

10
	console.log( 'THREE.WebGLRenderer', THREE.REVISION );
M
Mr.doob 已提交
11 12 13 14

	parameters = parameters || {};

	var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElement( 'canvas' ),
15
	_context = parameters.context !== undefined ? parameters.context : null,
M
Mr.doob 已提交
16

M
Mr.doob 已提交
17 18
	_width = _canvas.width,
	_height = _canvas.height,
19

20 21
	pixelRatio = 1,

22
	_alpha = parameters.alpha !== undefined ? parameters.alpha : false,
23
	_depth = parameters.depth !== undefined ? parameters.depth : true,
M
Mr.doob 已提交
24
	_stencil = parameters.stencil !== undefined ? parameters.stencil : true,
25 26
	_antialias = parameters.antialias !== undefined ? parameters.antialias : false,
	_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
M
Mr.doob 已提交
27 28
	_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,

29 30
	_clearColor = new THREE.Color( 0x000000 ),
	_clearAlpha = 0;
M
Mr.doob 已提交
31

M
Mr.doob 已提交
32
	var lights = [];
M
Mr.doob 已提交
33

O
OpenShift guest 已提交
34
	var opaqueObjects = [];
M
Mr.doob 已提交
35
	var opaqueObjectsLastIndex = - 1;
36
	var transparentObjects = [];
M
Mr.doob 已提交
37
	var transparentObjectsLastIndex = - 1;
38

39 40
	var morphInfluences = new Float32Array( 8 );

41

M
Mr.doob 已提交
42 43 44
	var sprites = [];
	var lensFlares = [];

M
Mr.doob 已提交
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
	// public properties

	this.domElement = _canvas;
	this.context = null;

	// clearing

	this.autoClear = true;
	this.autoClearColor = true;
	this.autoClearDepth = true;
	this.autoClearStencil = true;

	// scene graph

	this.sortObjects = true;

	// physically based shading

63
	this.gammaFactor = 2.0;	// for backwards compatibility
M
Mr.doob 已提交
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
	this.gammaInput = false;
	this.gammaOutput = false;

	// morphs

	this.maxMorphTargets = 8;
	this.maxMorphNormals = 4;

	// flags

	this.autoScaleCubemaps = true;

	// internal properties

	var _this = this,

	// internal state cache

	_currentProgram = null,
83
	_currentRenderTarget = null,
M
Mr.doob 已提交
84
	_currentFramebuffer = null,
85
	_currentMaterialId = - 1,
86
	_currentGeometryProgram = '',
M
Mr.doob 已提交
87 88 89 90
	_currentCamera = null,

	_usedTextureUnits = 0,

91 92 93
	_scissor = new THREE.Vector4( 0, 0, _canvas.width, _canvas.height ),
	_scissorTest = false,

M
Mr.doob 已提交
94
	_viewport = new THREE.Vector4( 0, 0, _canvas.width, _canvas.height ),
95

M
Mr.doob 已提交
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
	_currentWidth = 0,
	_currentHeight = 0,

	// frustum

	_frustum = new THREE.Frustum(),

	 // camera matrices cache

	_projScreenMatrix = new THREE.Matrix4(),

	_vector3 = new THREE.Vector3(),

	// light arrays cache

	_lights = {

113 114
		hash: '',

M
Mr.doob 已提交
115
		ambient: [ 0, 0, 0 ],
M
Mr.doob 已提交
116 117 118
		directional: [],
		point: [],
		spot: [],
119 120
		hemi: [],

121
		shadows: [],
122
		shadowsPointLight: 0
M
Mr.doob 已提交
123

124 125
	},

M
Mr.doob 已提交
126 127
	// info

128
	_infoMemory = {
129 130

		geometries: 0,
T
tschw 已提交
131
		textures: 0
132 133 134

	},

135
	_infoRender = {
136 137 138 139 140 141

		calls: 0,
		vertices: 0,
		faces: 0,
		points: 0

M
Mr.doob 已提交
142 143
	};

M
Mr.doob 已提交
144
	this.info = {
145

M
Mr.doob 已提交
146 147
		render: _infoRender,
		memory: _infoMemory,
148
		programs: null
M
Mr.doob 已提交
149 150

	};
151

152

M
Mr.doob 已提交
153 154 155 156
	// initialize

	var _gl;

M
Mr.doob 已提交
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
	try {

		var attributes = {
			alpha: _alpha,
			depth: _depth,
			stencil: _stencil,
			antialias: _antialias,
			premultipliedAlpha: _premultipliedAlpha,
			preserveDrawingBuffer: _preserveDrawingBuffer
		};

		_gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );

		if ( _gl === null ) {

G
gero3 已提交
172
			if ( _canvas.getContext( 'webgl' ) !== null ) {
173 174 175 176 177 178 179 180

				throw 'Error creating WebGL context with your selected attributes.';

			} else {

				throw 'Error creating WebGL context.';

			}
M
Mr.doob 已提交
181 182 183

		}

D
dubejf 已提交
184
		_canvas.addEventListener( 'webglcontextlost', onContextLost, false );
185

M
Mr.doob 已提交
186 187
	} catch ( error ) {

188
		console.error( 'THREE.WebGLRenderer: ' + error );
M
Mr.doob 已提交
189 190 191

	}

192 193
	var extensions = new THREE.WebGLExtensions( _gl );

194 195
	extensions.get( 'OES_texture_float' );
	extensions.get( 'OES_texture_float_linear' );
196 197
	extensions.get( 'OES_texture_half_float' );
	extensions.get( 'OES_texture_half_float_linear' );
198
	extensions.get( 'OES_standard_derivatives' );
B
Ben Adams 已提交
199
	extensions.get( 'ANGLE_instanced_arrays' );
200

201 202
	if ( extensions.get( 'OES_element_index_uint' ) ) {

203
		THREE.BufferGeometry.MaxIndex = 4294967296;
204 205 206

	}

M
Mr.doob 已提交
207
	var capabilities = new THREE.WebGLCapabilities( _gl, extensions, parameters );
M
Mr.doob 已提交
208

209 210 211
	var state = new THREE.WebGLState( _gl, extensions, paramThreeToGL );
	var properties = new THREE.WebGLProperties();
	var objects = new THREE.WebGLObjects( _gl, properties, this.info );
G
gero3 已提交
212
	var programCache = new THREE.WebGLPrograms( this, capabilities );
M
Mr.doob 已提交
213
	var lightCache = new THREE.WebGLLights();
214

215 216
	this.info.programs = programCache.programs;

217 218
	var bufferRenderer = new THREE.WebGLBufferRenderer( _gl, extensions, _infoRender );
	var indexedBufferRenderer = new THREE.WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
219

M
Mr.doob 已提交
220 221
	//

222 223 224 225 226 227
	function getTargetPixelRatio() {

		return _currentRenderTarget === null ? pixelRatio : 1;

	}

228
	function glClearColor( r, g, b, a ) {
229 230 231

		if ( _premultipliedAlpha === true ) {

232
			r *= a; g *= a; b *= a;
233 234 235

		}

236 237
		_gl.clearColor( r, g, b, a );

238
	}
239

240
	function setDefaultGLState() {
M
Mr.doob 已提交
241

M
Mr.doob 已提交
242
		state.init();
M
Mr.doob 已提交
243

244 245
		state.scissor( _scissor );
		state.viewport( _viewport );
M
Mr.doob 已提交
246

247
		glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
M
Mr.doob 已提交
248

249
	}
250

251
	function resetGLState() {
252 253 254 255

		_currentProgram = null;
		_currentCamera = null;

256
		_currentGeometryProgram = '';
257 258
		_currentMaterialId = - 1;

M
Mr.doob 已提交
259 260
		state.reset();

261
	}
M
Mr.doob 已提交
262 263 264 265

	setDefaultGLState();

	this.context = _gl;
M
Mr.doob 已提交
266
	this.capabilities = capabilities;
267
	this.extensions = extensions;
268
	this.properties = properties;
M
Mr.doob 已提交
269
	this.state = state;
M
Mr.doob 已提交
270

M
Mr.doob 已提交
271 272
	// shadow map

M
Mr.doob 已提交
273
	var shadowMap = new THREE.WebGLShadowMap( this, _lights, objects );
M
Mr.doob 已提交
274

275
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
276

M
Mr.doob 已提交
277

M
Mr.doob 已提交
278 279 280 281 282
	// Plugins

	var spritePlugin = new THREE.SpritePlugin( this, sprites );
	var lensFlarePlugin = new THREE.LensFlarePlugin( this, lensFlares );

M
Mr.doob 已提交
283 284 285 286 287 288 289 290
	// API

	this.getContext = function () {

		return _gl;

	};

291 292 293 294 295 296
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

297 298 299 300 301 302
	this.forceContextLoss = function () {

		extensions.get( 'WEBGL_lose_context' ).loseContext();

	};

303
	this.getMaxAnisotropy = ( function () {
M
Mr.doob 已提交
304

305
		var value;
M
Mr.doob 已提交
306

307
		return function getMaxAnisotropy() {
308

M
Mr.doob 已提交
309
			if ( value !== undefined ) return value;
310

M
Mr.doob 已提交
311
			var extension = extensions.get( 'EXT_texture_filter_anisotropic' );
312

M
Mr.doob 已提交
313
			if ( extension !== null ) {
314

M
Mr.doob 已提交
315
				value = _gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );
316

M
Mr.doob 已提交
317 318 319 320 321
			} else {

				value = 0;

			}
322 323 324

			return value;

M
Mr.doob 已提交
325
		};
326 327

	} )();
M
Mr.doob 已提交
328 329 330

	this.getPrecision = function () {

G
gero3 已提交
331
		return capabilities.precision;
M
Mr.doob 已提交
332 333 334

	};

335 336 337 338 339 340 341 342
	this.getPixelRatio = function () {

		return pixelRatio;

	};

	this.setPixelRatio = function ( value ) {

343
		if ( value !== undefined ) pixelRatio = value;
344 345 346

	};

347 348 349 350 351 352 353 354 355
	this.getSize = function () {

		return {
			width: _width,
			height: _height
		};

	};

356
	this.setSize = function ( width, height, updateStyle ) {
M
Mr.doob 已提交
357

358 359 360
		_width = width;
		_height = height;

361 362
		_canvas.width = width * pixelRatio;
		_canvas.height = height * pixelRatio;
363

364
		if ( updateStyle !== false ) {
365

G
gero3 已提交
366 367
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
368

G
gero3 已提交
369
		}
M
Mr.doob 已提交
370

371
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
372 373 374 375 376

	};

	this.setViewport = function ( x, y, width, height ) {

377
		_viewport.set( x, y, width, height ).multiplyScalar( pixelRatio );
378

379
		state.viewport( _viewport );
M
Mr.doob 已提交
380 381 382

	};

383
	this.setScissor = function ( x, y, width, height ) {
M
Mr.doob 已提交
384

385
		_scissor.set( x, y, width, height ).multiplyScalar( pixelRatio );
M
Mr.doob 已提交
386

387
		state.scissor( _scissor );
M
Mr.doob 已提交
388 389 390

	};

391 392 393
	this.setScissorTest = function ( boolean ) {

		_scissorTest = boolean;
M
Mr.doob 已提交
394

M
Mr.doob 已提交
395
		state.setScissorTest( boolean );
M
Mr.doob 已提交
396 397 398 399 400

	};

	// Clearing

M
Mr.doob 已提交
401
	this.getClearColor = function () {
M
Mr.doob 已提交
402

M
Mr.doob 已提交
403
		return _clearColor;
M
Mr.doob 已提交
404 405 406

	};

M
Mr.doob 已提交
407
	this.setClearColor = function ( color, alpha ) {
M
Mr.doob 已提交
408

M
Mr.doob 已提交
409
		_clearColor.set( color );
410

M
Mr.doob 已提交
411
		_clearAlpha = alpha !== undefined ? alpha : 1;
M
Mr.doob 已提交
412

413
		glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
M
Mr.doob 已提交
414 415 416

	};

M
Mr.doob 已提交
417
	this.getClearAlpha = function () {
M
Mr.doob 已提交
418

M
Mr.doob 已提交
419
		return _clearAlpha;
M
Mr.doob 已提交
420 421 422

	};

M
Mr.doob 已提交
423
	this.setClearAlpha = function ( alpha ) {
M
Mr.doob 已提交
424

M
Mr.doob 已提交
425
		_clearAlpha = alpha;
M
Mr.doob 已提交
426

427
		glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
M
Mr.doob 已提交
428 429 430 431 432 433 434 435 436 437 438 439

	};

	this.clear = function ( color, depth, stencil ) {

		var bits = 0;

		if ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;
		if ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;
		if ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;

		_gl.clear( bits );
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457

	};

	this.clearColor = function () {

		_gl.clear( _gl.COLOR_BUFFER_BIT );

	};

	this.clearDepth = function () {

		_gl.clear( _gl.DEPTH_BUFFER_BIT );

	};

	this.clearStencil = function () {

		_gl.clear( _gl.STENCIL_BUFFER_BIT );
M
Mr.doob 已提交
458 459 460 461 462 463 464 465 466 467

	};

	this.clearTarget = function ( renderTarget, color, depth, stencil ) {

		this.setRenderTarget( renderTarget );
		this.clear( color, depth, stencil );

	};

M
Mr.doob 已提交
468 469
	// Reset

470
	this.resetGLState = resetGLState;
M
Mr.doob 已提交
471

D
dubejf 已提交
472 473 474 475 476 477
	this.dispose = function() {

		_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );

	};

M
Mr.doob 已提交
478
	// Events
M
Mr.doob 已提交
479

D
dubejf 已提交
480 481 482 483 484 485 486 487 488
	function onContextLost( event ) {

		event.preventDefault();

		resetGLState();
		setDefaultGLState();

		properties.clear();

M
Mr.doob 已提交
489
	}
D
dubejf 已提交
490

491
	function onTextureDispose( event ) {
M
Mr.doob 已提交
492 493 494 495 496 497 498

		var texture = event.target;

		texture.removeEventListener( 'dispose', onTextureDispose );

		deallocateTexture( texture );

499
		_infoMemory.textures --;
M
Mr.doob 已提交
500 501


502
	}
M
Mr.doob 已提交
503

504
	function onRenderTargetDispose( event ) {
M
Mr.doob 已提交
505 506 507 508 509 510 511

		var renderTarget = event.target;

		renderTarget.removeEventListener( 'dispose', onRenderTargetDispose );

		deallocateRenderTarget( renderTarget );

512
		_infoMemory.textures --;
M
Mr.doob 已提交
513

514
	}
M
Mr.doob 已提交
515

516
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
517 518 519 520 521 522 523

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

524
	}
M
Mr.doob 已提交
525 526 527

	// Buffer deallocation

528
	function deallocateTexture( texture ) {
M
Mr.doob 已提交
529

530
		var textureProperties = properties.get( texture );
M
Mr.doob 已提交
531

532
		if ( texture.image && textureProperties.__image__webglTextureCube ) {
M
Mr.doob 已提交
533 534 535

			// cube texture

536
			_gl.deleteTexture( textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
537

538 539 540 541
		} else {

			// 2D texture

542
			if ( textureProperties.__webglInit === undefined ) return;
543

544
			_gl.deleteTexture( textureProperties.__webglTexture );
545

M
Mr.doob 已提交
546 547
		}

548
		// remove all webgl properties
549
		properties.delete( texture );
550

551
	}
M
Mr.doob 已提交
552

553
	function deallocateRenderTarget( renderTarget ) {
M
Mr.doob 已提交
554

555
		var renderTargetProperties = properties.get( renderTarget );
M
Mr.doob 已提交
556
		var textureProperties = properties.get( renderTarget.texture );
M
Mr.doob 已提交
557

M
Mr.doob 已提交
558
		if ( ! renderTarget || textureProperties.__webglTexture === undefined ) return;
M
Mr.doob 已提交
559

M
Mr.doob 已提交
560
		_gl.deleteTexture( textureProperties.__webglTexture );
M
Mr.doob 已提交
561

M
Mr.doob 已提交
562 563 564 565
		if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {

			for ( var i = 0; i < 6; i ++ ) {

566
				_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );
567
				_gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );
M
Mr.doob 已提交
568 569 570 571 572

			}

		} else {

573
			_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );
574
			_gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );
M
Mr.doob 已提交
575 576 577

		}

M
Mr.doob 已提交
578
		properties.delete( renderTarget.texture );
D
Daosheng Mu 已提交
579
		properties.delete( renderTarget );
M
Mr.doob 已提交
580

581
	}
M
Mr.doob 已提交
582

583
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
584

585 586 587 588
		releaseMaterialProgramReference( material );

		properties.delete( material );

589
	}
590 591


592
	function releaseMaterialProgramReference( material ) {
593

594
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
595 596 597

		material.program = undefined;

598
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
599

600
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
601

M
Mr.doob 已提交
602 603
		}

604
	}
M
Mr.doob 已提交
605 606 607 608 609

	// Buffer rendering

	this.renderBufferImmediate = function ( object, program, material ) {

610
		state.initAttributes();
611

612
		var buffers = properties.get( object );
613

614 615 616 617
		if ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();
		if ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();
		if ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();
		if ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();
M
Mr.doob 已提交
618

619
		var attributes = program.getAttributes();
620

M
Mr.doob 已提交
621 622
		if ( object.hasPositions ) {

623
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
M
Mr.doob 已提交
624
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
625

626 627
			state.enableAttribute( attributes.position );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
628 629 630 631 632

		}

		if ( object.hasNormals ) {

633
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );
M
Mr.doob 已提交
634

635
			if ( material.type !== 'MeshPhongMaterial' && material.type !== 'MeshStandardMaterial' && material.shading === THREE.FlatShading ) {
M
Mr.doob 已提交
636

637
				for ( var i = 0, l = object.count * 3; i < l; i += 9 ) {
M
Mr.doob 已提交
638

639
					var array = object.normalArray;
M
Mr.doob 已提交
640

641 642 643
					var nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;
					var ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;
					var nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;
M
Mr.doob 已提交
644

645 646 647
					array[ i + 0 ] = nx;
					array[ i + 1 ] = ny;
					array[ i + 2 ] = nz;
M
Mr.doob 已提交
648

649 650 651
					array[ i + 3 ] = nx;
					array[ i + 4 ] = ny;
					array[ i + 5 ] = nz;
M
Mr.doob 已提交
652

653 654 655
					array[ i + 6 ] = nx;
					array[ i + 7 ] = ny;
					array[ i + 8 ] = nz;
M
Mr.doob 已提交
656 657 658 659 660 661

				}

			}

			_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );
662

663
			state.enableAttribute( attributes.normal );
664

665
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
666 667 668 669 670

		}

		if ( object.hasUvs && material.map ) {

671
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
M
Mr.doob 已提交
672
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
673

674
			state.enableAttribute( attributes.uv );
675

676
			_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
677 678 679 680 681

		}

		if ( object.hasColors && material.vertexColors !== THREE.NoColors ) {

682
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
M
Mr.doob 已提交
683
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
684

685
			state.enableAttribute( attributes.color );
686

687
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
688 689 690

		}

691
		state.disableUnusedAttributes();
692

M
Mr.doob 已提交
693 694 695 696 697 698
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

699
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
700

M
Mr.doob 已提交
701 702
		setMaterial( material );

703
		var program = setProgram( camera, fog, material, object );
M
Mr.doob 已提交
704

M
Mr.doob 已提交
705 706
		var updateBuffers = false;
		var geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;
M
Mr.doob 已提交
707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729

		if ( geometryProgram !== _currentGeometryProgram ) {

			_currentGeometryProgram = geometryProgram;
			updateBuffers = true;

		}

		// morph targets

		var morphTargetInfluences = object.morphTargetInfluences;

		if ( morphTargetInfluences !== undefined ) {

			var activeInfluences = [];

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

				var influence = morphTargetInfluences[ i ];
				activeInfluences.push( [ influence, i ] );

			}

730
			activeInfluences.sort( absNumericalSort );
M
Mr.doob 已提交
731 732 733 734 735 736 737

			if ( activeInfluences.length > 8 ) {

				activeInfluences.length = 8;

			}

738 739
			var morphAttributes = geometry.morphAttributes;

M
Mr.doob 已提交
740 741 742 743 744 745 746
			for ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {

				var influence = activeInfluences[ i ];
				morphInfluences[ i ] = influence[ 0 ];

				if ( influence[ 0 ] !== 0 ) {

747
					var index = influence[ 1 ];
M
Mr.doob 已提交
748

749 750
					if ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );
					if ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );
M
Mr.doob 已提交
751 752 753

				} else {

754 755
					if ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );
					if ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );
M
Mr.doob 已提交
756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772

				}

			}

			var uniforms = program.getUniforms();

			if ( uniforms.morphTargetInfluences !== null ) {

				_gl.uniform1fv( uniforms.morphTargetInfluences, morphInfluences );

			}

			updateBuffers = true;

		}

M
Mr.doob 已提交
773 774
		//

775
		var index = geometry.index;
776 777
		var position = geometry.attributes.position;

778 779
		if ( material.wireframe === true ) {

780
			index = objects.getWireframeAttribute( geometry );
781 782 783

		}

784 785
		var renderer;

786
		if ( index !== null ) {
787

788 789
			renderer = indexedBufferRenderer;
			renderer.setIndex( index );
790

791
		} else {
792

793
			renderer = bufferRenderer;
794

795
		}
M
Mr.doob 已提交
796

797
		if ( updateBuffers ) {
M
Mr.doob 已提交
798

799
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
800

801
			if ( index !== null ) {
802

803
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );
804 805 806

			}

807
		}
808

M
Mr.doob 已提交
809
		//
810

M
Mr.doob 已提交
811 812
		var dataStart = 0;
		var dataCount = Infinity;
813

M
Mr.doob 已提交
814
		if ( index !== null ) {
815

M
Mr.doob 已提交
816
			dataCount = index.count;
817

M
Mr.doob 已提交
818
		} else if ( position !== undefined ) {
819

M
Mr.doob 已提交
820
			dataCount = position.count;
821

M
Mr.doob 已提交
822
		}
823

M
Mr.doob 已提交
824 825
		var rangeStart = geometry.drawRange.start;
		var rangeCount = geometry.drawRange.count;
826

M
Mr.doob 已提交
827 828
		var groupStart = group !== null ? group.start : 0;
		var groupCount = group !== null ? group.count : Infinity;
829

M
Mr.doob 已提交
830 831 832 833 834 835
		var drawStart = Math.max( dataStart, rangeStart, groupStart );
		var drawEnd = Math.min( dataStart + dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;

		var drawCount = Math.max( 0, drawEnd - drawStart + 1 );

		//
836

837
		if ( object instanceof THREE.Mesh ) {
838

839
			if ( material.wireframe === true ) {
840

841
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
842
				renderer.setMode( _gl.LINES );
843

844
			} else {
M
Mr.doob 已提交
845 846

				switch ( object.drawMode ) {
847

B
Ben Adams 已提交
848 849 850 851 852 853 854 855 856 857 858 859 860
					case THREE.TrianglesDrawMode:
						renderer.setMode( _gl.TRIANGLES );
						break;

					case THREE.TriangleStripDrawMode:
						renderer.setMode( _gl.TRIANGLE_STRIP );
						break;

					case THREE.TriangleFanDrawMode:
						renderer.setMode( _gl.TRIANGLE_FAN );
						break;

				}
861

862
			}
863

864

865
		} else if ( object instanceof THREE.Line ) {
866

867
			var lineWidth = material.linewidth;
868

869
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
870

871
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
872

873
			if ( object instanceof THREE.LineSegments ) {
874

875
				renderer.setMode( _gl.LINES );
876

877
			} else {
878

879
				renderer.setMode( _gl.LINE_STRIP );
880 881

			}
M
Mr.doob 已提交
882

883
		} else if ( object instanceof THREE.Points ) {
884 885

			renderer.setMode( _gl.POINTS );
886 887

		}
888

889 890 891 892 893 894
		if ( geometry instanceof THREE.InstancedBufferGeometry && geometry.maxInstancedCount > 0 ) {

			renderer.renderInstances( geometry, drawStart, drawCount );

		} else {

M
Mr.doob 已提交
895
			renderer.render( drawStart, drawCount );
896

M
Mr.doob 已提交
897 898 899 900
		}

	};

901
	function setupVertexAttributes( material, program, geometry, startIndex ) {
M
Mr.doob 已提交
902

M
Mr.doob 已提交
903
		var extension;
B
Ben Adams 已提交
904

M
Mr.doob 已提交
905
		if ( geometry instanceof THREE.InstancedBufferGeometry ) {
B
Ben Adams 已提交
906

M
Mr.doob 已提交
907
			extension = extensions.get( 'ANGLE_instanced_arrays' );
B
Ben Adams 已提交
908

M
Mr.doob 已提交
909
			if ( extension === null ) {
B
Ben Adams 已提交
910

911
				console.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
M
Mr.doob 已提交
912
				return;
B
Ben Adams 已提交
913

M
Mr.doob 已提交
914 915 916
			}

		}
B
Ben Adams 已提交
917

918 919
		if ( startIndex === undefined ) startIndex = 0;

920 921
		state.initAttributes();

922
		var geometryAttributes = geometry.attributes;
923

924
		var programAttributes = program.getAttributes();
925

926
		var materialDefaultAttributeValues = material.defaultAttributeValues;
927

928
		for ( var name in programAttributes ) {
929

930
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
931

M
Mr.doob 已提交
932
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
933

934
				var geometryAttribute = geometryAttributes[ name ];
935

M
Mr.doob 已提交
936
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
937

938
					var size = geometryAttribute.itemSize;
G
gero3 已提交
939
					var buffer = objects.getAttributeBuffer( geometryAttribute );
940

B
Ben Adams 已提交
941
					if ( geometryAttribute instanceof THREE.InterleavedBufferAttribute ) {
942

M
Mr.doob 已提交
943 944 945 946 947
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

						if ( data instanceof THREE.InstancedInterleavedBuffer ) {
M
Mr.doob 已提交
948

M
Mr.doob 已提交
949
							state.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension );
B
Ben Adams 已提交
950

M
Mr.doob 已提交
951
							if ( geometry.maxInstancedCount === undefined ) {
952

D
dubejf 已提交
953
								geometry.maxInstancedCount = data.meshPerAttribute * data.count;
B
Ben Adams 已提交
954

M
Mr.doob 已提交
955
							}
B
Ben Adams 已提交
956

M
Mr.doob 已提交
957
						} else {
B
Ben Adams 已提交
958

M
Mr.doob 已提交
959
							state.enableAttribute( programAttribute );
B
Ben Adams 已提交
960

M
Mr.doob 已提交
961
						}
B
Ben Adams 已提交
962

M
Mr.doob 已提交
963 964
						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
						_gl.vertexAttribPointer( programAttribute, size, _gl.FLOAT, false, stride * data.array.BYTES_PER_ELEMENT, ( startIndex * stride + offset ) * data.array.BYTES_PER_ELEMENT );
B
Ben Adams 已提交
965

M
Mr.doob 已提交
966
					} else {
B
Ben Adams 已提交
967

M
Mr.doob 已提交
968
						if ( geometryAttribute instanceof THREE.InstancedBufferAttribute ) {
B
Ben Adams 已提交
969

M
Mr.doob 已提交
970
							state.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension );
B
Ben Adams 已提交
971

M
Mr.doob 已提交
972
							if ( geometry.maxInstancedCount === undefined ) {
B
Ben Adams 已提交
973

D
dubejf 已提交
974
								geometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;
B
Ben Adams 已提交
975

M
Mr.doob 已提交
976
							}
B
Ben Adams 已提交
977

M
Mr.doob 已提交
978 979 980 981
						} else {

							state.enableAttribute( programAttribute );

M
Mr.doob 已提交
982
						}
B
Ben Adams 已提交
983

M
Mr.doob 已提交
984 985 986
						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
						_gl.vertexAttribPointer( programAttribute, size, _gl.FLOAT, false, 0, startIndex * size * 4 ); // 4 bytes per Float32

B
Ben Adams 已提交
987
					}
M
Mr.doob 已提交
988

989 990
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
991
					var value = materialDefaultAttributeValues[ name ];
992

993
					if ( value !== undefined ) {
M
Mr.doob 已提交
994

995
						switch ( value.length ) {
M
Mr.doob 已提交
996

997 998 999
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
1000

1001 1002 1003
							case 3:
								_gl.vertexAttrib3fv( programAttribute, value );
								break;
M
Mr.doob 已提交
1004

1005 1006 1007
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
1008

1009 1010
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
1011 1012

						}
M
Mr.doob 已提交
1013 1014 1015 1016 1017 1018 1019 1020

					}

				}

			}

		}
1021

1022
		state.disableUnusedAttributes();
1023

M
Mr.doob 已提交
1024 1025
	}

M
Mr.doob 已提交
1026 1027
	// Sorting

1028
	function absNumericalSort( a, b ) {
1029

1030
		return Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );
1031 1032 1033

	}

M
Mr.doob 已提交
1034 1035
	function painterSortStable ( a, b ) {

U
unconed 已提交
1036
		if ( a.object.renderOrder !== b.object.renderOrder ) {
1037

U
unconed 已提交
1038
			return a.object.renderOrder - b.object.renderOrder;
1039

M
Mr.doob 已提交
1040
		} else if ( a.material.id !== b.material.id ) {
M
Mr.doob 已提交
1041

M
Mr.doob 已提交
1042
			return a.material.id - b.material.id;
1043 1044

		} else if ( a.z !== b.z ) {
M
Mr.doob 已提交
1045

M
Mr.doob 已提交
1046
			return a.z - b.z;
M
Mr.doob 已提交
1047 1048 1049

		} else {

1050
			return a.id - b.id;
M
Mr.doob 已提交
1051 1052 1053

		}

1054
	}
M
Mr.doob 已提交
1055

1056 1057
	function reversePainterSortStable ( a, b ) {

U
unconed 已提交
1058
		if ( a.object.renderOrder !== b.object.renderOrder ) {
1059

U
unconed 已提交
1060
			return a.object.renderOrder - b.object.renderOrder;
1061 1062

		} if ( a.z !== b.z ) {
1063

M
Mr.doob 已提交
1064
			return b.z - a.z;
1065 1066 1067 1068 1069 1070 1071

		} else {

			return a.id - b.id;

		}

1072
	}
1073

M
Mr.doob 已提交
1074 1075 1076 1077 1078 1079
	// Rendering

	this.render = function ( scene, camera, renderTarget, forceClear ) {

		if ( camera instanceof THREE.Camera === false ) {

1080
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1081 1082 1083 1084
			return;

		}

M
Mr.doob 已提交
1085
		var fog = scene.fog;
M
Mr.doob 已提交
1086 1087 1088

		// reset caching for this frame

1089
		_currentGeometryProgram = '';
1090
		_currentMaterialId = - 1;
1091
		_currentCamera = null;
M
Mr.doob 已提交
1092 1093 1094

		// update scene graph

1095
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1096 1097 1098

		// update camera matrices and frustum

1099
		if ( camera.parent === null ) camera.updateMatrixWorld();
M
Mr.doob 已提交
1100 1101 1102 1103 1104 1105

		camera.matrixWorldInverse.getInverse( camera.matrixWorld );

		_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
		_frustum.setFromMatrix( _projScreenMatrix );

M
Mr.doob 已提交
1106
		lights.length = 0;
1107

M
Mr.doob 已提交
1108 1109
		opaqueObjectsLastIndex = - 1;
		transparentObjectsLastIndex = - 1;
1110

M
Mr.doob 已提交
1111 1112 1113
		sprites.length = 0;
		lensFlares.length = 0;

1114
		projectObject( scene, camera );
M
Mr.doob 已提交
1115

1116 1117 1118
		opaqueObjects.length = opaqueObjectsLastIndex + 1;
		transparentObjects.length = transparentObjectsLastIndex + 1;

M
Mr.doob 已提交
1119
		if ( _this.sortObjects === true ) {
1120 1121 1122

			opaqueObjects.sort( painterSortStable );
			transparentObjects.sort( reversePainterSortStable );
M
Mr.doob 已提交
1123

1124 1125
		}

1126 1127
		setupLights( lights, camera );

M
Mr.doob 已提交
1128
		//
M
Mr.doob 已提交
1129

M
Mr.doob 已提交
1130
		shadowMap.render( scene, camera );
M
Mr.doob 已提交
1131 1132 1133

		//

1134 1135 1136 1137
		_infoRender.calls = 0;
		_infoRender.vertices = 0;
		_infoRender.faces = 0;
		_infoRender.points = 0;
M
Mr.doob 已提交
1138

1139 1140 1141 1142 1143 1144
		if ( renderTarget === undefined ) {

			renderTarget = null;

		}

M
Mr.doob 已提交
1145 1146 1147 1148 1149 1150 1151 1152
		this.setRenderTarget( renderTarget );

		if ( this.autoClear || forceClear ) {

			this.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );

		}

1153
		//
M
Mr.doob 已提交
1154 1155 1156

		if ( scene.overrideMaterial ) {

1157
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1158

1159 1160
			renderObjects( opaqueObjects, camera, fog, overrideMaterial );
			renderObjects( transparentObjects, camera, fog, overrideMaterial );
1161

M
Mr.doob 已提交
1162 1163 1164 1165
		} else {

			// opaque pass (front-to-back order)

M
Mr.doob 已提交
1166
			state.setBlending( THREE.NoBlending );
1167
			renderObjects( opaqueObjects, camera, fog );
M
Mr.doob 已提交
1168 1169 1170

			// transparent pass (back-to-front order)

1171
			renderObjects( transparentObjects, camera, fog );
M
Mr.doob 已提交
1172 1173 1174 1175 1176

		}

		// custom render plugins (post pass)

M
Mr.doob 已提交
1177 1178
		spritePlugin.render( scene, camera );
		lensFlarePlugin.render( scene, camera, _currentWidth, _currentHeight );
M
Mr.doob 已提交
1179 1180 1181

		// Generate mipmap if we're using any kind of mipmap filtering

M
Mr.doob 已提交
1182 1183 1184
		if ( renderTarget ) {

			var texture = renderTarget.texture;
M
Mr.doob 已提交
1185

M
Mr.doob 已提交
1186 1187 1188 1189 1190
			if ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&
					texture.minFilter !== THREE.NearestFilter &&
					texture.minFilter !== THREE.LinearFilter ) {

				updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1191 1192

			}
M
Mr.doob 已提交
1193 1194 1195 1196 1197

		}

		// Ensure depth buffer writing is enabled so it can be cleared on next render

M
Mr.doob 已提交
1198 1199
		state.setDepthTest( true );
		state.setDepthWrite( true );
1200
		state.setColorWrite( true );
M
Mr.doob 已提交
1201 1202 1203 1204

		// _gl.finish();

	};
M
Mr.doob 已提交
1205

M
Mr.doob 已提交
1206 1207
	function pushRenderItem( object, geometry, material, z, group ) {

1208
		var array, index;
M
Mr.doob 已提交
1209

1210
		// allocate the next position in the appropriate array
M
Mr.doob 已提交
1211 1212 1213

		if ( material.transparent ) {

1214 1215
			array = transparentObjects;
			index = ++ transparentObjectsLastIndex;
M
Mr.doob 已提交
1216 1217 1218

		} else {

1219 1220 1221 1222 1223
			array = opaqueObjects;
			index = ++ opaqueObjectsLastIndex;

		}

1224 1225
		// recycle existing render item or grow the array

1226 1227 1228 1229 1230 1231 1232 1233 1234 1235
		var renderItem = array[ index ];

		if ( renderItem !== undefined ) {

			renderItem.id = object.id;
			renderItem.object = object;
			renderItem.geometry = geometry;
			renderItem.material = material;
			renderItem.z = _vector3.z;
			renderItem.group = group;
M
Mr.doob 已提交
1236 1237 1238

		} else {

1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249
			renderItem = {
				id: object.id,
				object: object,
				geometry: geometry,
				material: material,
				z: _vector3.z,
				group: group
			};

			// assert( index === array.length );
			array.push( renderItem );
M
Mr.doob 已提交
1250 1251 1252 1253 1254

		}

	}

1255
	function projectObject( object, camera ) {
M
Mr.doob 已提交
1256

M
Mr.doob 已提交
1257
		if ( object.visible === false ) return;
M
Mr.doob 已提交
1258

1259
		if ( object.layers.test( camera.layers ) ) {
M
Mr.doob 已提交
1260

1261
			if ( object instanceof THREE.Light ) {
M
Mr.doob 已提交
1262

1263
				lights.push( object );
M
Mr.doob 已提交
1264

1265
			} else if ( object instanceof THREE.Sprite ) {
M
Mr.doob 已提交
1266

1267 1268 1269 1270 1271
				if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) {

					sprites.push( object );

				}
M
Mr.doob 已提交
1272

1273
			} else if ( object instanceof THREE.LensFlare ) {
M
Mr.doob 已提交
1274

1275
				lensFlares.push( object );
M
Mr.doob 已提交
1276

1277
			} else if ( object instanceof THREE.ImmediateRenderObject ) {
M
Mr.doob 已提交
1278

1279
				if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1280

1281 1282
					_vector3.setFromMatrixPosition( object.matrixWorld );
					_vector3.applyProjection( _projScreenMatrix );
M
Mr.doob 已提交
1283

1284
				}
1285

1286
				pushRenderItem( object, null, object.material, _vector3.z, null );
M
Mr.doob 已提交
1287

1288
			} else if ( object instanceof THREE.Mesh || object instanceof THREE.Line || object instanceof THREE.Points ) {
M
Mr.doob 已提交
1289

1290
				if ( object instanceof THREE.SkinnedMesh ) {
M
Mr.doob 已提交
1291

1292
					object.skeleton.update();
1293

1294
				}
1295

1296
				if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) {
1297

1298
					var material = object.material;
1299

1300
					if ( material.visible === true ) {
M
Mr.doob 已提交
1301

1302
						if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1303

1304 1305 1306 1307
							_vector3.setFromMatrixPosition( object.matrixWorld );
							_vector3.applyProjection( _projScreenMatrix );

						}
M
Mr.doob 已提交
1308

1309
						var geometry = objects.update( object );
M
Mr.doob 已提交
1310

S
SUNAG 已提交
1311
						if ( material instanceof THREE.MultiMaterial ) {
1312

1313 1314
							var groups = geometry.groups;
							var materials = material.materials;
1315

1316
							for ( var i = 0, l = groups.length; i < l; i ++ ) {
1317

1318 1319
								var group = groups[ i ];
								var groupMaterial = materials[ group.materialIndex ];
1320

1321
								if ( groupMaterial.visible === true ) {
1322

1323 1324 1325
									pushRenderItem( object, geometry, groupMaterial, _vector3.z, group );

								}
M
Mr.doob 已提交
1326

M
Mr.doob 已提交
1327
							}
M
Mr.doob 已提交
1328

1329
						} else {
M
Mr.doob 已提交
1330

1331
							pushRenderItem( object, geometry, material, _vector3.z, null );
1332

1333
						}
O
OpenShift guest 已提交
1334

1335
					}
M
Mr.doob 已提交
1336

1337
				}
M
Mr.doob 已提交
1338

1339
			}
M
Mr.doob 已提交
1340

M
Mr.doob 已提交
1341
		}
M
Mr.doob 已提交
1342

M
Mr.doob 已提交
1343
		var children = object.children;
M
Mr.doob 已提交
1344

M
Mr.doob 已提交
1345 1346
		for ( var i = 0, l = children.length; i < l; i ++ ) {

1347
			projectObject( children[ i ], camera );
M
Mr.doob 已提交
1348

1349
		}
1350

1351
	}
M
Mr.doob 已提交
1352

1353
	function renderObjects( renderList, camera, fog, overrideMaterial ) {
M
Mr.doob 已提交
1354

M
Mr.doob 已提交
1355
		for ( var i = 0, l = renderList.length; i < l; i ++ ) {
M
Mr.doob 已提交
1356

1357
			var renderItem = renderList[ i ];
M
Mr.doob 已提交
1358

1359
			var object = renderItem.object;
M
Mr.doob 已提交
1360 1361 1362
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
M
Mr.doob 已提交
1363

1364 1365
			object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
			object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
M
Mr.doob 已提交
1366

M
Mr.doob 已提交
1367
			if ( object instanceof THREE.ImmediateRenderObject ) {
M
Mr.doob 已提交
1368

M
Mr.doob 已提交
1369
				setMaterial( material );
M
Mr.doob 已提交
1370

1371
				var program = setProgram( camera, fog, material, object );
M
Mr.doob 已提交
1372

M
Mr.doob 已提交
1373
				_currentGeometryProgram = '';
M
Mr.doob 已提交
1374

M
Mr.doob 已提交
1375
				object.render( function ( object ) {
M
Mr.doob 已提交
1376

M
Mr.doob 已提交
1377
					_this.renderBufferImmediate( object, program, material );
M
Mr.doob 已提交
1378

M
Mr.doob 已提交
1379
				} );
1380

M
Mr.doob 已提交
1381
			} else {
M
Mr.doob 已提交
1382

1383
				_this.renderBufferDirect( camera, fog, geometry, material, object, group );
M
Mr.doob 已提交
1384

M
Mr.doob 已提交
1385
			}
M
Mr.doob 已提交
1386

1387
		}
M
Mr.doob 已提交
1388

1389
	}
G
gero3 已提交
1390

1391
	function initMaterial( material, fog, object ) {
M
Mr.doob 已提交
1392

1393
		var materialProperties = properties.get( material );
G
gero3 已提交
1394

1395
		var parameters = programCache.getParameters( material, _lights, fog, object );
G
gero3 已提交
1396
		var code = programCache.getProgramCode( material, parameters );
G
gero3 已提交
1397

1398
		var program = materialProperties.program;
T
tschw 已提交
1399
		var programChange = true;
1400

1401
		if ( program === undefined ) {
B
Ben Adams 已提交
1402

M
Mr.doob 已提交
1403 1404
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1405

1406
		} else if ( program.code !== code ) {
B
Ben Adams 已提交
1407

M
Mr.doob 已提交
1408
			// changed glsl or parameters
1409
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1410

G
gero3 已提交
1411
		} else if ( parameters.shaderID !== undefined ) {
B
Ben Adams 已提交
1412

T
tschw 已提交
1413
			// same glsl and uniform list
T
tschw 已提交
1414 1415
			return;

T
tschw 已提交
1416
		} else {
B
Ben Adams 已提交
1417

T
tschw 已提交
1418 1419
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1420 1421 1422

		}

1423
		if ( programChange ) {
B
Ben Adams 已提交
1424

1425
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1426

1427
				var shader = THREE.ShaderLib[ parameters.shaderID ];
B
Ben Adams 已提交
1428

1429 1430 1431 1432 1433 1434
				materialProperties.__webglShader = {
					name: material.type,
					uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
					vertexShader: shader.vertexShader,
					fragmentShader: shader.fragmentShader
				};
B
Ben Adams 已提交
1435

1436
			} else {
B
Ben Adams 已提交
1437

1438 1439 1440 1441 1442 1443
				materialProperties.__webglShader = {
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
					fragmentShader: material.fragmentShader
				};
G
gero3 已提交
1444

1445
			}
G
gero3 已提交
1446

1447
			material.__webglShader = materialProperties.__webglShader;
G
gero3 已提交
1448

1449
			program = programCache.acquireProgram( material, parameters, code );
B
Ben Adams 已提交
1450

1451 1452
			materialProperties.program = program;
			material.program = program;
1453 1454 1455

		}

1456
		var attributes = program.getAttributes();
M
Mr.doob 已提交
1457 1458 1459 1460 1461

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

1462
			for ( var i = 0; i < _this.maxMorphTargets; i ++ ) {
M
Mr.doob 已提交
1463

M
Mr.doob 已提交
1464
				if ( attributes[ 'morphTarget' + i ] >= 0 ) {
M
Mr.doob 已提交
1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

M
Mr.doob 已提交
1478
			for ( var i = 0; i < _this.maxMorphNormals; i ++ ) {
M
Mr.doob 已提交
1479

M
Mr.doob 已提交
1480
				if ( attributes[ 'morphNormal' + i ] >= 0 ) {
M
Mr.doob 已提交
1481 1482 1483 1484 1485 1486 1487 1488 1489

					material.numSupportedMorphNormals ++;

				}

			}

		}

1490
		materialProperties.uniformsList = [];
M
Mr.doob 已提交
1491

1492 1493
		var uniforms = materialProperties.__webglShader.uniforms,
			uniformLocations = materialProperties.program.getUniforms();
M
Mr.doob 已提交
1494

1495
		for ( var u in uniforms ) {
M
Mr.doob 已提交
1496

1497
			var location = uniformLocations[ u ];
1498 1499

			if ( location ) {
G
gero3 已提交
1500

1501
				materialProperties.uniformsList.push( [ materialProperties.__webglShader.uniforms[ u ], location ] );
G
gero3 已提交
1502

1503
			}
M
Mr.doob 已提交
1504 1505 1506

		}

1507 1508
		if ( material instanceof THREE.MeshPhongMaterial ||
				material instanceof THREE.MeshLambertMaterial ||
1509
				material instanceof THREE.MeshStandardMaterial ||
1510 1511
				material.lights ) {

1512 1513
			// store the light setup it was created for

1514 1515
			materialProperties.lightsHash = _lights.hash;

1516 1517 1518 1519 1520 1521 1522 1523 1524 1525
			// wire up the material to this renderer's lighting state

			uniforms.ambientLightColor.value = _lights.ambient;
			uniforms.directionalLights.value = _lights.directional;
			uniforms.pointLights.value = _lights.point;
			uniforms.spotLights.value = _lights.spot;
			uniforms.hemisphereLights.value = _lights.hemi;

		}

A
arose 已提交
1526 1527 1528 1529 1530 1531 1532 1533
		// detect dynamic uniforms

		materialProperties.hasDynamicUniforms = false;

		for ( var j = 0, jl = materialProperties.uniformsList.length; j < jl; j ++ ) {

			var uniform = materialProperties.uniformsList[ j ][ 0 ];

1534
			if ( uniform.dynamic === true ) {
A
arose 已提交
1535 1536 1537 1538 1539 1540 1541 1542

				materialProperties.hasDynamicUniforms = true;
				break;

			}

		}

M
Mr.doob 已提交
1543
	}
M
Mr.doob 已提交
1544

1545 1546
	function setMaterial( material ) {

M
Mr.doob 已提交
1547 1548
		setMaterialFaces( material );

1549 1550
		if ( material.transparent === true ) {

M
Mr.doob 已提交
1551
			state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha );
1552

1553 1554 1555 1556
		} else {

			state.setBlending( THREE.NoBlending );

1557 1558
		}

B
Ben Adams 已提交
1559
		state.setDepthFunc( material.depthFunc );
M
Mr.doob 已提交
1560 1561
		state.setDepthTest( material.depthTest );
		state.setDepthWrite( material.depthWrite );
1562
		state.setColorWrite( material.colorWrite );
M
Mr.doob 已提交
1563
		state.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
1564 1565 1566

	}

M
Mr.doob 已提交
1567 1568
	function setMaterialFaces( material ) {

1569
		material.side !== THREE.DoubleSide ? state.enable( _gl.CULL_FACE ) : state.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
1570 1571 1572 1573
		state.setFlipSided( material.side === THREE.BackSide );

	}

1574
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1575 1576 1577

		_usedTextureUnits = 0;

1578
		var materialProperties = properties.get( material );
1579

1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593
		if ( materialProperties.program === undefined ) {

			material.needsUpdate = true;

		}

		if ( materialProperties.lightsHash !== undefined &&
			materialProperties.lightsHash !== _lights.hash ) {

			material.needsUpdate = true;

		}

		if ( material.needsUpdate ) {
M
Mr.doob 已提交
1594

1595
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1596 1597 1598 1599
			material.needsUpdate = false;

		}

1600
		var refreshProgram = false;
M
Mr.doob 已提交
1601
		var refreshMaterial = false;
1602
		var refreshLights = false;
M
Mr.doob 已提交
1603

1604
		var program = materialProperties.program,
1605
			p_uniforms = program.getUniforms(),
1606
			m_uniforms = materialProperties.__webglShader.uniforms;
M
Mr.doob 已提交
1607

1608
		if ( program.id !== _currentProgram ) {
M
Mr.doob 已提交
1609

1610 1611
			_gl.useProgram( program.program );
			_currentProgram = program.id;
M
Mr.doob 已提交
1612

1613
			refreshProgram = true;
M
Mr.doob 已提交
1614
			refreshMaterial = true;
1615
			refreshLights = true;
M
Mr.doob 已提交
1616 1617 1618 1619 1620 1621

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1622

M
Mr.doob 已提交
1623 1624 1625 1626
			refreshMaterial = true;

		}

1627
		if ( refreshProgram || camera !== _currentCamera ) {
M
Mr.doob 已提交
1628 1629 1630

			_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, camera.projectionMatrix.elements );

G
gero3 已提交
1631
			if ( capabilities.logarithmicDepthBuffer ) {
1632

1633
				_gl.uniform1f( p_uniforms.logDepthBufFC, 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1634 1635 1636 1637

			}


1638 1639 1640 1641 1642 1643 1644 1645 1646
			if ( camera !== _currentCamera ) {

				_currentCamera = camera;

				// lighting uniforms depend on the camera so enforce an update
				// now, in case this material supports lights - or later, when
				// the next material that does gets activated:

				refreshMaterial = true;		// set to true on material change
T
tschw 已提交
1647
				refreshLights = true;		// remains set until update done
1648 1649

			}
M
Mr.doob 已提交
1650

1651 1652 1653 1654 1655
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
1656
				 material instanceof THREE.MeshStandardMaterial ||
1657 1658
				 material.envMap ) {

1659
				if ( p_uniforms.cameraPosition !== undefined ) {
1660 1661 1662 1663 1664 1665 1666 1667 1668 1669

					_vector3.setFromMatrixPosition( camera.matrixWorld );
					_gl.uniform3f( p_uniforms.cameraPosition, _vector3.x, _vector3.y, _vector3.z );

				}

			}

			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
1670
				 material instanceof THREE.MeshBasicMaterial ||
1671
				 material instanceof THREE.MeshStandardMaterial ||
1672 1673 1674
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {

1675
				if ( p_uniforms.viewMatrix !== undefined ) {
1676 1677

					_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, camera.matrixWorldInverse.elements );
M
Mr.doob 已提交
1678

1679 1680 1681 1682
				}

			}

M
Mr.doob 已提交
1683 1684 1685 1686 1687 1688 1689 1690
		}

		// skinning uniforms must be set even if material didn't change
		// auto-setting of texture unit for bone texture must go before other textures
		// not sure why, but otherwise weird things happen

		if ( material.skinning ) {

1691
			if ( object.bindMatrix && p_uniforms.bindMatrix !== undefined ) {
1692 1693 1694 1695 1696

				_gl.uniformMatrix4fv( p_uniforms.bindMatrix, false, object.bindMatrix.elements );

			}

1697
			if ( object.bindMatrixInverse && p_uniforms.bindMatrixInverse !== undefined ) {
1698 1699 1700 1701 1702

				_gl.uniformMatrix4fv( p_uniforms.bindMatrixInverse, false, object.bindMatrixInverse.elements );

			}

1703
			if ( capabilities.floatVertexTextures && object.skeleton && object.skeleton.useVertexTexture ) {
M
Mr.doob 已提交
1704

1705
				if ( p_uniforms.boneTexture !== undefined ) {
M
Mr.doob 已提交
1706 1707 1708 1709

					var textureUnit = getTextureUnit();

					_gl.uniform1i( p_uniforms.boneTexture, textureUnit );
1710
					_this.setTexture( object.skeleton.boneTexture, textureUnit );
M
Mr.doob 已提交
1711 1712 1713

				}

1714
				if ( p_uniforms.boneTextureWidth !== undefined ) {
1715

1716
					_gl.uniform1i( p_uniforms.boneTextureWidth, object.skeleton.boneTextureWidth );
1717 1718 1719

				}

1720
				if ( p_uniforms.boneTextureHeight !== undefined ) {
1721

1722
					_gl.uniform1i( p_uniforms.boneTextureHeight, object.skeleton.boneTextureHeight );
1723 1724 1725

				}

1726
			} else if ( object.skeleton && object.skeleton.boneMatrices ) {
M
Mr.doob 已提交
1727

1728
				if ( p_uniforms.boneGlobalMatrices !== undefined ) {
M
Mr.doob 已提交
1729

1730
					_gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.skeleton.boneMatrices );
M
Mr.doob 已提交
1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741

				}

			}

		}

		if ( refreshMaterial ) {

			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
1742
				 material instanceof THREE.MeshStandardMaterial ||
M
Mr.doob 已提交
1743 1744
				 material.lights ) {

1745
				// the current material requires lighting info
M
Mr.doob 已提交
1746

T
tschw 已提交
1747 1748 1749 1750 1751 1752
				// note: all lighting uniforms are always set correctly
				// they simply reference the renderer's state for their
				// values
				//
				// use the current material's .needsUpdate flags to set
				// the GL state when required
M
Mr.doob 已提交
1753

T
tschw 已提交
1754
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1755

T
tschw 已提交
1756
			}
G
gero3 已提交
1757

T
tschw 已提交
1758
			// refresh uniforms common to several materials
G
gero3 已提交
1759

T
tschw 已提交
1760
			if ( fog && material.fog ) {
G
gero3 已提交
1761

T
tschw 已提交
1762
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1763 1764 1765 1766 1767

			}

			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
W
WestLangley 已提交
1768
				 material instanceof THREE.MeshPhongMaterial ||
1769
				 material instanceof THREE.MeshStandardMaterial ) {
M
Mr.doob 已提交
1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785

				refreshUniformsCommon( m_uniforms, material );

			}

			// refresh single material specific uniforms

			if ( material instanceof THREE.LineBasicMaterial ) {

				refreshUniformsLine( m_uniforms, material );

			} else if ( material instanceof THREE.LineDashedMaterial ) {

				refreshUniformsLine( m_uniforms, material );
				refreshUniformsDash( m_uniforms, material );

1786
			} else if ( material instanceof THREE.PointsMaterial ) {
M
Mr.doob 已提交
1787

M
Mr.doob 已提交
1788
				refreshUniformsPoints( m_uniforms, material );
M
Mr.doob 已提交
1789

1790 1791 1792 1793
			} else if ( material instanceof THREE.MeshLambertMaterial ) {

				refreshUniformsLambert( m_uniforms, material );

M
Mr.doob 已提交
1794 1795 1796 1797
			} else if ( material instanceof THREE.MeshPhongMaterial ) {

				refreshUniformsPhong( m_uniforms, material );

1798
			} else if ( material instanceof THREE.MeshStandardMaterial ) {
W
WestLangley 已提交
1799

1800
				refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1801

M
Mr.doob 已提交
1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813
			} else if ( material instanceof THREE.MeshDepthMaterial ) {

				m_uniforms.mNear.value = camera.near;
				m_uniforms.mFar.value = camera.far;
				m_uniforms.opacity.value = material.opacity;

			} else if ( material instanceof THREE.MeshNormalMaterial ) {

				m_uniforms.opacity.value = material.opacity;

			}

M
Mr.doob 已提交
1814
			if ( shadowMap.enabled ) {
M
Mr.doob 已提交
1815

1816 1817
				if ( object.receiveShadow && ! material._shadowPass ) {

1818
					refreshUniformsShadow( m_uniforms, camera );
1819 1820

				}
M
Mr.doob 已提交
1821 1822 1823 1824 1825

			}

			// load common uniforms

1826
			loadUniformsGeneric( materialProperties.uniformsList );
M
Mr.doob 已提交
1827 1828 1829 1830 1831

		}

		loadUniformsMatrices( p_uniforms, object );

1832
		if ( p_uniforms.modelMatrix !== undefined ) {
M
Mr.doob 已提交
1833 1834

			_gl.uniformMatrix4fv( p_uniforms.modelMatrix, false, object.matrixWorld.elements );
M
Mr.doob 已提交
1835

M
Mr.doob 已提交
1836 1837
		}

1838
		if ( materialProperties.hasDynamicUniforms === true ) {
A
arose 已提交
1839

1840
			updateDynamicUniforms( materialProperties.uniformsList, object, camera );
A
arose 已提交
1841 1842 1843

		}

M
Mr.doob 已提交
1844 1845
		return program;

M
Mr.doob 已提交
1846
	}
M
Mr.doob 已提交
1847

1848
	function updateDynamicUniforms ( uniforms, object, camera ) {
A
arose 已提交
1849 1850 1851 1852 1853 1854

		var dynamicUniforms = [];

		for ( var j = 0, jl = uniforms.length; j < jl; j ++ ) {

			var uniform = uniforms[ j ][ 0 ];
1855
			var onUpdateCallback = uniform.onUpdateCallback;
A
arose 已提交
1856

1857
			if ( onUpdateCallback !== undefined ) {
A
arose 已提交
1858

1859
				onUpdateCallback.bind( uniform )( object, camera );
A
arose 已提交
1860 1861 1862 1863 1864 1865 1866 1867 1868 1869
				dynamicUniforms.push( uniforms[ j ] );

			}

		}

		loadUniformsGeneric( dynamicUniforms );

	}

M
Mr.doob 已提交
1870 1871 1872 1873 1874 1875
	// Uniforms (refresh uniforms objects)

	function refreshUniformsCommon ( uniforms, material ) {

		uniforms.opacity.value = material.opacity;

1876
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
1877

1878
		if ( material.emissive ) {
M
Mr.doob 已提交
1879

1880
			uniforms.emissive.value = material.emissive;
M
Mr.doob 已提交
1881 1882 1883

		}

1884 1885 1886
		uniforms.map.value = material.map;
		uniforms.specularMap.value = material.specularMap;
		uniforms.alphaMap.value = material.alphaMap;
M
Mr.doob 已提交
1887

1888
		if ( material.aoMap ) {
1889

1890 1891
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1892 1893 1894

		}

M
Mr.doob 已提交
1895
		// uv repeat and offset setting priorities
M
Mr.doob 已提交
1896 1897 1898 1899 1900
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
1901
		// 6. emissive map
M
Mr.doob 已提交
1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

1913 1914 1915 1916
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
1917 1918 1919 1920 1921 1922 1923 1924
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

1925 1926 1927 1928 1929 1930 1931 1932
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

1933 1934 1935 1936
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

1937 1938 1939 1940
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
1941 1942 1943 1944
		}

		if ( uvScaleMap !== undefined ) {

M
Mr.doob 已提交
1945 1946 1947 1948 1949 1950
			if ( uvScaleMap instanceof THREE.WebGLRenderTarget ) {

				uvScaleMap = uvScaleMap.texture;

			}

M
Mr.doob 已提交
1951 1952 1953 1954 1955 1956 1957 1958
			var offset = uvScaleMap.offset;
			var repeat = uvScaleMap.repeat;

			uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );

		}

		uniforms.envMap.value = material.envMap;
1959
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : - 1;
M
Mr.doob 已提交
1960

1961
		uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
1962 1963
		uniforms.refractionRatio.value = material.refractionRatio;

M
Mr.doob 已提交
1964
	}
M
Mr.doob 已提交
1965 1966 1967 1968 1969 1970

	function refreshUniformsLine ( uniforms, material ) {

		uniforms.diffuse.value = material.color;
		uniforms.opacity.value = material.opacity;

M
Mr.doob 已提交
1971
	}
M
Mr.doob 已提交
1972 1973 1974 1975 1976 1977 1978

	function refreshUniformsDash ( uniforms, material ) {

		uniforms.dashSize.value = material.dashSize;
		uniforms.totalSize.value = material.dashSize + material.gapSize;
		uniforms.scale.value = material.scale;

M
Mr.doob 已提交
1979
	}
M
Mr.doob 已提交
1980

M
Mr.doob 已提交
1981
	function refreshUniformsPoints ( uniforms, material ) {
M
Mr.doob 已提交
1982

1983
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
1984
		uniforms.opacity.value = material.opacity;
1985
		uniforms.size.value = material.size;
M
Mr.doob 已提交
1986 1987 1988 1989
		uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.

		uniforms.map.value = material.map;

1990 1991 1992 1993 1994 1995 1996 1997 1998
		if ( material.map !== null ) {

			var offset = material.map.offset;
			var repeat = material.map.repeat;

			uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );

		}

M
Mr.doob 已提交
1999
	}
M
Mr.doob 已提交
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015

	function refreshUniformsFog ( uniforms, fog ) {

		uniforms.fogColor.value = fog.color;

		if ( fog instanceof THREE.Fog ) {

			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;

		} else if ( fog instanceof THREE.FogExp2 ) {

			uniforms.fogDensity.value = fog.density;

		}

M
Mr.doob 已提交
2016
	}
M
Mr.doob 已提交
2017

2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034
	function refreshUniformsLambert ( uniforms, material ) {

		if ( material.lightMap ) {

			uniforms.lightMap.value = material.lightMap;
			uniforms.lightMapIntensity.value = material.lightMapIntensity;

		}

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

M
Mr.doob 已提交
2035 2036
	function refreshUniformsPhong ( uniforms, material ) {

2037
		uniforms.specular.value = material.specular;
M
Mr.doob 已提交
2038
		uniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )
M
Mr.doob 已提交
2039

2040 2041 2042 2043
		if ( material.lightMap ) {

			uniforms.lightMap.value = material.lightMap;
			uniforms.lightMapIntensity.value = material.lightMapIntensity;
M
Mr.doob 已提交
2044

2045
		}
2046

2047
		if ( material.emissiveMap ) {
2048

2049
			uniforms.emissiveMap.value = material.emissiveMap;
2050

2051
		}
M
Mr.doob 已提交
2052

2053 2054 2055 2056
		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;
M
Mr.doob 已提交
2057

2058
		}
M
Mr.doob 已提交
2059

2060 2061 2062 2063 2064 2065
		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );

		}
M
Mr.doob 已提交
2066

2067 2068 2069 2070 2071
		if ( material.displacementMap ) {

			uniforms.displacementMap.value = material.displacementMap;
			uniforms.displacementScale.value = material.displacementScale;
			uniforms.displacementBias.value = material.displacementBias;
2072

2073
		}
2074 2075 2076

	}

2077
	function refreshUniformsStandard ( uniforms, material ) {
W
WestLangley 已提交
2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137

		uniforms.roughness.value = material.roughness;
		uniforms.metalness.value = material.metalness;

		if ( material.roughnessMap ) {

			uniforms.roughnessMap.value = material.roughnessMap;

		}

		if ( material.metalnessMap ) {

			uniforms.metalnessMap.value = material.metalnessMap;

		}

		if ( material.lightMap ) {

			uniforms.lightMap.value = material.lightMap;
			uniforms.lightMapIntensity.value = material.lightMapIntensity;

		}

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );

		}

		if ( material.displacementMap ) {

			uniforms.displacementMap.value = material.displacementMap;
			uniforms.displacementScale.value = material.displacementScale;
			uniforms.displacementBias.value = material.displacementBias;

		}

		if ( material.envMap ) {

			//uniforms.envMap.value = material.envMap; // part of uniforms common
			uniforms.envMapIntensity.value = material.envMapIntensity;

		}

	}

2138 2139
	// If uniforms are marked as clean, they don't need to be loaded to the GPU.

M
Mr.doob 已提交
2140
	function markUniformsLightsNeedsUpdate ( uniforms, value ) {
2141

M
Mr.doob 已提交
2142
		uniforms.ambientLightColor.needsUpdate = value;
2143

B
Ben Houston 已提交
2144 2145 2146 2147
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
		uniforms.hemisphereLights.needsUpdate = value;
2148

M
Mr.doob 已提交
2149
	}
2150

2151
	function refreshUniformsShadow ( uniforms, camera ) {
M
Mr.doob 已提交
2152 2153 2154

		if ( uniforms.shadowMatrix ) {

2155
			var shadows = _lights.shadows;
M
Mr.doob 已提交
2156

2157
			for ( var i = 0, l = shadows.length; i < l; i ++ ) {
M
Mr.doob 已提交
2158

2159
				var light = shadows[ i ];
2160
				var shadow = light.shadow;
M
Mr.doob 已提交
2161

2162
				if ( light instanceof THREE.PointLight ) {
M
Mr.doob 已提交
2163

2164 2165 2166 2167
					// for point lights we set the shadow matrix to be a translation-only matrix
					// equal to inverse of the light's position
					_vector3.setFromMatrixPosition( light.matrixWorld ).negate();
					shadow.matrix.identity().setPosition( _vector3 );
M
Mr.doob 已提交
2168

2169 2170
					// for point lights we set the sign of the shadowDarkness uniform to be negative
					uniforms.shadowDarkness.value[ i ] = - shadow.darkness;
M
Mr.doob 已提交
2171

2172
				} else {
M
Mr.doob 已提交
2173

2174
					uniforms.shadowDarkness.value[ i ] = shadow.darkness;
M
Mr.doob 已提交
2175 2176 2177

				}

2178 2179 2180 2181 2182
				uniforms.shadowBias.value[ i ] = shadow.bias;
				uniforms.shadowMap.value[ i ] = shadow.map;
				uniforms.shadowMapSize.value[ i ] = shadow.mapSize;
				uniforms.shadowMatrix.value[ i ] = shadow.matrix;

M
Mr.doob 已提交
2183 2184 2185 2186
			}

		}

M
Mr.doob 已提交
2187
	}
M
Mr.doob 已提交
2188 2189 2190 2191 2192

	// Uniforms (load to GPU)

	function loadUniformsMatrices ( uniforms, object ) {

2193
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object.modelViewMatrix.elements );
M
Mr.doob 已提交
2194 2195 2196

		if ( uniforms.normalMatrix ) {

2197
			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object.normalMatrix.elements );
M
Mr.doob 已提交
2198 2199 2200

		}

M
Mr.doob 已提交
2201
	}
M
Mr.doob 已提交
2202 2203 2204 2205 2206

	function getTextureUnit() {

		var textureUnit = _usedTextureUnits;

G
gero3 已提交
2207
		if ( textureUnit >= capabilities.maxTextures ) {
M
Mr.doob 已提交
2208

G
gero3 已提交
2209
			console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
M
Mr.doob 已提交
2210 2211 2212 2213 2214 2215 2216

		}

		_usedTextureUnits += 1;

		return textureUnit;

M
Mr.doob 已提交
2217
	}
M
Mr.doob 已提交
2218

2219
	function loadUniformsGeneric ( uniforms ) {
M
Mr.doob 已提交
2220

M
Mr.doob 已提交
2221
		var texture, textureUnit;
M
Mr.doob 已提交
2222

M
Mr.doob 已提交
2223 2224 2225
		for ( var j = 0, jl = uniforms.length; j < jl; j ++ ) {

			var uniform = uniforms[ j ][ 0 ];
M
Mr.doob 已提交
2226

2227 2228
			// needsUpdate property is not added to all uniforms.
			if ( uniform.needsUpdate === false ) continue;
2229

M
Mr.doob 已提交
2230 2231
			var type = uniform.type;
			var value = uniform.value;
2232
			var location = uniforms[ j ][ 1 ];
M
Mr.doob 已提交
2233

2234
			switch ( type ) {
M
Mr.doob 已提交
2235

2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279
				case '1i':
					_gl.uniform1i( location, value );
					break;

				case '1f':
					_gl.uniform1f( location, value );
					break;

				case '2f':
					_gl.uniform2f( location, value[ 0 ], value[ 1 ] );
					break;

				case '3f':
					_gl.uniform3f( location, value[ 0 ], value[ 1 ], value[ 2 ] );
					break;

				case '4f':
					_gl.uniform4f( location, value[ 0 ], value[ 1 ], value[ 2 ], value[ 3 ] );
					break;

				case '1iv':
					_gl.uniform1iv( location, value );
					break;

				case '3iv':
					_gl.uniform3iv( location, value );
					break;

				case '1fv':
					_gl.uniform1fv( location, value );
					break;

				case '2fv':
					_gl.uniform2fv( location, value );
					break;

				case '3fv':
					_gl.uniform3fv( location, value );
					break;

				case '4fv':
					_gl.uniform4fv( location, value );
					break;

2280 2281 2282 2283
				case 'Matrix2fv':
					_gl.uniformMatrix2fv( location, false, value );
					break;

2284 2285 2286 2287 2288 2289 2290 2291 2292 2293
				case 'Matrix3fv':
					_gl.uniformMatrix3fv( location, false, value );
					break;

				case 'Matrix4fv':
					_gl.uniformMatrix4fv( location, false, value );
					break;

				//

M
Mr.doob 已提交
2294
				case 'i':
M
Mr.doob 已提交
2295

2296 2297
					// single integer
					_gl.uniform1i( location, value );
M
Mr.doob 已提交
2298

2299
					break;
M
Mr.doob 已提交
2300

2301
				case 'f':
M
Mr.doob 已提交
2302

2303 2304
					// single float
					_gl.uniform1f( location, value );
M
Mr.doob 已提交
2305

2306
					break;
M
Mr.doob 已提交
2307

2308
				case 'v2':
M
Mr.doob 已提交
2309

2310 2311
					// single THREE.Vector2
					_gl.uniform2f( location, value.x, value.y );
M
Mr.doob 已提交
2312

2313
					break;
M
Mr.doob 已提交
2314

2315
				case 'v3':
M
Mr.doob 已提交
2316

2317 2318
					// single THREE.Vector3
					_gl.uniform3f( location, value.x, value.y, value.z );
M
Mr.doob 已提交
2319

2320
					break;
M
Mr.doob 已提交
2321

M
Mr.doob 已提交
2322
				case 'v4':
M
Mr.doob 已提交
2323

2324 2325
					// single THREE.Vector4
					_gl.uniform4f( location, value.x, value.y, value.z, value.w );
M
Mr.doob 已提交
2326

2327
					break;
M
Mr.doob 已提交
2328

2329
				case 'c':
M
Mr.doob 已提交
2330

2331 2332
					// single THREE.Color
					_gl.uniform3f( location, value.r, value.g, value.b );
M
Mr.doob 已提交
2333

2334
					break;
M
Mr.doob 已提交
2335

2336
				/*
2337 2338 2339
				case 's':

					// TODO: Optimize this.
B
Ben Houston 已提交
2340
					for( var propertyName in uniform.properties ) {
M
Mr.doob 已提交
2341

B
Ben Houston 已提交
2342 2343 2344
						var property = uniform.properties[ propertyName ];
						var locationProperty =  location[ propertyName ];
						var valueProperty = value[ propertyName ];
M
Mr.doob 已提交
2345

2346
						switch( property.type ) {
2347 2348 2349
							case 'i':
								_gl.uniform1i( locationProperty, valueProperty );
								break;
2350
							case 'f':
B
Ben Houston 已提交
2351
								_gl.uniform1f( locationProperty, valueProperty );
2352 2353
								break;
							case 'v2':
B
Ben Houston 已提交
2354
								_gl.uniform2f( locationProperty, valueProperty.x, valueProperty.y );
2355 2356
								break;
							case 'v3':
B
Ben Houston 已提交
2357
								_gl.uniform3f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z );
2358 2359
								break;
							case 'v4':
B
Ben Houston 已提交
2360
								_gl.uniform4f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w );
2361 2362
								break;
							case 'c':
B
Ben Houston 已提交
2363
								_gl.uniform3f( locationProperty, valueProperty.r, valueProperty.g, valueProperty.b );
2364 2365
								break;
						};
2366 2367 2368 2369

					}

					break;
2370
				*/
2371

2372
				case 'sa':
2373

2374
					// TODO: Optimize this.
M
Mr.doob 已提交
2375
					for ( var i = 0; i < value.length; i ++ ) {
2376

M
Mr.doob 已提交
2377
						for ( var propertyName in uniform.properties ) {
M
Mr.doob 已提交
2378

B
Ben Houston 已提交
2379 2380
							var property = uniform.properties[ propertyName ];
							var locationProperty =  location[ i ][ propertyName ];
2381
							var valueProperty = value[ i ][ propertyName ];
M
Mr.doob 已提交
2382

2383
							switch ( property.type ) {
2384 2385 2386
								case 'i':
									_gl.uniform1i( locationProperty, valueProperty );
									break;
2387
								case 'f':
B
Ben Houston 已提交
2388
									_gl.uniform1f( locationProperty, valueProperty );
2389 2390
									break;
								case 'v2':
B
Ben Houston 已提交
2391
									_gl.uniform2f( locationProperty, valueProperty.x, valueProperty.y );
2392 2393
									break;
								case 'v3':
B
Ben Houston 已提交
2394
									_gl.uniform3f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z );
2395 2396
									break;
								case 'v4':
B
Ben Houston 已提交
2397
									_gl.uniform4f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w );
2398 2399
									break;
								case 'c':
B
Ben Houston 已提交
2400
									_gl.uniform3f( locationProperty, valueProperty.r, valueProperty.g, valueProperty.b );
2401
									break;
M
Mr.doob 已提交
2402
							}
2403

2404
						}
2405 2406

					}
M
Mr.doob 已提交
2407

2408 2409
					break;

2410
				case 'iv1':
M
Mr.doob 已提交
2411

2412 2413
					// flat array of integers (JS or typed array)
					_gl.uniform1iv( location, value );
M
Mr.doob 已提交
2414

2415
					break;
M
Mr.doob 已提交
2416

2417
				case 'iv':
M
Mr.doob 已提交
2418

2419 2420
					// flat array of integers with 3 x N size (JS or typed array)
					_gl.uniform3iv( location, value );
M
Mr.doob 已提交
2421

2422
					break;
M
Mr.doob 已提交
2423

2424
				case 'fv1':
M
Mr.doob 已提交
2425

2426 2427
					// flat array of floats (JS or typed array)
					_gl.uniform1fv( location, value );
M
Mr.doob 已提交
2428

2429
					break;
M
Mr.doob 已提交
2430

2431
				case 'fv':
M
Mr.doob 已提交
2432

2433 2434
					// flat array of floats with 3 x N size (JS or typed array)
					_gl.uniform3fv( location, value );
M
Mr.doob 已提交
2435

2436
					break;
M
Mr.doob 已提交
2437

2438
				case 'v2v':
M
Mr.doob 已提交
2439

2440
					// array of THREE.Vector2
M
Mr.doob 已提交
2441

2442
					if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2443

2444
						uniform._array = new Float32Array( 2 * value.length );
M
Mr.doob 已提交
2445

2446
					}
M
Mr.doob 已提交
2447

M
Mr.doob 已提交
2448
					for ( var i = 0, i2 = 0, il = value.length; i < il; i ++, i2 += 2 ) {
M
Mr.doob 已提交
2449

M
Mr.doob 已提交
2450 2451
						uniform._array[ i2 + 0 ] = value[ i ].x;
						uniform._array[ i2 + 1 ] = value[ i ].y;
M
Mr.doob 已提交
2452

2453
					}
M
Mr.doob 已提交
2454

2455
					_gl.uniform2fv( location, uniform._array );
M
Mr.doob 已提交
2456

2457
					break;
M
Mr.doob 已提交
2458

2459
				case 'v3v':
M
Mr.doob 已提交
2460

2461
					// array of THREE.Vector3
M
Mr.doob 已提交
2462

2463
					if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2464

2465
						uniform._array = new Float32Array( 3 * value.length );
M
Mr.doob 已提交
2466

2467
					}
M
Mr.doob 已提交
2468

M
Mr.doob 已提交
2469
					for ( var i = 0, i3 = 0, il = value.length; i < il; i ++, i3 += 3 ) {
R
Ryan Tsao 已提交
2470

M
Mr.doob 已提交
2471 2472 2473
						uniform._array[ i3 + 0 ] = value[ i ].x;
						uniform._array[ i3 + 1 ] = value[ i ].y;
						uniform._array[ i3 + 2 ] = value[ i ].z;
R
Ryan Tsao 已提交
2474

2475
					}
R
Ryan Tsao 已提交
2476

2477
					_gl.uniform3fv( location, uniform._array );
R
Ryan Tsao 已提交
2478

2479
					break;
R
Ryan Tsao 已提交
2480

2481
				case 'v4v':
R
Ryan Tsao 已提交
2482

2483
					// array of THREE.Vector4
R
Ryan Tsao 已提交
2484

2485
					if ( uniform._array === undefined ) {
R
Ryan Tsao 已提交
2486

2487
						uniform._array = new Float32Array( 4 * value.length );
R
Ryan Tsao 已提交
2488

2489
					}
M
Mr.doob 已提交
2490

M
Mr.doob 已提交
2491
					for ( var i = 0, i4 = 0, il = value.length; i < il; i ++, i4 += 4 ) {
M
Mr.doob 已提交
2492

M
Mr.doob 已提交
2493 2494 2495 2496
						uniform._array[ i4 + 0 ] = value[ i ].x;
						uniform._array[ i4 + 1 ] = value[ i ].y;
						uniform._array[ i4 + 2 ] = value[ i ].z;
						uniform._array[ i4 + 3 ] = value[ i ].w;
M
Mr.doob 已提交
2497

2498
					}
M
Mr.doob 已提交
2499

2500
					_gl.uniform4fv( location, uniform._array );
M
Mr.doob 已提交
2501

2502
					break;
M
Mr.doob 已提交
2503

2504 2505 2506 2507 2508 2509 2510
				case 'm2':

					// single THREE.Matrix2
					_gl.uniformMatrix2fv( location, false, value.elements );

					break;

2511
				case 'm3':
M
Mr.doob 已提交
2512

2513 2514
					// single THREE.Matrix3
					_gl.uniformMatrix3fv( location, false, value.elements );
M
Mr.doob 已提交
2515

2516
					break;
M
Mr.doob 已提交
2517

2518
				case 'm3v':
M
Mr.doob 已提交
2519

2520
					// array of THREE.Matrix3
M
Mr.doob 已提交
2521

2522
					if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2523

2524
						uniform._array = new Float32Array( 9 * value.length );
M
Mr.doob 已提交
2525

2526
					}
M
Mr.doob 已提交
2527

2528
					for ( var i = 0, il = value.length; i < il; i ++ ) {
M
Mr.doob 已提交
2529

2530
						value[ i ].flattenToArrayOffset( uniform._array, i * 9 );
M
Mr.doob 已提交
2531

2532
					}
M
Mr.doob 已提交
2533

2534
					_gl.uniformMatrix3fv( location, false, uniform._array );
M
Mr.doob 已提交
2535

2536
					break;
M
Mr.doob 已提交
2537

2538
				case 'm4':
M
Mr.doob 已提交
2539

2540 2541
					// single THREE.Matrix4
					_gl.uniformMatrix4fv( location, false, value.elements );
M
Mr.doob 已提交
2542

2543
					break;
M
Mr.doob 已提交
2544

2545
				case 'm4v':
M
Mr.doob 已提交
2546

2547
					// array of THREE.Matrix4
M
Mr.doob 已提交
2548

2549
					if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2550

2551
						uniform._array = new Float32Array( 16 * value.length );
M
Mr.doob 已提交
2552

2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563
					}

					for ( var i = 0, il = value.length; i < il; i ++ ) {

						value[ i ].flattenToArrayOffset( uniform._array, i * 16 );

					}

					_gl.uniformMatrix4fv( location, false, uniform._array );

					break;
M
Mr.doob 已提交
2564

2565
				case 't':
M
Mr.doob 已提交
2566

2567
					// single THREE.Texture (2d or cube)
M
Mr.doob 已提交
2568

2569 2570 2571 2572
					texture = value;
					textureUnit = getTextureUnit();

					_gl.uniform1i( location, textureUnit );
M
Mr.doob 已提交
2573

2574
					if ( ! texture ) continue;
M
Mr.doob 已提交
2575

2576
					if ( texture instanceof THREE.CubeTexture ||
G
gero3 已提交
2577 2578 2579
						 ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {

						// CompressedTexture can have Array in image :/
M
Mr.doob 已提交
2580

2581
						setCubeTexture( texture, textureUnit );
M
Mr.doob 已提交
2582

2583 2584
					} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {

M
Mr.doob 已提交
2585 2586 2587 2588 2589
						setCubeTextureDynamic( texture.texture, textureUnit );

					} else if ( texture instanceof THREE.WebGLRenderTarget ) {

						_this.setTexture( texture.texture, textureUnit );
2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600

					} else {

						_this.setTexture( texture, textureUnit );

					}

					break;

				case 'tv':

M
Mr.doob 已提交
2601
					// array of THREE.Texture (2d or cube)
2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623

					if ( uniform._array === undefined ) {

						uniform._array = [];

					}

					for ( var i = 0, il = uniform.value.length; i < il; i ++ ) {

						uniform._array[ i ] = getTextureUnit();

					}

					_gl.uniform1iv( location, uniform._array );

					for ( var i = 0, il = uniform.value.length; i < il; i ++ ) {

						texture = uniform.value[ i ];
						textureUnit = uniform._array[ i ];

						if ( ! texture ) continue;

M
Mr.doob 已提交
2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643
						if ( texture instanceof THREE.CubeTexture ||
							 ( texture.image instanceof Array && texture.image.length === 6 ) ) {

							// CompressedTexture can have Array in image :/

							setCubeTexture( texture, textureUnit );

						} else if ( texture instanceof THREE.WebGLRenderTarget ) {

							_this.setTexture( texture.texture, textureUnit );

						} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {

							setCubeTextureDynamic( texture.texture, textureUnit );

						} else {

							_this.setTexture( texture, textureUnit );

						}
2644 2645 2646 2647 2648 2649

					}

					break;

				default:
2650

2651
					console.warn( 'THREE.WebGLRenderer: Unknown uniform type: ' + type );
2652

M
Mr.doob 已提交
2653 2654 2655 2656
			}

		}

M
Mr.doob 已提交
2657
	}
M
Mr.doob 已提交
2658

T
tschw 已提交
2659
	function setupLights ( lights, camera ) {
M
Mr.doob 已提交
2660

B
brason 已提交
2661
		var l, ll, light,
M
Mr.doob 已提交
2662
		r = 0, g = 0, b = 0,
B
Ben Houston 已提交
2663
		color,
B
brason 已提交
2664
		intensity,
M
Mr.doob 已提交
2665 2666
		distance,

2667
		viewMatrix = camera.matrixWorldInverse,
M
Mr.doob 已提交
2668

M
Mr.doob 已提交
2669
		directionalLength = 0,
M
Mr.doob 已提交
2670 2671
		pointLength = 0,
		spotLength = 0,
2672 2673 2674
		hemiLength = 0,

		shadowsLength = 0;
M
Mr.doob 已提交
2675

2676 2677
		_lights.shadowsPointLight = 0;

M
Mr.doob 已提交
2678 2679 2680 2681 2682 2683 2684 2685 2686 2687
		for ( l = 0, ll = lights.length; l < ll; l ++ ) {

			light = lights[ l ];

			color = light.color;
			intensity = light.intensity;
			distance = light.distance;

			if ( light instanceof THREE.AmbientLight ) {

2688 2689 2690
				r += color.r * intensity;
				g += color.g * intensity;
				b += color.b * intensity;
M
Mr.doob 已提交
2691 2692 2693

			} else if ( light instanceof THREE.DirectionalLight ) {

M
Mr.doob 已提交
2694
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2695

M
Mr.doob 已提交
2696
				uniforms.direction.setFromMatrixPosition( light.matrixWorld );
2697
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
M
Mr.doob 已提交
2698 2699 2700 2701
				uniforms.direction.sub( _vector3 );
				uniforms.direction.transformDirection( viewMatrix );
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );

2702
				if ( light.castShadow ) {
M
Mr.doob 已提交
2703

2704 2705
					uniforms.shadow = shadowsLength;

2706
					_lights.shadows[ shadowsLength ++ ] = light;
2707

2708 2709
				} else {

M
Mr.doob 已提交
2710
					uniforms.shadow = - 1;
2711

2712 2713 2714
				}

				_lights.directional[ directionalLength ++ ] = uniforms;
M
Mr.doob 已提交
2715 2716 2717

			} else if ( light instanceof THREE.PointLight ) {

M
Mr.doob 已提交
2718
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2719 2720 2721

				uniforms.position.setFromMatrixPosition( light.matrixWorld );
				uniforms.position.applyMatrix4( viewMatrix );
M
Mr.doob 已提交
2722

M
Mr.doob 已提交
2723 2724 2725
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
				uniforms.distance = light.distance;
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
M
Mr.doob 已提交
2726

2727 2728
				if ( light.castShadow ) {

2729 2730
					uniforms.shadow = shadowsLength;

2731
					_lights.shadows[ shadowsLength ++ ] = light;
2732 2733
					_lights.shadowsPointLight ++;

2734 2735
				} else {

M
Mr.doob 已提交
2736
					uniforms.shadow = - 1;
2737

2738 2739
				}

2740 2741
				_lights.point[ pointLength ++ ] = uniforms;

M
Mr.doob 已提交
2742 2743
			} else if ( light instanceof THREE.SpotLight ) {

M
Mr.doob 已提交
2744
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2745

M
Mr.doob 已提交
2746 2747
				uniforms.position.setFromMatrixPosition( light.matrixWorld );
				uniforms.position.applyMatrix4( viewMatrix );
M
Mr.doob 已提交
2748

M
Mr.doob 已提交
2749 2750
				uniforms.color.copy( color ).multiplyScalar( intensity );
				uniforms.distance = distance;
M
Mr.doob 已提交
2751

M
Mr.doob 已提交
2752
				uniforms.direction.setFromMatrixPosition( light.matrixWorld );
2753
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
M
Mr.doob 已提交
2754 2755
				uniforms.direction.sub( _vector3 );
				uniforms.direction.transformDirection( viewMatrix );
M
Mr.doob 已提交
2756

M
Mr.doob 已提交
2757 2758 2759 2760
				uniforms.angleCos = Math.cos( light.angle );
				uniforms.exponent = light.exponent;
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;

2761 2762
				if ( light.castShadow ) {

2763 2764
					uniforms.shadow = shadowsLength;

2765
					_lights.shadows[ shadowsLength ++ ] = light;
M
Mr.doob 已提交
2766

2767 2768
				} else {

M
Mr.doob 已提交
2769
					uniforms.shadow = - 1;
2770

2771 2772 2773
				}

				_lights.spot[ spotLength ++ ] = uniforms;
2774

M
Mr.doob 已提交
2775 2776
			} else if ( light instanceof THREE.HemisphereLight ) {

M
Mr.doob 已提交
2777
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2778 2779 2780 2781

				uniforms.direction.setFromMatrixPosition( light.matrixWorld );
				uniforms.direction.transformDirection( viewMatrix );
				uniforms.direction.normalize();
M
Mr.doob 已提交
2782

M
Mr.doob 已提交
2783 2784
				uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
				uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
M
Mr.doob 已提交
2785

M
Mr.doob 已提交
2786
				_lights.hemi[ hemiLength ++ ] = uniforms;
M
Mr.doob 已提交
2787 2788 2789 2790 2791

			}

		}

M
Mr.doob 已提交
2792 2793 2794
		_lights.ambient[ 0 ] = r;
		_lights.ambient[ 1 ] = g;
		_lights.ambient[ 2 ] = b;
M
Mr.doob 已提交
2795

M
Mr.doob 已提交
2796 2797 2798 2799
		_lights.directional.length = directionalLength;
		_lights.point.length = pointLength;
		_lights.spot.length = spotLength;
		_lights.hemi.length = hemiLength;
2800

2801 2802
		_lights.shadows.length = shadowsLength;

2803
		_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + hemiLength + ',' + shadowsLength;
2804

M
Mr.doob 已提交
2805
	}
M
Mr.doob 已提交
2806 2807 2808 2809 2810 2811 2812

	// GL state setting

	this.setFaceCulling = function ( cullFace, frontFaceDirection ) {

		if ( cullFace === THREE.CullFaceNone ) {

2813
			state.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840

		} else {

			if ( frontFaceDirection === THREE.FrontFaceDirectionCW ) {

				_gl.frontFace( _gl.CW );

			} else {

				_gl.frontFace( _gl.CCW );

			}

			if ( cullFace === THREE.CullFaceBack ) {

				_gl.cullFace( _gl.BACK );

			} else if ( cullFace === THREE.CullFaceFront ) {

				_gl.cullFace( _gl.FRONT );

			} else {

				_gl.cullFace( _gl.FRONT_AND_BACK );

			}

2841
			state.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
2842 2843 2844 2845 2846 2847 2848 2849 2850

		}

	};

	// Textures

	function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {

2851 2852
		var extension;

M
Mr.doob 已提交
2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864
		if ( isImagePowerOfTwo ) {

			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );

			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );

		} else {

			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
M
Mr.doob 已提交
2865 2866 2867

			if ( texture.wrapS !== THREE.ClampToEdgeWrapping || texture.wrapT !== THREE.ClampToEdgeWrapping ) {

M
Mr.doob 已提交
2868
				console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );
M
Mr.doob 已提交
2869

2870
			}
M
Mr.doob 已提交
2871 2872 2873 2874

			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );

M
Mr.doob 已提交
2875 2876
			if ( texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) {

M
Mr.doob 已提交
2877
				console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );
M
Mr.doob 已提交
2878

2879
			}
M
Mr.doob 已提交
2880

M
Mr.doob 已提交
2881 2882
		}

2883 2884
		extension = extensions.get( 'EXT_texture_filter_anisotropic' );

2885
		if ( extension ) {
M
Mr.doob 已提交
2886

2887 2888
			if ( texture.type === THREE.FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;
			if ( texture.type === THREE.HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;
M
Mr.doob 已提交
2889

2890
			if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {
M
Mr.doob 已提交
2891

2892
				_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _this.getMaxAnisotropy() ) );
2893
				properties.get( texture ).__currentAnisotropy = texture.anisotropy;
M
Mr.doob 已提交
2894 2895 2896 2897 2898

			}

		}

M
Mr.doob 已提交
2899
	}
M
Mr.doob 已提交
2900

2901
	function uploadTexture( textureProperties, texture, slot ) {
2902

2903
		if ( textureProperties.__webglInit === undefined ) {
2904

2905
			textureProperties.__webglInit = true;
2906 2907 2908

			texture.addEventListener( 'dispose', onTextureDispose );

2909
			textureProperties.__webglTexture = _gl.createTexture();
2910

2911
			_infoMemory.textures ++;
2912 2913

		}
M
Mr.doob 已提交
2914

B
Ben Adams 已提交
2915
		state.activeTexture( _gl.TEXTURE0 + slot );
2916
		state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
M
Mr.doob 已提交
2917

H
Henri Astre 已提交
2918 2919 2920 2921
		_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
		_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
		_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );

G
gero3 已提交
2922
		texture.image = clampToMaxSize( texture.image, capabilities.maxTextureSize );
2923

M
Mr.doob 已提交
2924 2925 2926 2927 2928 2929
		if ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( texture.image ) === false ) {

			texture.image = makePowerOfTwo( texture.image );

		}

H
Henri Astre 已提交
2930
		var image = texture.image,
M
Mr.doob 已提交
2931
		isImagePowerOfTwo = isPowerOfTwo( image ),
H
Henri Astre 已提交
2932 2933
		glFormat = paramThreeToGL( texture.format ),
		glType = paramThreeToGL( texture.type );
M
Mr.doob 已提交
2934

H
Henri Astre 已提交
2935
		setTextureParameters( _gl.TEXTURE_2D, texture, isImagePowerOfTwo );
M
Mr.doob 已提交
2936

H
Henri Astre 已提交
2937
		var mipmap, mipmaps = texture.mipmaps;
M
Mr.doob 已提交
2938

H
Henri Astre 已提交
2939
		if ( texture instanceof THREE.DataTexture ) {
M
Mr.doob 已提交
2940

H
Henri Astre 已提交
2941 2942 2943
			// use manually created mipmaps if available
			// if there are no manual mipmaps
			// set 0 level mipmap and then use GL to generate other mipmap levels
M
Mr.doob 已提交
2944

H
Henri Astre 已提交
2945 2946 2947
			if ( mipmaps.length > 0 && isImagePowerOfTwo ) {

				for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
M
Mr.doob 已提交
2948

H
Henri Astre 已提交
2949
					mipmap = mipmaps[ i ];
2950
					state.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
M
Mr.doob 已提交
2951

H
Henri Astre 已提交
2952
				}
M
Mr.doob 已提交
2953

H
Henri Astre 已提交
2954
				texture.generateMipmaps = false;
M
Mr.doob 已提交
2955

H
Henri Astre 已提交
2956
			} else {
M
Mr.doob 已提交
2957

2958
				state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );
M
Mr.doob 已提交
2959

H
Henri Astre 已提交
2960
			}
M
Mr.doob 已提交
2961

H
Henri Astre 已提交
2962
		} else if ( texture instanceof THREE.CompressedTexture ) {
M
Mr.doob 已提交
2963

H
Henri Astre 已提交
2964
			for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
M
Mr.doob 已提交
2965

H
Henri Astre 已提交
2966
				mipmap = mipmaps[ i ];
M
Mr.doob 已提交
2967

2968
				if ( texture.format !== THREE.RGBAFormat && texture.format !== THREE.RGBFormat ) {
M
Mr.doob 已提交
2969

2970
					if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {
M
Mr.doob 已提交
2971

2972
						state.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
M
Mr.doob 已提交
2973

2974
					} else {
M
Mr.doob 已提交
2975

2976
						console.warn( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()" );
M
Mr.doob 已提交
2977

2978
					}
M
Mr.doob 已提交
2979

H
Henri Astre 已提交
2980
				} else {
M
Mr.doob 已提交
2981

2982
					state.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
M
Mr.doob 已提交
2983

M
Mr.doob 已提交
2984 2985
				}

H
Henri Astre 已提交
2986 2987
			}

G
gero3 已提交
2988 2989 2990
		} else {

			// regular Texture (image, video, canvas)
H
Henri Astre 已提交
2991 2992 2993 2994 2995 2996

			// use manually created mipmaps if available
			// if there are no manual mipmaps
			// set 0 level mipmap and then use GL to generate other mipmap levels

			if ( mipmaps.length > 0 && isImagePowerOfTwo ) {
M
Mr.doob 已提交
2997

2998
				for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
M
Mr.doob 已提交
2999 3000

					mipmap = mipmaps[ i ];
3001
					state.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );
M
Mr.doob 已提交
3002 3003 3004

				}

H
Henri Astre 已提交
3005
				texture.generateMipmaps = false;
M
Mr.doob 已提交
3006

H
Henri Astre 已提交
3007
			} else {
M
Mr.doob 已提交
3008

3009
				state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, texture.image );
M
Mr.doob 已提交
3010

H
Henri Astre 已提交
3011
			}
M
Mr.doob 已提交
3012

H
Henri Astre 已提交
3013
		}
M
Mr.doob 已提交
3014

H
Henri Astre 已提交
3015
		if ( texture.generateMipmaps && isImagePowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
M
Mr.doob 已提交
3016

3017
		textureProperties.__version = texture.version;
M
Mr.doob 已提交
3018

B
Ben Adams 已提交
3019
		if ( texture.onUpdate ) texture.onUpdate( texture );
M
Mr.doob 已提交
3020

3021
	}
M
Mr.doob 已提交
3022

H
Henri Astre 已提交
3023
	this.setTexture = function ( texture, slot ) {
M
Mr.doob 已提交
3024

3025 3026 3027
		var textureProperties = properties.get( texture );

		if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
M
Mr.doob 已提交
3028

3029
			var image = texture.image;
M
Mr.doob 已提交
3030

3031 3032
			if ( image === undefined ) {

3033
				console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );
3034 3035 3036 3037
				return;

			}

3038
			if ( image.complete === false ) {
M
Mr.doob 已提交
3039

3040
				console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );
3041 3042 3043 3044
				return;

			}

3045
			uploadTexture( textureProperties, texture, slot );
3046

3047
			return;
M
Mr.doob 已提交
3048 3049 3050

		}

B
Ben Adams 已提交
3051
		state.activeTexture( _gl.TEXTURE0 + slot );
3052
		state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
3053

M
Mr.doob 已提交
3054 3055 3056 3057
	};

	function clampToMaxSize ( image, maxSize ) {

3058
		if ( image.width > maxSize || image.height > maxSize ) {
M
Mr.doob 已提交
3059

3060 3061
			// Warning: Scaling through the canvas will only work with images that use
			// premultiplied alpha.
M
Mr.doob 已提交
3062

3063
			var scale = maxSize / Math.max( image.width, image.height );
M
Mr.doob 已提交
3064

3065 3066 3067
			var canvas = document.createElement( 'canvas' );
			canvas.width = Math.floor( image.width * scale );
			canvas.height = Math.floor( image.height * scale );
M
Mr.doob 已提交
3068

3069 3070
			var context = canvas.getContext( '2d' );
			context.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );
M
Mr.doob 已提交
3071

3072
			console.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );
M
Mr.doob 已提交
3073

3074 3075 3076
			return canvas;

		}
M
Mr.doob 已提交
3077

3078
		return image;
M
Mr.doob 已提交
3079 3080 3081

	}

M
Mr.doob 已提交
3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117
	function isPowerOfTwo( image ) {

		return THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height );

	}

	function textureNeedsPowerOfTwo( texture ) {

		if ( texture.wrapS !== THREE.ClampToEdgeWrapping || texture.wrapT !== THREE.ClampToEdgeWrapping ) return true;
		if ( texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) return true;

		return false;

	}

	function makePowerOfTwo( image ) {

		if ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {

			var canvas = document.createElement( 'canvas' );
			canvas.width = THREE.Math.nearestPowerOfTwo( image.width );
			canvas.height = THREE.Math.nearestPowerOfTwo( image.height );

			var context = canvas.getContext( '2d' );
			context.drawImage( image, 0, 0, canvas.width, canvas.height );

			console.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );

			return canvas;

		}

		return image;

	}

M
Mr.doob 已提交
3118 3119
	function setCubeTexture ( texture, slot ) {

3120
		var textureProperties = properties.get( texture );
3121

M
Mr.doob 已提交
3122 3123
		if ( texture.image.length === 6 ) {

3124
			if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
M
Mr.doob 已提交
3125

3126
				if ( ! textureProperties.__image__webglTextureCube ) {
M
Mr.doob 已提交
3127

3128 3129
					texture.addEventListener( 'dispose', onTextureDispose );

3130
					textureProperties.__image__webglTextureCube = _gl.createTexture();
M
Mr.doob 已提交
3131

3132
					_infoMemory.textures ++;
M
Mr.doob 已提交
3133 3134 3135

				}

B
Ben Adams 已提交
3136
				state.activeTexture( _gl.TEXTURE0 + slot );
3137
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
3138 3139 3140

				_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );

M
Mr.doob 已提交
3141 3142
				var isCompressed = texture instanceof THREE.CompressedTexture;
				var isDataTexture = texture.image[ 0 ] instanceof THREE.DataTexture;
M
Mr.doob 已提交
3143 3144 3145 3146 3147

				var cubeImage = [];

				for ( var i = 0; i < 6; i ++ ) {

3148
					if ( _this.autoScaleCubemaps && ! isCompressed && ! isDataTexture ) {
M
Mr.doob 已提交
3149

G
gero3 已提交
3150
						cubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );
M
Mr.doob 已提交
3151 3152 3153

					} else {

3154
						cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];
M
Mr.doob 已提交
3155 3156 3157 3158 3159 3160

					}

				}

				var image = cubeImage[ 0 ],
M
Mr.doob 已提交
3161
				isImagePowerOfTwo = isPowerOfTwo( image ),
M
Mr.doob 已提交
3162 3163 3164 3165 3166 3167 3168
				glFormat = paramThreeToGL( texture.format ),
				glType = paramThreeToGL( texture.type );

				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo );

				for ( var i = 0; i < 6; i ++ ) {

3169
					if ( ! isCompressed ) {
M
Mr.doob 已提交
3170

M
Mr.doob 已提交
3171
						if ( isDataTexture ) {
3172

3173
							state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );
3174

M
Mr.doob 已提交
3175
						} else {
3176

3177
							state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
3178

M
Mr.doob 已提交
3179 3180
						}

3181
					} else {
3182

M
Mr.doob 已提交
3183 3184
						var mipmap, mipmaps = cubeImage[ i ].mipmaps;

3185
						for ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {
M
Mr.doob 已提交
3186 3187

							mipmap = mipmaps[ j ];
M
Mr.doob 已提交
3188

3189
							if ( texture.format !== THREE.RGBAFormat && texture.format !== THREE.RGBFormat ) {
M
Mr.doob 已提交
3190

3191
								if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {
M
Mr.doob 已提交
3192

3193
									state.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
M
Mr.doob 已提交
3194

3195
								} else {
M
Mr.doob 已提交
3196

3197
									console.warn( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setCubeTexture()" );
M
Mr.doob 已提交
3198

3199
								}
M
Mr.doob 已提交
3200

3201
							} else {
M
Mr.doob 已提交
3202

3203
								state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
M
Mr.doob 已提交
3204

3205
							}
M
Mr.doob 已提交
3206

3207
						}
M
Mr.doob 已提交
3208

M
Mr.doob 已提交
3209
					}
M
Mr.doob 已提交
3210

M
Mr.doob 已提交
3211 3212 3213 3214 3215 3216 3217 3218
				}

				if ( texture.generateMipmaps && isImagePowerOfTwo ) {

					_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

				}

3219
				textureProperties.__version = texture.version;
M
Mr.doob 已提交
3220

B
Ben Adams 已提交
3221
				if ( texture.onUpdate ) texture.onUpdate( texture );
M
Mr.doob 已提交
3222 3223 3224

			} else {

B
Ben Adams 已提交
3225
				state.activeTexture( _gl.TEXTURE0 + slot );
3226
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
3227 3228 3229 3230 3231

			}

		}

M
Mr.doob 已提交
3232
	}
M
Mr.doob 已提交
3233 3234 3235

	function setCubeTextureDynamic ( texture, slot ) {

B
Ben Adams 已提交
3236
		state.activeTexture( _gl.TEXTURE0 + slot );
3237
		state.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );
M
Mr.doob 已提交
3238

M
Mr.doob 已提交
3239
	}
M
Mr.doob 已提交
3240 3241 3242

	// Render targets

3243 3244
	// Setup storage for target texture and bind it to correct framebuffer
	function setupFrameBufferTexture ( framebuffer, renderTarget, attachment, textureTarget ) {
M
Mr.doob 已提交
3245

3246 3247 3248
		var glFormat = paramThreeToGL( renderTarget.texture.format );
		var glType = paramThreeToGL( renderTarget.texture.type );
		state.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
M
Mr.doob 已提交
3249
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
3250 3251
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
M
Mr.doob 已提交
3252

M
Mr.doob 已提交
3253
	}
M
Mr.doob 已提交
3254

3255 3256
	// Setup storage for internal depth/stencil buffers and bind to correct framebuffer
	function setupRenderBufferStorage ( renderbuffer, renderTarget ) {
M
Mr.doob 已提交
3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271

		_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );

		if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {

			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );

		} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {

			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );

		} else {

3272
			// FIXME: We don't support !depth !stencil
M
Mr.doob 已提交
3273 3274 3275 3276
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );

		}

3277
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
M
Mr.doob 已提交
3278

M
Mr.doob 已提交
3279
	}
M
Mr.doob 已提交
3280

3281
	// Setup GL resources for a non-texture depth buffer
M
Marius Kintel 已提交
3282
	function setupDepthRenderbuffer( renderTarget ) {
M
Mr.doob 已提交
3283

3284
		var renderTargetProperties = properties.get( renderTarget );
M
Mr.doob 已提交
3285 3286

		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
M
Mr.doob 已提交
3287

3288
		if ( isCube ) {
M
Mr.doob 已提交
3289

3290
			renderTargetProperties.__webglDepthbuffer = [];
M
Mr.doob 已提交
3291

3292
			for ( var i = 0; i < 6; i ++ ) {
M
Mr.doob 已提交
3293

M
Marius Kintel 已提交
3294
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );
3295 3296
				renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();
				setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );
M
Mr.doob 已提交
3297 3298

			}
B
Ben Adams 已提交
3299

M
Mr.doob 已提交
3300
		} else {
M
Mr.doob 已提交
3301

M
Marius Kintel 已提交
3302
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );
3303 3304
			renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
			setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );
M
Mr.doob 已提交
3305

3306
		}
M
Mr.doob 已提交
3307

M
Marius Kintel 已提交
3308
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
M
Mr.doob 已提交
3309

M
Mr.doob 已提交
3310
	}
M
Mr.doob 已提交
3311

3312
	// Set up GL resources for the render target
M
Marius Kintel 已提交
3313
	function setupRenderTarget( renderTarget ) {
M
Mr.doob 已提交
3314

3315 3316
		var renderTargetProperties = properties.get( renderTarget );
		var textureProperties = properties.get( renderTarget.texture );
M
Mr.doob 已提交
3317

3318
		renderTarget.addEventListener( 'dispose', onRenderTargetDispose );
M
Mr.doob 已提交
3319

3320
		textureProperties.__webglTexture = _gl.createTexture();
M
Mr.doob 已提交
3321

3322
		_infoMemory.textures ++;
M
Mr.doob 已提交
3323

3324 3325
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
		var isTargetPowerOfTwo = THREE.Math.isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height );
M
Mr.doob 已提交
3326

3327
		// Setup framebuffer
M
Mr.doob 已提交
3328

3329
		if ( isCube ) {
M
Mr.doob 已提交
3330

3331
			renderTargetProperties.__webglFramebuffer = [];
M
Mr.doob 已提交
3332

3333
			for ( var i = 0; i < 6; i ++ ) {
M
Mr.doob 已提交
3334

3335
				renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();
M
Mr.doob 已提交
3336

3337
			}
M
Mr.doob 已提交
3338

3339
		} else {
M
Mr.doob 已提交
3340

3341
			renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
M
Mr.doob 已提交
3342

3343
		}
M
Mr.doob 已提交
3344

3345
		// Setup color buffer
M
Mr.doob 已提交
3346

3347
		if ( isCube ) {
M
Mr.doob 已提交
3348

3349 3350
			state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
			setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );
M
Mr.doob 已提交
3351

3352
			for ( var i = 0; i < 6; i ++ ) {
M
Mr.doob 已提交
3353

3354
				setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
M
Mr.doob 已提交
3355 3356 3357

			}

3358 3359
			if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
			state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
M
Mr.doob 已提交
3360

3361
		} else {
M
Mr.doob 已提交
3362

3363 3364 3365
			state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
			setTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );
			setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );
M
Mr.doob 已提交
3366

3367 3368
			if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
			state.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
3369

3370
		}
M
Mr.doob 已提交
3371

3372
		// Setup depth and stencil buffers
3373

3374
		if ( renderTarget.depthBuffer ) {
M
Mr.doob 已提交
3375

M
Marius Kintel 已提交
3376
			setupDepthRenderbuffer( renderTarget );
M
Mr.doob 已提交
3377

3378
		}
M
Mr.doob 已提交
3379

3380
	}
M
Mr.doob 已提交
3381

3382
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
3383

3384 3385
		_currentRenderTarget = renderTarget;

3386
		if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {
M
Mr.doob 已提交
3387

M
Marius Kintel 已提交
3388
			setupRenderTarget( renderTarget );
M
Mr.doob 已提交
3389 3390 3391

		}

3392
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
3393
		var framebuffer, scissor, scissorTest, viewport;
M
Mr.doob 已提交
3394 3395 3396

		if ( renderTarget ) {

3397
			var renderTargetProperties = properties.get( renderTarget );
F
Fordy 已提交
3398

M
Mr.doob 已提交
3399 3400
			if ( isCube ) {

3401
				framebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
3402 3403 3404

			} else {

3405
				framebuffer = renderTargetProperties.__webglFramebuffer;
M
Mr.doob 已提交
3406 3407 3408

			}

3409 3410 3411
			scissor = renderTarget.scissor;
			scissorTest = renderTarget.scissorTest;

3412
			viewport = renderTarget.viewport;
M
Mr.doob 已提交
3413 3414 3415 3416 3417

		} else {

			framebuffer = null;

3418 3419 3420
			scissor = _scissor;
			scissorTest = _scissorTest;

3421
			viewport = _viewport;
M
Mr.doob 已提交
3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432

		}

		if ( framebuffer !== _currentFramebuffer ) {

			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );

			_currentFramebuffer = framebuffer;

		}

3433 3434 3435 3436 3437
		state.scissor( scissor );
		state.setScissorTest( scissorTest );

		state.viewport( viewport );

M
Mr.doob 已提交
3438 3439 3440 3441 3442 3443 3444
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, 0 );

		}

3445 3446
		_currentWidth = viewport.z;
		_currentHeight = viewport.w;
M
Mr.doob 已提交
3447 3448 3449

	};

M
Mr.doob 已提交
3450
	this.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {
3451

M
Mr.doob 已提交
3452
		if ( renderTarget instanceof THREE.WebGLRenderTarget === false ) {
3453

3454
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
3455
			return;
3456

G
gero3 已提交
3457
		}
3458

M
Mr.doob 已提交
3459
		var framebuffer = properties.get( renderTarget ).__webglFramebuffer;
3460

M
Mr.doob 已提交
3461
		if ( framebuffer ) {
3462

G
gero3 已提交
3463
			var restore = false;
3464

M
Mr.doob 已提交
3465
			if ( framebuffer !== _currentFramebuffer ) {
3466

M
Mr.doob 已提交
3467
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
3468

G
gero3 已提交
3469
				restore = true;
3470

G
gero3 已提交
3471
			}
3472

M
Mr.doob 已提交
3473
			try {
3474

M
Mr.doob 已提交
3475
				var texture = renderTarget.texture;
3476

M
Mr.doob 已提交
3477 3478
				if ( texture.format !== THREE.RGBAFormat
					&& paramThreeToGL( texture.format ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
3479

M
Mr.doob 已提交
3480 3481
					console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );
					return;
3482

M
Mr.doob 已提交
3483
				}
3484

M
Mr.doob 已提交
3485 3486 3487 3488
				if ( texture.type !== THREE.UnsignedByteType
					&& paramThreeToGL( texture.type ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE )
					&& ! ( texture.type === THREE.FloatType && extensions.get( 'WEBGL_color_buffer_float' ) )
					&& ! ( texture.type === THREE.HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {
3489

M
Mr.doob 已提交
3490 3491
					console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );
					return;
3492

M
Mr.doob 已提交
3493
				}
3494

M
Mr.doob 已提交
3495
				if ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {
3496

M
Mr.doob 已提交
3497
					_gl.readPixels( x, y, width, height, paramThreeToGL( texture.format ), paramThreeToGL( texture.type ), buffer );
3498

M
Mr.doob 已提交
3499
				} else {
M
Mr.doob 已提交
3500

M
Mr.doob 已提交
3501 3502 3503
					console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );

				}
M
Mr.doob 已提交
3504

M
Mr.doob 已提交
3505
			} finally {
M
Mr.doob 已提交
3506

M
Mr.doob 已提交
3507 3508 3509
				if ( restore ) {

					_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );
M
Mr.doob 已提交
3510

M
Mr.doob 已提交
3511 3512 3513
				}

			}
M
Mr.doob 已提交
3514 3515 3516

		}

M
Mr.doob 已提交
3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527
	};

	function updateRenderTargetMipmap( renderTarget ) {

		var target = renderTarget instanceof THREE.WebGLRenderTargetCube ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;
		var texture = properties.get( renderTarget.texture ).__webglTexture;

		state.bindTexture( target, texture );
		_gl.generateMipmap( target );
		state.bindTexture( target, null );

M
Mr.doob 已提交
3528
	}
M
Mr.doob 已提交
3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541

	// Fallback filters for non-power-of-2 textures

	function filterFallback ( f ) {

		if ( f === THREE.NearestFilter || f === THREE.NearestMipMapNearestFilter || f === THREE.NearestMipMapLinearFilter ) {

			return _gl.NEAREST;

		}

		return _gl.LINEAR;

M
Mr.doob 已提交
3542
	}
M
Mr.doob 已提交
3543 3544 3545 3546 3547

	// Map three.js constants to WebGL constants

	function paramThreeToGL ( p ) {

3548 3549
		var extension;

M
Mr.doob 已提交
3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573
		if ( p === THREE.RepeatWrapping ) return _gl.REPEAT;
		if ( p === THREE.ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;
		if ( p === THREE.MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;

		if ( p === THREE.NearestFilter ) return _gl.NEAREST;
		if ( p === THREE.NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;
		if ( p === THREE.NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;

		if ( p === THREE.LinearFilter ) return _gl.LINEAR;
		if ( p === THREE.LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;
		if ( p === THREE.LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;

		if ( p === THREE.UnsignedByteType ) return _gl.UNSIGNED_BYTE;
		if ( p === THREE.UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;
		if ( p === THREE.UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;
		if ( p === THREE.UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;

		if ( p === THREE.ByteType ) return _gl.BYTE;
		if ( p === THREE.ShortType ) return _gl.SHORT;
		if ( p === THREE.UnsignedShortType ) return _gl.UNSIGNED_SHORT;
		if ( p === THREE.IntType ) return _gl.INT;
		if ( p === THREE.UnsignedIntType ) return _gl.UNSIGNED_INT;
		if ( p === THREE.FloatType ) return _gl.FLOAT;

3574 3575 3576 3577 3578 3579 3580 3581
		extension = extensions.get( 'OES_texture_half_float' );

		if ( extension !== null ) {

			if ( p === THREE.HalfFloatType ) return extension.HALF_FLOAT_OES;

		}

M
Mr.doob 已提交
3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604
		if ( p === THREE.AlphaFormat ) return _gl.ALPHA;
		if ( p === THREE.RGBFormat ) return _gl.RGB;
		if ( p === THREE.RGBAFormat ) return _gl.RGBA;
		if ( p === THREE.LuminanceFormat ) return _gl.LUMINANCE;
		if ( p === THREE.LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;

		if ( p === THREE.AddEquation ) return _gl.FUNC_ADD;
		if ( p === THREE.SubtractEquation ) return _gl.FUNC_SUBTRACT;
		if ( p === THREE.ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;

		if ( p === THREE.ZeroFactor ) return _gl.ZERO;
		if ( p === THREE.OneFactor ) return _gl.ONE;
		if ( p === THREE.SrcColorFactor ) return _gl.SRC_COLOR;
		if ( p === THREE.OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;
		if ( p === THREE.SrcAlphaFactor ) return _gl.SRC_ALPHA;
		if ( p === THREE.OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;
		if ( p === THREE.DstAlphaFactor ) return _gl.DST_ALPHA;
		if ( p === THREE.OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;

		if ( p === THREE.DstColorFactor ) return _gl.DST_COLOR;
		if ( p === THREE.OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;
		if ( p === THREE.SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;

3605
		extension = extensions.get( 'WEBGL_compressed_texture_s3tc' );
M
Mr.doob 已提交
3606

3607 3608 3609 3610 3611 3612
		if ( extension !== null ) {

			if ( p === THREE.RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;
			if ( p === THREE.RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;
			if ( p === THREE.RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;
			if ( p === THREE.RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;
M
Mr.doob 已提交
3613 3614 3615

		}

3616 3617 3618
		extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );

		if ( extension !== null ) {
P
Pierre Lepers 已提交
3619

3620 3621 3622 3623
			if ( p === THREE.RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
			if ( p === THREE.RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
			if ( p === THREE.RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
			if ( p === THREE.RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
P
Pierre Lepers 已提交
3624 3625 3626

		}

3627 3628 3629
		extension = extensions.get( 'EXT_blend_minmax' );

		if ( extension !== null ) {
3630

3631 3632
			if ( p === THREE.MinEquation ) return extension.MIN_EXT;
			if ( p === THREE.MaxEquation ) return extension.MAX_EXT;
3633 3634 3635

		}

M
Mr.doob 已提交
3636 3637
		return 0;

M
Mr.doob 已提交
3638
	}
M
Mr.doob 已提交
3639 3640

};