WebGLRenderer.js 83.3 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

17
	_alpha = parameters.alpha !== undefined ? parameters.alpha : false,
18
	_depth = parameters.depth !== undefined ? parameters.depth : true,
M
Mr.doob 已提交
19
	_stencil = parameters.stencil !== undefined ? parameters.stencil : true,
20 21
	_antialias = parameters.antialias !== undefined ? parameters.antialias : false,
	_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
M
Mr.doob 已提交
22
	_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;
M
Mr.doob 已提交
23

M
Mr.doob 已提交
24
	var lights = [];
M
Mr.doob 已提交
25

O
OpenShift guest 已提交
26
	var opaqueObjects = [];
M
Mr.doob 已提交
27
	var opaqueObjectsLastIndex = - 1;
28
	var transparentObjects = [];
M
Mr.doob 已提交
29
	var transparentObjectsLastIndex = - 1;
30

31 32
	var morphInfluences = new Float32Array( 8 );

M
Mr.doob 已提交
33 34 35
	var sprites = [];
	var lensFlares = [];

M
Mr.doob 已提交
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
	// 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

54
	this.gammaFactor = 2.0;	// for backwards compatibility
M
Mr.doob 已提交
55 56 57
	this.gammaInput = false;
	this.gammaOutput = false;

58 59
	// physical lights

60
	this.physicallyCorrectLights = false;
61

B
Ben Houston 已提交
62 63 64 65 66 67
	// tone mapping

	this.toneMapping = THREE.LinearToneMapping;
	this.toneMappingExposure = 1.0;
	this.toneMappingWhitePoint = 1.0;

M
Mr.doob 已提交
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
	// morphs

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

	// flags

	this.autoScaleCubemaps = true;

	// internal properties

	var _this = this,

	// internal state cache

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

90 91 92 93 94
	_currentScissor = new THREE.Vector4(),
	_currentScissorTest = null,

	_currentViewport = new THREE.Vector4(),

95 96
	//

M
Mr.doob 已提交
97 98
	_usedTextureUnits = 0,

M
Mr.doob 已提交
99 100 101 102 103 104 105 106 107 108 109
	//

	_clearColor = new THREE.Color( 0x000000 ),
	_clearAlpha = 0,

	_width = _canvas.width,
	_height = _canvas.height,

	_pixelRatio = 1,

	_scissor = new THREE.Vector4( 0, 0, _width, _height ),
110 111
	_scissorTest = false,

M
Mr.doob 已提交
112
	_viewport = new THREE.Vector4( 0, 0, _width, _height ),
113

M
Mr.doob 已提交
114 115 116 117
	// frustum

	_frustum = new THREE.Frustum(),

M
Mr.doob 已提交
118
	// camera matrices cache
M
Mr.doob 已提交
119 120 121 122 123 124 125 126 127

	_projScreenMatrix = new THREE.Matrix4(),

	_vector3 = new THREE.Vector3(),

	// light arrays cache

	_lights = {

128 129
		hash: '',

M
Mr.doob 已提交
130
		ambient: [ 0, 0, 0 ],
M
Mr.doob 已提交
131
		directional: [],
132 133
		directionalShadowMap: [],
		directionalShadowMatrix: [],
M
Mr.doob 已提交
134
		spot: [],
135 136
		spotShadowMap: [],
		spotShadowMatrix: [],
M
Mr.doob 已提交
137
		point: [],
138 139
		pointShadowMap: [],
		pointShadowMatrix: [],
140 141
		hemi: [],

142
		shadows: 0,
143
		shadowsPointLight: 0
M
Mr.doob 已提交
144

145 146
	},

M
Mr.doob 已提交
147 148
	// info

149
	_infoMemory = {
150 151

		geometries: 0,
T
tschw 已提交
152
		textures: 0
153 154 155

	},

156
	_infoRender = {
157 158 159 160 161 162

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

M
Mr.doob 已提交
163 164
	};

M
Mr.doob 已提交
165
	this.info = {
166

M
Mr.doob 已提交
167 168
		render: _infoRender,
		memory: _infoMemory,
169
		programs: null
M
Mr.doob 已提交
170 171

	};
172

173

M
Mr.doob 已提交
174 175 176 177
	// initialize

	var _gl;

M
Mr.doob 已提交
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
	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 已提交
193
			if ( _canvas.getContext( 'webgl' ) !== null ) {
194 195 196 197 198 199 200 201

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

			} else {

				throw 'Error creating WebGL context.';

			}
M
Mr.doob 已提交
202 203 204

		}

205 206 207 208 209 210 211 212 213 214 215 216
		// Some experimental-webgl implementations do not have getShaderPrecisionFormat

		if ( _gl.getShaderPrecisionFormat === undefined ) {

			_gl.getShaderPrecisionFormat = function () {

				return { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };

			};

		}

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

M
Mr.doob 已提交
219 220
	} catch ( error ) {

221
		console.error( 'THREE.WebGLRenderer: ' + error );
M
Mr.doob 已提交
222 223 224

	}

225 226
	var extensions = new THREE.WebGLExtensions( _gl );

227 228
	extensions.get( 'OES_texture_float' );
	extensions.get( 'OES_texture_float_linear' );
229 230
	extensions.get( 'OES_texture_half_float' );
	extensions.get( 'OES_texture_half_float_linear' );
231
	extensions.get( 'OES_standard_derivatives' );
B
Ben Adams 已提交
232
	extensions.get( 'ANGLE_instanced_arrays' );
233

234 235
	if ( extensions.get( 'OES_element_index_uint' ) ) {

236
		THREE.BufferGeometry.MaxIndex = 4294967296;
237 238 239

	}

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

242 243 244
	var state = new THREE.WebGLState( _gl, extensions, paramThreeToGL );
	var properties = new THREE.WebGLProperties();
	var objects = new THREE.WebGLObjects( _gl, properties, this.info );
G
gero3 已提交
245
	var programCache = new THREE.WebGLPrograms( this, capabilities );
M
Mr.doob 已提交
246
	var lightCache = new THREE.WebGLLights();
247

248 249
	this.info.programs = programCache.programs;

250 251
	var bufferRenderer = new THREE.WebGLBufferRenderer( _gl, extensions, _infoRender );
	var indexedBufferRenderer = new THREE.WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
252

M
Mr.doob 已提交
253 254
	//

255 256
	function getTargetPixelRatio() {

257
		return _currentRenderTarget === null ? _pixelRatio : 1;
258 259 260

	}

261
	function glClearColor( r, g, b, a ) {
262 263 264

		if ( _premultipliedAlpha === true ) {

265
			r *= a; g *= a; b *= a;
266 267 268

		}

M
Mr.doob 已提交
269
		state.clearColor( r, g, b, a );
270

271
	}
272

273
	function setDefaultGLState() {
M
Mr.doob 已提交
274

M
Mr.doob 已提交
275
		state.init();
M
Mr.doob 已提交
276

277 278
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
M
Mr.doob 已提交
279

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

282
	}
283

284
	function resetGLState() {
285 286 287 288

		_currentProgram = null;
		_currentCamera = null;

289
		_currentGeometryProgram = '';
290 291
		_currentMaterialId = - 1;

M
Mr.doob 已提交
292 293
		state.reset();

294
	}
M
Mr.doob 已提交
295 296 297 298

	setDefaultGLState();

	this.context = _gl;
M
Mr.doob 已提交
299
	this.capabilities = capabilities;
300
	this.extensions = extensions;
301
	this.properties = properties;
M
Mr.doob 已提交
302
	this.state = state;
M
Mr.doob 已提交
303

M
Mr.doob 已提交
304 305
	// shadow map

306
	var shadowMap = new THREE.WebGLShadowMap( this, lights, objects );
M
Mr.doob 已提交
307

308
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
309

M
Mr.doob 已提交
310

M
Mr.doob 已提交
311 312 313 314 315
	// Plugins

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

M
Mr.doob 已提交
316 317 318 319 320 321 322 323
	// API

	this.getContext = function () {

		return _gl;

	};

324 325 326 327 328 329
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

330 331 332 333 334 335
	this.forceContextLoss = function () {

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

	};

336
	this.getMaxAnisotropy = ( function () {
M
Mr.doob 已提交
337

338
		var value;
M
Mr.doob 已提交
339

340
		return function getMaxAnisotropy() {
341

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

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

M
Mr.doob 已提交
346
			if ( extension !== null ) {
347

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

M
Mr.doob 已提交
350 351 352 353 354
			} else {

				value = 0;

			}
355 356 357

			return value;

M
Mr.doob 已提交
358
		};
359 360

	} )();
M
Mr.doob 已提交
361 362 363

	this.getPrecision = function () {

G
gero3 已提交
364
		return capabilities.precision;
M
Mr.doob 已提交
365 366 367

	};

368 369
	this.getPixelRatio = function () {

370
		return _pixelRatio;
371 372 373 374 375

	};

	this.setPixelRatio = function ( value ) {

376 377 378 379 380
		if ( value === undefined ) return;

		_pixelRatio = value;

		this.setSize( _viewport.z, _viewport.w, false );
381 382 383

	};

384 385 386
	this.getSize = function () {

		return {
387 388
			width: _width,
			height: _height
389 390 391 392
		};

	};

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

395 396 397
		_width = width;
		_height = height;

398 399
		_canvas.width = width * _pixelRatio;
		_canvas.height = height * _pixelRatio;
400

401
		if ( updateStyle !== false ) {
402

G
gero3 已提交
403 404
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
405

G
gero3 已提交
406
		}
M
Mr.doob 已提交
407

408
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
409 410 411 412 413

	};

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

414
		state.viewport( _viewport.set( x, y, width, height ) );
M
Mr.doob 已提交
415 416 417

	};

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

420
		state.scissor( _scissor.set( x, y, width, height ) );
M
Mr.doob 已提交
421 422 423

	};

424 425
	this.setScissorTest = function ( boolean ) {

426
		state.setScissorTest( _scissorTest = boolean );
M
Mr.doob 已提交
427 428 429 430 431

	};

	// Clearing

M
Mr.doob 已提交
432
	this.getClearColor = function () {
M
Mr.doob 已提交
433

M
Mr.doob 已提交
434
		return _clearColor;
M
Mr.doob 已提交
435 436 437

	};

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

M
Mr.doob 已提交
440
		_clearColor.set( color );
441

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

444
		glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
M
Mr.doob 已提交
445 446 447

	};

M
Mr.doob 已提交
448
	this.getClearAlpha = function () {
M
Mr.doob 已提交
449

M
Mr.doob 已提交
450
		return _clearAlpha;
M
Mr.doob 已提交
451 452 453

	};

M
Mr.doob 已提交
454
	this.setClearAlpha = function ( alpha ) {
M
Mr.doob 已提交
455

M
Mr.doob 已提交
456
		_clearAlpha = alpha;
M
Mr.doob 已提交
457

458
		glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
M
Mr.doob 已提交
459 460 461 462 463 464 465 466 467 468 469 470

	};

	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 );
471 472 473 474 475

	};

	this.clearColor = function () {

M
Mr.doob 已提交
476
		this.clear( true, false, false );
477 478 479 480 481

	};

	this.clearDepth = function () {

M
Mr.doob 已提交
482
		this.clear( false, true, false );
483 484 485 486 487

	};

	this.clearStencil = function () {

M
Mr.doob 已提交
488
		this.clear( false, false, true );
M
Mr.doob 已提交
489 490 491 492 493 494 495 496 497 498

	};

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

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

	};

M
Mr.doob 已提交
499 500
	// Reset

501
	this.resetGLState = resetGLState;
M
Mr.doob 已提交
502

D
dubejf 已提交
503 504 505 506 507 508
	this.dispose = function() {

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

	};

M
Mr.doob 已提交
509
	// Events
M
Mr.doob 已提交
510

D
dubejf 已提交
511 512 513 514 515 516 517 518 519
	function onContextLost( event ) {

		event.preventDefault();

		resetGLState();
		setDefaultGLState();

		properties.clear();

M
Mr.doob 已提交
520
	}
D
dubejf 已提交
521

522
	function onTextureDispose( event ) {
M
Mr.doob 已提交
523 524 525 526 527 528 529

		var texture = event.target;

		texture.removeEventListener( 'dispose', onTextureDispose );

		deallocateTexture( texture );

530
		_infoMemory.textures --;
M
Mr.doob 已提交
531 532


533
	}
M
Mr.doob 已提交
534

535
	function onRenderTargetDispose( event ) {
M
Mr.doob 已提交
536 537 538 539 540 541 542

		var renderTarget = event.target;

		renderTarget.removeEventListener( 'dispose', onRenderTargetDispose );

		deallocateRenderTarget( renderTarget );

543
		_infoMemory.textures --;
M
Mr.doob 已提交
544

545
	}
M
Mr.doob 已提交
546

547
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
548 549 550 551 552 553 554

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

555
	}
M
Mr.doob 已提交
556 557 558

	// Buffer deallocation

559
	function deallocateTexture( texture ) {
M
Mr.doob 已提交
560

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

563
		if ( texture.image && textureProperties.__image__webglTextureCube ) {
M
Mr.doob 已提交
564 565 566

			// cube texture

567
			_gl.deleteTexture( textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
568

569 570 571 572
		} else {

			// 2D texture

573
			if ( textureProperties.__webglInit === undefined ) return;
574

575
			_gl.deleteTexture( textureProperties.__webglTexture );
576

M
Mr.doob 已提交
577 578
		}

579
		// remove all webgl properties
580
		properties.delete( texture );
581

582
	}
M
Mr.doob 已提交
583

584
	function deallocateRenderTarget( renderTarget ) {
M
Mr.doob 已提交
585

586
		var renderTargetProperties = properties.get( renderTarget );
M
Mr.doob 已提交
587
		var textureProperties = properties.get( renderTarget.texture );
M
Mr.doob 已提交
588

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

M
Mr.doob 已提交
591
		_gl.deleteTexture( textureProperties.__webglTexture );
M
Mr.doob 已提交
592

M
Mr.doob 已提交
593 594 595 596
		if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {

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

597
				_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );
598
				_gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );
M
Mr.doob 已提交
599 600 601 602 603

			}

		} else {

604
			_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );
605
			_gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );
M
Mr.doob 已提交
606 607 608

		}

M
Mr.doob 已提交
609
		properties.delete( renderTarget.texture );
D
Daosheng Mu 已提交
610
		properties.delete( renderTarget );
M
Mr.doob 已提交
611

612
	}
M
Mr.doob 已提交
613

614
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
615

616 617 618 619
		releaseMaterialProgramReference( material );

		properties.delete( material );

620
	}
621 622


623
	function releaseMaterialProgramReference( material ) {
624

625
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
626 627 628

		material.program = undefined;

629
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
630

631
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
632

M
Mr.doob 已提交
633 634
		}

635
	}
M
Mr.doob 已提交
636 637 638 639 640

	// Buffer rendering

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

641
		state.initAttributes();
642

643
		var buffers = properties.get( object );
644

645 646 647 648
		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 已提交
649

650
		var attributes = program.getAttributes();
651

M
Mr.doob 已提交
652 653
		if ( object.hasPositions ) {

654
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
M
Mr.doob 已提交
655
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
656

657 658
			state.enableAttribute( attributes.position );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
659 660 661 662 663

		}

		if ( object.hasNormals ) {

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

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

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

670
					var array = object.normalArray;
M
Mr.doob 已提交
671

672 673 674
					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 已提交
675

676 677 678
					array[ i + 0 ] = nx;
					array[ i + 1 ] = ny;
					array[ i + 2 ] = nz;
M
Mr.doob 已提交
679

680 681 682
					array[ i + 3 ] = nx;
					array[ i + 4 ] = ny;
					array[ i + 5 ] = nz;
M
Mr.doob 已提交
683

684 685 686
					array[ i + 6 ] = nx;
					array[ i + 7 ] = ny;
					array[ i + 8 ] = nz;
M
Mr.doob 已提交
687 688 689 690 691 692

				}

			}

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

694
			state.enableAttribute( attributes.normal );
695

696
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
697 698 699 700 701

		}

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

702
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
M
Mr.doob 已提交
703
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
704

705
			state.enableAttribute( attributes.uv );
706

707
			_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
708 709 710 711 712

		}

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

713
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
M
Mr.doob 已提交
714
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
715

716
			state.enableAttribute( attributes.color );
717

718
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
719 720 721

		}

722
		state.disableUnusedAttributes();
723

M
Mr.doob 已提交
724 725 726 727 728 729
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

730
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
731

M
Mr.doob 已提交
732 733
		setMaterial( material );

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

M
Mr.doob 已提交
736 737
		var updateBuffers = false;
		var geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;
M
Mr.doob 已提交
738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760

		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 ] );

			}

761
			activeInfluences.sort( absNumericalSort );
M
Mr.doob 已提交
762 763 764 765 766 767 768

			if ( activeInfluences.length > 8 ) {

				activeInfluences.length = 8;

			}

769 770
			var morphAttributes = geometry.morphAttributes;

M
Mr.doob 已提交
771 772 773 774 775 776 777
			for ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {

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

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

778
					var index = influence[ 1 ];
M
Mr.doob 已提交
779

780 781
					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 已提交
782 783 784

				} else {

785 786
					if ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );
					if ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );
M
Mr.doob 已提交
787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803

				}

			}

			var uniforms = program.getUniforms();

			if ( uniforms.morphTargetInfluences !== null ) {

				_gl.uniform1fv( uniforms.morphTargetInfluences, morphInfluences );

			}

			updateBuffers = true;

		}

M
Mr.doob 已提交
804 805
		//

806
		var index = geometry.index;
807 808
		var position = geometry.attributes.position;

809 810
		if ( material.wireframe === true ) {

811
			index = objects.getWireframeAttribute( geometry );
812 813 814

		}

815 816
		var renderer;

817
		if ( index !== null ) {
818

819 820
			renderer = indexedBufferRenderer;
			renderer.setIndex( index );
821

822
		} else {
823

824
			renderer = bufferRenderer;
825

826
		}
M
Mr.doob 已提交
827

828
		if ( updateBuffers ) {
M
Mr.doob 已提交
829

830
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
831

832
			if ( index !== null ) {
833

834
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );
835 836 837

			}

838
		}
839

M
Mr.doob 已提交
840
		//
841

M
Mr.doob 已提交
842 843
		var dataStart = 0;
		var dataCount = Infinity;
844

M
Mr.doob 已提交
845
		if ( index !== null ) {
846

M
Mr.doob 已提交
847
			dataCount = index.count;
848

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

M
Mr.doob 已提交
851
			dataCount = position.count;
852

M
Mr.doob 已提交
853
		}
854

M
Mr.doob 已提交
855 856
		var rangeStart = geometry.drawRange.start;
		var rangeCount = geometry.drawRange.count;
857

M
Mr.doob 已提交
858 859
		var groupStart = group !== null ? group.start : 0;
		var groupCount = group !== null ? group.count : Infinity;
860

M
Mr.doob 已提交
861 862 863 864 865 866
		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 );

		//
867

868
		if ( object instanceof THREE.Mesh ) {
869

870
			if ( material.wireframe === true ) {
871

872
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
873
				renderer.setMode( _gl.LINES );
874

875
			} else {
M
Mr.doob 已提交
876 877

				switch ( object.drawMode ) {
878

B
Ben Adams 已提交
879 880 881 882 883 884 885 886 887 888 889 890 891
					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;

				}
892

893
			}
894

895

896
		} else if ( object instanceof THREE.Line ) {
897

898
			var lineWidth = material.linewidth;
899

900
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
901

902
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
903

904
			if ( object instanceof THREE.LineSegments ) {
905

906
				renderer.setMode( _gl.LINES );
907

908
			} else {
909

910
				renderer.setMode( _gl.LINE_STRIP );
911 912

			}
M
Mr.doob 已提交
913

914
		} else if ( object instanceof THREE.Points ) {
915 916

			renderer.setMode( _gl.POINTS );
917 918

		}
919

J
jfranc 已提交
920
		if ( geometry instanceof THREE.InstancedBufferGeometry ) {
M
Mr.doob 已提交
921 922 923

			if ( geometry.maxInstancedCount > 0 ) {

J
jfranc 已提交
924
				renderer.renderInstances( geometry, drawStart, drawCount );
M
Mr.doob 已提交
925

J
jfranc 已提交
926
			}
927 928 929

		} else {

M
Mr.doob 已提交
930
			renderer.render( drawStart, drawCount );
931

M
Mr.doob 已提交
932 933 934 935
		}

	};

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

M
Mr.doob 已提交
938
		var extension;
B
Ben Adams 已提交
939

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

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

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

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

M
Mr.doob 已提交
949 950 951
			}

		}
B
Ben Adams 已提交
952

953 954
		if ( startIndex === undefined ) startIndex = 0;

955 956
		state.initAttributes();

957
		var geometryAttributes = geometry.attributes;
958

959
		var programAttributes = program.getAttributes();
960

961
		var materialDefaultAttributeValues = material.defaultAttributeValues;
962

963
		for ( var name in programAttributes ) {
964

965
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
966

M
Mr.doob 已提交
967
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
968

969
				var geometryAttribute = geometryAttributes[ name ];
970

M
Mr.doob 已提交
971
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
972

973
					var size = geometryAttribute.itemSize;
G
gero3 已提交
974
					var buffer = objects.getAttributeBuffer( geometryAttribute );
975

B
Ben Adams 已提交
976
					if ( geometryAttribute instanceof THREE.InterleavedBufferAttribute ) {
977

M
Mr.doob 已提交
978 979 980 981 982
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

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

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

M
Mr.doob 已提交
986
							if ( geometry.maxInstancedCount === undefined ) {
987

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

M
Mr.doob 已提交
990
							}
B
Ben Adams 已提交
991

M
Mr.doob 已提交
992
						} else {
B
Ben Adams 已提交
993

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

M
Mr.doob 已提交
996
						}
B
Ben Adams 已提交
997

M
Mr.doob 已提交
998 999
						_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 已提交
1000

M
Mr.doob 已提交
1001
					} else {
B
Ben Adams 已提交
1002

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

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

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

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

M
Mr.doob 已提交
1011
							}
B
Ben Adams 已提交
1012

M
Mr.doob 已提交
1013 1014 1015 1016
						} else {

							state.enableAttribute( programAttribute );

M
Mr.doob 已提交
1017
						}
B
Ben Adams 已提交
1018

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

B
Ben Adams 已提交
1022
					}
M
Mr.doob 已提交
1023

1024 1025
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
1026
					var value = materialDefaultAttributeValues[ name ];
1027

1028
					if ( value !== undefined ) {
M
Mr.doob 已提交
1029

1030
						switch ( value.length ) {
M
Mr.doob 已提交
1031

1032 1033 1034
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
1035

1036 1037 1038
							case 3:
								_gl.vertexAttrib3fv( programAttribute, value );
								break;
M
Mr.doob 已提交
1039

1040 1041 1042
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
1043

1044 1045
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
1046 1047

						}
M
Mr.doob 已提交
1048 1049 1050 1051 1052 1053 1054 1055

					}

				}

			}

		}
1056

1057
		state.disableUnusedAttributes();
1058

M
Mr.doob 已提交
1059 1060
	}

M
Mr.doob 已提交
1061 1062
	// Sorting

1063
	function absNumericalSort( a, b ) {
1064

1065
		return Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );
1066 1067 1068

	}

M
Mr.doob 已提交
1069 1070
	function painterSortStable ( a, b ) {

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

U
unconed 已提交
1073
			return a.object.renderOrder - b.object.renderOrder;
1074

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

M
Mr.doob 已提交
1077
			return a.material.id - b.material.id;
1078 1079

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

M
Mr.doob 已提交
1081
			return a.z - b.z;
M
Mr.doob 已提交
1082 1083 1084

		} else {

1085
			return a.id - b.id;
M
Mr.doob 已提交
1086 1087 1088

		}

1089
	}
M
Mr.doob 已提交
1090

1091 1092
	function reversePainterSortStable ( a, b ) {

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

U
unconed 已提交
1095
			return a.object.renderOrder - b.object.renderOrder;
1096 1097

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

M
Mr.doob 已提交
1099
			return b.z - a.z;
1100 1101 1102 1103 1104 1105 1106

		} else {

			return a.id - b.id;

		}

1107
	}
1108

M
Mr.doob 已提交
1109 1110 1111 1112 1113 1114
	// Rendering

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

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

1115
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1116 1117 1118 1119
			return;

		}

M
Mr.doob 已提交
1120
		var fog = scene.fog;
M
Mr.doob 已提交
1121 1122 1123

		// reset caching for this frame

1124
		_currentGeometryProgram = '';
1125
		_currentMaterialId = - 1;
1126
		_currentCamera = null;
M
Mr.doob 已提交
1127 1128 1129

		// update scene graph

1130
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1131 1132 1133

		// update camera matrices and frustum

1134
		if ( camera.parent === null ) camera.updateMatrixWorld();
M
Mr.doob 已提交
1135 1136 1137 1138 1139 1140

		camera.matrixWorldInverse.getInverse( camera.matrixWorld );

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

M
Mr.doob 已提交
1141
		lights.length = 0;
1142

M
Mr.doob 已提交
1143 1144
		opaqueObjectsLastIndex = - 1;
		transparentObjectsLastIndex = - 1;
1145

M
Mr.doob 已提交
1146 1147 1148
		sprites.length = 0;
		lensFlares.length = 0;

1149
		projectObject( scene, camera );
M
Mr.doob 已提交
1150

1151 1152 1153
		opaqueObjects.length = opaqueObjectsLastIndex + 1;
		transparentObjects.length = transparentObjectsLastIndex + 1;

M
Mr.doob 已提交
1154
		if ( _this.sortObjects === true ) {
1155 1156 1157

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

1159 1160
		}

M
Mr.doob 已提交
1161
		//
M
Mr.doob 已提交
1162

M
Mr.doob 已提交
1163
		shadowMap.render( scene, camera );
M
Mr.doob 已提交
1164

1165 1166
		setupLights( lights, camera );

M
Mr.doob 已提交
1167 1168
		//

1169 1170 1171 1172
		_infoRender.calls = 0;
		_infoRender.vertices = 0;
		_infoRender.faces = 0;
		_infoRender.points = 0;
M
Mr.doob 已提交
1173

1174 1175 1176 1177 1178 1179
		if ( renderTarget === undefined ) {

			renderTarget = null;

		}

M
Mr.doob 已提交
1180 1181 1182 1183 1184 1185 1186 1187
		this.setRenderTarget( renderTarget );

		if ( this.autoClear || forceClear ) {

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

		}

1188
		//
M
Mr.doob 已提交
1189 1190 1191

		if ( scene.overrideMaterial ) {

1192
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1193

1194 1195
			renderObjects( opaqueObjects, camera, fog, overrideMaterial );
			renderObjects( transparentObjects, camera, fog, overrideMaterial );
1196

M
Mr.doob 已提交
1197 1198 1199 1200
		} else {

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

M
Mr.doob 已提交
1201
			state.setBlending( THREE.NoBlending );
1202
			renderObjects( opaqueObjects, camera, fog );
M
Mr.doob 已提交
1203 1204 1205

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

1206
			renderObjects( transparentObjects, camera, fog );
M
Mr.doob 已提交
1207 1208 1209 1210 1211

		}

		// custom render plugins (post pass)

M
Mr.doob 已提交
1212
		spritePlugin.render( scene, camera );
1213
		lensFlarePlugin.render( scene, camera, _currentViewport );
M
Mr.doob 已提交
1214 1215 1216

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

M
Mr.doob 已提交
1217 1218 1219
		if ( renderTarget ) {

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

M
Mr.doob 已提交
1221 1222 1223 1224 1225
			if ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&
					texture.minFilter !== THREE.NearestFilter &&
					texture.minFilter !== THREE.LinearFilter ) {

				updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1226 1227

			}
M
Mr.doob 已提交
1228 1229 1230

		}

1231
		// Ensure depth buffer writing is enabled so it can be cleared on next render
M
Mr.doob 已提交
1232

M
Mr.doob 已提交
1233 1234
		state.setDepthTest( true );
		state.setDepthWrite( true );
1235
		state.setColorWrite( true );
M
Mr.doob 已提交
1236 1237 1238 1239

		// _gl.finish();

	};
M
Mr.doob 已提交
1240

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

1243
		var array, index;
M
Mr.doob 已提交
1244

1245
		// allocate the next position in the appropriate array
M
Mr.doob 已提交
1246 1247 1248

		if ( material.transparent ) {

1249 1250
			array = transparentObjects;
			index = ++ transparentObjectsLastIndex;
M
Mr.doob 已提交
1251 1252 1253

		} else {

1254 1255 1256 1257 1258
			array = opaqueObjects;
			index = ++ opaqueObjectsLastIndex;

		}

1259 1260
		// recycle existing render item or grow the array

1261 1262 1263 1264 1265 1266 1267 1268 1269 1270
		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 已提交
1271 1272 1273

		} else {

1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284
			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 已提交
1285 1286 1287 1288 1289

		}

	}

1290
	function projectObject( object, camera ) {
M
Mr.doob 已提交
1291

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

1294
		if ( object.layers.test( camera.layers ) ) {
M
Mr.doob 已提交
1295

1296
			if ( object instanceof THREE.Light ) {
M
Mr.doob 已提交
1297

1298
				lights.push( object );
M
Mr.doob 已提交
1299

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

1302 1303 1304 1305 1306
				if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) {

					sprites.push( object );

				}
M
Mr.doob 已提交
1307

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

1310
				lensFlares.push( object );
M
Mr.doob 已提交
1311

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

1314
				if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1315

1316 1317
					_vector3.setFromMatrixPosition( object.matrixWorld );
					_vector3.applyProjection( _projScreenMatrix );
M
Mr.doob 已提交
1318

1319
				}
1320

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

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

1325
				if ( object instanceof THREE.SkinnedMesh ) {
M
Mr.doob 已提交
1326

1327
					object.skeleton.update();
1328

1329
				}
1330

1331
				if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) {
1332

1333
					var material = object.material;
1334

1335
					if ( material.visible === true ) {
M
Mr.doob 已提交
1336

1337
						if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1338

1339 1340 1341 1342
							_vector3.setFromMatrixPosition( object.matrixWorld );
							_vector3.applyProjection( _projScreenMatrix );

						}
M
Mr.doob 已提交
1343

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

S
SUNAG 已提交
1346
						if ( material instanceof THREE.MultiMaterial ) {
1347

1348 1349
							var groups = geometry.groups;
							var materials = material.materials;
1350

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

1353 1354
								var group = groups[ i ];
								var groupMaterial = materials[ group.materialIndex ];
1355

1356
								if ( groupMaterial.visible === true ) {
1357

1358 1359 1360
									pushRenderItem( object, geometry, groupMaterial, _vector3.z, group );

								}
M
Mr.doob 已提交
1361

M
Mr.doob 已提交
1362
							}
M
Mr.doob 已提交
1363

1364
						} else {
M
Mr.doob 已提交
1365

1366
							pushRenderItem( object, geometry, material, _vector3.z, null );
1367

1368
						}
O
OpenShift guest 已提交
1369

1370
					}
M
Mr.doob 已提交
1371

1372
				}
M
Mr.doob 已提交
1373

1374
			}
M
Mr.doob 已提交
1375

M
Mr.doob 已提交
1376
		}
M
Mr.doob 已提交
1377

M
Mr.doob 已提交
1378
		var children = object.children;
M
Mr.doob 已提交
1379

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

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

1384
		}
1385

1386
	}
M
Mr.doob 已提交
1387

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

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

1392
			var renderItem = renderList[ i ];
M
Mr.doob 已提交
1393

1394
			var object = renderItem.object;
M
Mr.doob 已提交
1395 1396 1397
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
M
Mr.doob 已提交
1398

1399 1400
			object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
			object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
M
Mr.doob 已提交
1401

M
Mr.doob 已提交
1402
			if ( object instanceof THREE.ImmediateRenderObject ) {
M
Mr.doob 已提交
1403

M
Mr.doob 已提交
1404
				setMaterial( material );
M
Mr.doob 已提交
1405

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

M
Mr.doob 已提交
1408
				_currentGeometryProgram = '';
M
Mr.doob 已提交
1409

M
Mr.doob 已提交
1410
				object.render( function ( object ) {
M
Mr.doob 已提交
1411

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

M
Mr.doob 已提交
1414
				} );
1415

M
Mr.doob 已提交
1416
			} else {
M
Mr.doob 已提交
1417

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

M
Mr.doob 已提交
1420
			}
M
Mr.doob 已提交
1421

1422
		}
M
Mr.doob 已提交
1423

1424
	}
G
gero3 已提交
1425

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

1428
		var materialProperties = properties.get( material );
G
gero3 已提交
1429

1430
		var parameters = programCache.getParameters( material, _lights, fog, object );
G
gero3 已提交
1431
		var code = programCache.getProgramCode( material, parameters );
G
gero3 已提交
1432

1433
		var program = materialProperties.program;
T
tschw 已提交
1434
		var programChange = true;
1435

1436
		if ( program === undefined ) {
B
Ben Adams 已提交
1437

M
Mr.doob 已提交
1438 1439
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1440

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

M
Mr.doob 已提交
1443
			// changed glsl or parameters
1444
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1445

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

T
tschw 已提交
1448
			// same glsl and uniform list
T
tschw 已提交
1449 1450
			return;

T
tschw 已提交
1451
		} else {
B
Ben Adams 已提交
1452

T
tschw 已提交
1453 1454
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1455 1456 1457

		}

1458
		if ( programChange ) {
B
Ben Adams 已提交
1459

1460
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1461

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

1464 1465 1466 1467 1468 1469
				materialProperties.__webglShader = {
					name: material.type,
					uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
					vertexShader: shader.vertexShader,
					fragmentShader: shader.fragmentShader
				};
B
Ben Adams 已提交
1470

1471
			} else {
B
Ben Adams 已提交
1472

1473 1474 1475 1476 1477 1478
				materialProperties.__webglShader = {
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
					fragmentShader: material.fragmentShader
				};
G
gero3 已提交
1479

1480
			}
G
gero3 已提交
1481

1482
			material.__webglShader = materialProperties.__webglShader;
G
gero3 已提交
1483

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

1486 1487
			materialProperties.program = program;
			material.program = program;
1488 1489 1490

		}

1491
		var attributes = program.getAttributes();
M
Mr.doob 已提交
1492 1493 1494 1495 1496

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

M
Mr.doob 已提交
1499
				if ( attributes[ 'morphTarget' + i ] >= 0 ) {
M
Mr.doob 已提交
1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

M
Mr.doob 已提交
1515
				if ( attributes[ 'morphNormal' + i ] >= 0 ) {
M
Mr.doob 已提交
1516 1517 1518 1519 1520 1521 1522 1523 1524

					material.numSupportedMorphNormals ++;

				}

			}

		}

1525
		materialProperties.uniformsList = [];
M
Mr.doob 已提交
1526

1527 1528
		var uniforms = materialProperties.__webglShader.uniforms,
			uniformLocations = materialProperties.program.getUniforms();
M
Mr.doob 已提交
1529

1530
		for ( var u in uniforms ) {
M
Mr.doob 已提交
1531

1532
			var location = uniformLocations[ u ];
1533 1534

			if ( location ) {
G
gero3 已提交
1535

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

1538
			}
M
Mr.doob 已提交
1539 1540 1541

		}

1542 1543
		if ( material instanceof THREE.MeshPhongMaterial ||
				material instanceof THREE.MeshLambertMaterial ||
1544
				material instanceof THREE.MeshStandardMaterial ||
1545 1546
				material.lights ) {

1547 1548
			// store the light setup it was created for

1549 1550
			materialProperties.lightsHash = _lights.hash;

1551 1552 1553 1554 1555
			// wire up the material to this renderer's lighting state

			uniforms.ambientLightColor.value = _lights.ambient;
			uniforms.directionalLights.value = _lights.directional;
			uniforms.spotLights.value = _lights.spot;
M
Mr.doob 已提交
1556
			uniforms.pointLights.value = _lights.point;
1557 1558
			uniforms.hemisphereLights.value = _lights.hemi;

1559 1560 1561 1562 1563 1564
			uniforms.directionalShadowMap.value = _lights.directionalShadowMap;
			uniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;
			uniforms.spotShadowMap.value = _lights.spotShadowMap;
			uniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;
			uniforms.pointShadowMap.value = _lights.pointShadowMap;
			uniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;
1565

1566 1567
		}

A
arose 已提交
1568 1569 1570 1571 1572 1573 1574 1575
		// detect dynamic uniforms

		materialProperties.hasDynamicUniforms = false;

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

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

1576
			if ( uniform.dynamic === true ) {
A
arose 已提交
1577 1578 1579 1580 1581 1582 1583 1584

				materialProperties.hasDynamicUniforms = true;
				break;

			}

		}

M
Mr.doob 已提交
1585
	}
M
Mr.doob 已提交
1586

1587 1588
	function setMaterial( material ) {

M
Mr.doob 已提交
1589 1590
		setMaterialFaces( material );

1591 1592
		if ( material.transparent === true ) {

1593
			state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha );
1594

1595 1596 1597 1598
		} else {

			state.setBlending( THREE.NoBlending );

1599 1600
		}

B
Ben Adams 已提交
1601
		state.setDepthFunc( material.depthFunc );
M
Mr.doob 已提交
1602 1603
		state.setDepthTest( material.depthTest );
		state.setDepthWrite( material.depthWrite );
1604
		state.setColorWrite( material.colorWrite );
M
Mr.doob 已提交
1605
		state.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
1606 1607 1608

	}

M
Mr.doob 已提交
1609 1610
	function setMaterialFaces( material ) {

1611
		material.side !== THREE.DoubleSide ? state.enable( _gl.CULL_FACE ) : state.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
1612 1613 1614 1615
		state.setFlipSided( material.side === THREE.BackSide );

	}

1616
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1617 1618 1619

		_usedTextureUnits = 0;

1620
		var materialProperties = properties.get( material );
1621

1622 1623 1624 1625 1626 1627
		if ( materialProperties.program === undefined ) {

			material.needsUpdate = true;

		}

1628
		if ( materialProperties.lightsHash !== _lights.hash ) {
1629 1630 1631 1632 1633 1634

			material.needsUpdate = true;

		}

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

1636
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1637 1638 1639 1640
			material.needsUpdate = false;

		}

1641
		var refreshProgram = false;
M
Mr.doob 已提交
1642
		var refreshMaterial = false;
1643
		var refreshLights = false;
M
Mr.doob 已提交
1644

1645
		var program = materialProperties.program,
1646
			p_uniforms = program.getUniforms(),
1647
			m_uniforms = materialProperties.__webglShader.uniforms;
M
Mr.doob 已提交
1648

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

1651 1652
			_gl.useProgram( program.program );
			_currentProgram = program.id;
M
Mr.doob 已提交
1653

1654
			refreshProgram = true;
M
Mr.doob 已提交
1655
			refreshMaterial = true;
1656
			refreshLights = true;
M
Mr.doob 已提交
1657 1658 1659 1660 1661 1662

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1663

M
Mr.doob 已提交
1664 1665 1666 1667
			refreshMaterial = true;

		}

1668
		if ( refreshProgram || camera !== _currentCamera ) {
M
Mr.doob 已提交
1669 1670 1671

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

G
gero3 已提交
1672
			if ( capabilities.logarithmicDepthBuffer ) {
1673

1674
				_gl.uniform1f( p_uniforms.logDepthBufFC, 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1675 1676 1677 1678

			}


1679 1680 1681 1682 1683 1684 1685 1686 1687
			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 已提交
1688
				refreshLights = true;		// remains set until update done
1689 1690

			}
M
Mr.doob 已提交
1691

1692 1693 1694 1695 1696
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
1697
				 material instanceof THREE.MeshStandardMaterial ||
1698 1699
				 material.envMap ) {

1700
				if ( p_uniforms.cameraPosition !== undefined ) {
1701 1702 1703 1704 1705 1706 1707 1708 1709 1710

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

				}

			}

			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
1711
				 material instanceof THREE.MeshBasicMaterial ||
1712
				 material instanceof THREE.MeshStandardMaterial ||
1713 1714 1715
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {

1716
				if ( p_uniforms.viewMatrix !== undefined ) {
1717 1718

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

1720 1721 1722 1723
				}

			}

B
Ben Houston 已提交
1724 1725 1726 1727

			if ( p_uniforms.toneMappingExposure !== undefined ) {

				_gl.uniform1f( p_uniforms.toneMappingExposure, _this.toneMappingExposure );
1728

B
Ben Houston 已提交
1729 1730 1731 1732 1733 1734 1735
			}

			if ( p_uniforms.toneMappingWhitePoint !== undefined ) {

				_gl.uniform1f( p_uniforms.toneMappingWhitePoint, _this.toneMappingWhitePoint );

			}
M
Mr.doob 已提交
1736

M
Mr.doob 已提交
1737 1738 1739 1740 1741 1742 1743 1744
		}

		// 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 ) {

1745
			if ( object.bindMatrix && p_uniforms.bindMatrix !== undefined ) {
1746 1747 1748 1749 1750

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

			}

1751
			if ( object.bindMatrixInverse && p_uniforms.bindMatrixInverse !== undefined ) {
1752 1753 1754 1755 1756

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

			}

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

1759
				if ( p_uniforms.boneTexture !== undefined ) {
M
Mr.doob 已提交
1760 1761 1762 1763

					var textureUnit = getTextureUnit();

					_gl.uniform1i( p_uniforms.boneTexture, textureUnit );
1764
					_this.setTexture( object.skeleton.boneTexture, textureUnit );
M
Mr.doob 已提交
1765 1766 1767

				}

1768
				if ( p_uniforms.boneTextureWidth !== undefined ) {
1769

1770
					_gl.uniform1i( p_uniforms.boneTextureWidth, object.skeleton.boneTextureWidth );
1771 1772 1773

				}

1774
				if ( p_uniforms.boneTextureHeight !== undefined ) {
1775

1776
					_gl.uniform1i( p_uniforms.boneTextureHeight, object.skeleton.boneTextureHeight );
1777 1778 1779

				}

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

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

1784
					_gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.skeleton.boneMatrices );
M
Mr.doob 已提交
1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795

				}

			}

		}

		if ( refreshMaterial ) {

			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
1796
				 material instanceof THREE.MeshStandardMaterial ||
M
Mr.doob 已提交
1797 1798
				 material.lights ) {

1799
				// the current material requires lighting info
M
Mr.doob 已提交
1800

T
tschw 已提交
1801 1802 1803 1804 1805 1806
				// 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 已提交
1807

T
tschw 已提交
1808
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1809

T
tschw 已提交
1810
			}
G
gero3 已提交
1811

T
tschw 已提交
1812
			// refresh uniforms common to several materials
G
gero3 已提交
1813

T
tschw 已提交
1814
			if ( fog && material.fog ) {
G
gero3 已提交
1815

T
tschw 已提交
1816
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1817 1818 1819 1820 1821

			}

			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
W
WestLangley 已提交
1822
				 material instanceof THREE.MeshPhongMaterial ||
1823
				 material instanceof THREE.MeshStandardMaterial ) {
M
Mr.doob 已提交
1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839

				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 );

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

M
Mr.doob 已提交
1842
				refreshUniformsPoints( m_uniforms, material );
M
Mr.doob 已提交
1843

1844 1845 1846 1847
			} else if ( material instanceof THREE.MeshLambertMaterial ) {

				refreshUniformsLambert( m_uniforms, material );

M
Mr.doob 已提交
1848 1849 1850 1851
			} else if ( material instanceof THREE.MeshPhongMaterial ) {

				refreshUniformsPhong( m_uniforms, material );

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

1854
				refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1855

M
Mr.doob 已提交
1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869
			} 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;

			}

			// load common uniforms

1870
			loadUniformsGeneric( materialProperties.uniformsList );
M
Mr.doob 已提交
1871 1872 1873 1874 1875

		}

		loadUniformsMatrices( p_uniforms, object );

1876
		if ( p_uniforms.modelMatrix !== undefined ) {
M
Mr.doob 已提交
1877 1878

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

M
Mr.doob 已提交
1880 1881
		}

1882
		if ( materialProperties.hasDynamicUniforms === true ) {
A
arose 已提交
1883

1884
			updateDynamicUniforms( materialProperties.uniformsList, object, camera );
A
arose 已提交
1885 1886 1887

		}

M
Mr.doob 已提交
1888 1889
		return program;

M
Mr.doob 已提交
1890
	}
M
Mr.doob 已提交
1891

1892
	function updateDynamicUniforms ( uniforms, object, camera ) {
A
arose 已提交
1893 1894 1895 1896 1897 1898

		var dynamicUniforms = [];

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

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

1901
			if ( onUpdateCallback !== undefined ) {
A
arose 已提交
1902

1903
				onUpdateCallback.bind( uniform )( object, camera );
A
arose 已提交
1904 1905 1906 1907 1908 1909 1910 1911 1912 1913
				dynamicUniforms.push( uniforms[ j ] );

			}

		}

		loadUniformsGeneric( dynamicUniforms );

	}

M
Mr.doob 已提交
1914 1915 1916 1917 1918 1919
	// Uniforms (refresh uniforms objects)

	function refreshUniformsCommon ( uniforms, material ) {

		uniforms.opacity.value = material.opacity;

1920
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
1921

1922
		if ( material.emissive ) {
M
Mr.doob 已提交
1923

1924
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
1925 1926 1927

		}

1928 1929 1930
		uniforms.map.value = material.map;
		uniforms.specularMap.value = material.specularMap;
		uniforms.alphaMap.value = material.alphaMap;
M
Mr.doob 已提交
1931

1932
		if ( material.aoMap ) {
1933

1934 1935
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1936 1937 1938

		}

M
Mr.doob 已提交
1939
		// uv repeat and offset setting priorities
M
Mr.doob 已提交
1940 1941 1942 1943 1944
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
1945
		// 6. emissive map
M
Mr.doob 已提交
1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

1957 1958 1959 1960
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
1961 1962 1963 1964 1965 1966 1967 1968
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

1969 1970 1971 1972 1973 1974 1975 1976
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

1977 1978 1979 1980
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

1981 1982 1983 1984
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
1985 1986 1987 1988
		}

		if ( uvScaleMap !== undefined ) {

M
Mr.doob 已提交
1989 1990 1991 1992 1993 1994
			if ( uvScaleMap instanceof THREE.WebGLRenderTarget ) {

				uvScaleMap = uvScaleMap.texture;

			}

M
Mr.doob 已提交
1995 1996 1997 1998 1999 2000 2001 2002
			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;
2003
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : - 1;
M
Mr.doob 已提交
2004

2005
		uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
2006 2007
		uniforms.refractionRatio.value = material.refractionRatio;

M
Mr.doob 已提交
2008
	}
M
Mr.doob 已提交
2009 2010 2011 2012 2013 2014

	function refreshUniformsLine ( uniforms, material ) {

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

M
Mr.doob 已提交
2015
	}
M
Mr.doob 已提交
2016 2017 2018 2019 2020 2021 2022

	function refreshUniformsDash ( uniforms, material ) {

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

M
Mr.doob 已提交
2023
	}
M
Mr.doob 已提交
2024

M
Mr.doob 已提交
2025
	function refreshUniformsPoints ( uniforms, material ) {
M
Mr.doob 已提交
2026

2027
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
2028
		uniforms.opacity.value = material.opacity;
2029 2030
		uniforms.size.value = material.size * _pixelRatio;
		uniforms.scale.value = _canvas.clientHeight / 2.0; // TODO: Cache this.
M
Mr.doob 已提交
2031 2032 2033

		uniforms.map.value = material.map;

2034 2035 2036 2037 2038 2039 2040 2041 2042
		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 已提交
2043
	}
M
Mr.doob 已提交
2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059

	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 已提交
2060
	}
M
Mr.doob 已提交
2061

2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078
	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 已提交
2079 2080
	function refreshUniformsPhong ( uniforms, material ) {

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

2084 2085 2086 2087
		if ( material.lightMap ) {

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

2089
		}
2090

2091
		if ( material.emissiveMap ) {
2092

2093
			uniforms.emissiveMap.value = material.emissiveMap;
2094

2095
		}
M
Mr.doob 已提交
2096

2097 2098 2099 2100
		if ( material.bumpMap ) {

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

2102
		}
M
Mr.doob 已提交
2103

2104 2105 2106 2107 2108 2109
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2110

2111 2112 2113 2114 2115
		if ( material.displacementMap ) {

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

2117
		}
2118 2119 2120

	}

2121
	function refreshUniformsStandard ( uniforms, material ) {
W
WestLangley 已提交
2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181

		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;

		}

	}

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

M
Mr.doob 已提交
2184
	function markUniformsLightsNeedsUpdate ( uniforms, value ) {
2185

M
Mr.doob 已提交
2186
		uniforms.ambientLightColor.needsUpdate = value;
2187

B
Ben Houston 已提交
2188 2189 2190 2191
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
		uniforms.hemisphereLights.needsUpdate = value;
2192

M
Mr.doob 已提交
2193
	}
2194

M
Mr.doob 已提交
2195 2196 2197 2198
	// Uniforms (load to GPU)

	function loadUniformsMatrices ( uniforms, object ) {

2199
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object.modelViewMatrix.elements );
M
Mr.doob 已提交
2200 2201 2202

		if ( uniforms.normalMatrix ) {

2203
			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object.normalMatrix.elements );
M
Mr.doob 已提交
2204 2205 2206

		}

M
Mr.doob 已提交
2207
	}
M
Mr.doob 已提交
2208 2209 2210 2211 2212

	function getTextureUnit() {

		var textureUnit = _usedTextureUnits;

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

G
gero3 已提交
2215
			console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
M
Mr.doob 已提交
2216 2217 2218 2219 2220 2221 2222

		}

		_usedTextureUnits += 1;

		return textureUnit;

M
Mr.doob 已提交
2223
	}
M
Mr.doob 已提交
2224

2225
	function loadUniform( uniform, type, location, value ) {
M
Mr.doob 已提交
2226

M
Mr.doob 已提交
2227
		var texture, textureUnit;
M
Mr.doob 已提交
2228

2229
		if ( type === '1i' ) {
M
Mr.doob 已提交
2230

2231
			_gl.uniform1i( location, value );
M
Mr.doob 已提交
2232

2233
		} else if ( type === '1f' ) {
2234

2235 2236 2237
			_gl.uniform1f( location, value );

		} else if ( type === '2f' ) {
M
Mr.doob 已提交
2238

2239
			_gl.uniform2f( location, value[ 0 ], value[ 1 ] );
M
Mr.doob 已提交
2240

2241
		} else if ( type === '3f' ) {
2242

2243
			_gl.uniform3f( location, value[ 0 ], value[ 1 ], value[ 2 ] );
2244

2245
		} else if ( type === '4f' ) {
2246

2247
			_gl.uniform4f( location, value[ 0 ], value[ 1 ], value[ 2 ], value[ 3 ] );
2248

2249
		} else if ( type === '1iv' ) {
2250

2251
			_gl.uniform1iv( location, value );
2252

2253
		} else if ( type === '3iv' ) {
2254

2255
			_gl.uniform3iv( location, value );
2256

2257
		} else if ( type === '1fv' ) {
2258

2259
			_gl.uniform1fv( location, value );
2260

2261
		} else if ( type === '2fv' ) {
2262

2263
			_gl.uniform2fv( location, value );
2264

2265
		} else if ( type === '3fv' ) {
2266

2267
			_gl.uniform3fv( location, value );
2268

2269
		} else if ( type === '4fv' ) {
2270

2271
			_gl.uniform4fv( location, value );
M
Mr.doob 已提交
2272

2273
		} else if ( type === 'Matrix2fv' ) {
M
Mr.doob 已提交
2274

2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285
			_gl.uniformMatrix2fv( location, false, value );

		} else if ( type === 'Matrix3fv' ) {

			_gl.uniformMatrix3fv( location, false, value );

		} else if ( type === 'Matrix4fv' ) {

			_gl.uniformMatrix4fv( location, false, value );

		//
M
Mr.doob 已提交
2286

2287
		} else if ( type === 'i' ) {
M
Mr.doob 已提交
2288

2289 2290
			// single integer
			_gl.uniform1i( location, value );
M
Mr.doob 已提交
2291

2292
		} else if ( type === 'f' ) {
M
Mr.doob 已提交
2293

2294 2295
			// single float
			_gl.uniform1f( location, value );
M
Mr.doob 已提交
2296

2297
		} else if ( type === 'v2' ) {
M
Mr.doob 已提交
2298

2299 2300
			// single THREE.Vector2
			_gl.uniform2f( location, value.x, value.y );
M
Mr.doob 已提交
2301

2302
		} else if ( type === 'v3' ) {
M
Mr.doob 已提交
2303

2304 2305
			// single THREE.Vector3
			_gl.uniform3f( location, value.x, value.y, value.z );
M
Mr.doob 已提交
2306

2307
		} else if ( type === 'v4' ) {
M
Mr.doob 已提交
2308

2309 2310
			// single THREE.Vector4
			_gl.uniform4f( location, value.x, value.y, value.z, value.w );
M
Mr.doob 已提交
2311

2312
		} else if ( type === 'c' ) {
M
Mr.doob 已提交
2313

2314 2315
			// single THREE.Color
			_gl.uniform3f( location, value.r, value.g, value.b );
M
Mr.doob 已提交
2316

2317
		} else if ( type === 's' ) {
M
Mr.doob 已提交
2318

2319
			// TODO: Optimize this
M
Mr.doob 已提交
2320

2321
			var properties = uniform.properties;
2322

2323
			for ( var name in properties ) {
2324

2325 2326 2327
				var property = properties[ name ];
				var locationProperty = location[ name ];
				var valueProperty = value[ name ];
2328

2329
				loadUniform( property, property.type, locationProperty, valueProperty );
2330 2331

			}
2332

2333 2334 2335 2336
		} else if ( type === 'sa' ) {

			// TODO: Optimize this

M
Mr.doob 已提交
2337
			var properties = uniform.properties;
2338

M
Mr.doob 已提交
2339
			for ( var i = 0, l = value.length; i < l; i ++ ) {
2340

M
Mr.doob 已提交
2341
				for ( var name in properties ) {
2342

M
Mr.doob 已提交
2343 2344 2345
					var property = properties[ name ];
					var locationProperty =  location[ i ][ name ];
					var valueProperty = value[ i ][ name ];
2346

M
Mr.doob 已提交
2347
					loadUniform( property, property.type, locationProperty, valueProperty );
M
Mr.doob 已提交
2348

2349 2350
				}

2351
			}
2352

2353
		} else if ( type === 'iv1' ) {
M
Mr.doob 已提交
2354

2355 2356
			// flat array of integers (JS or typed array)
			_gl.uniform1iv( location, value );
M
Mr.doob 已提交
2357

2358
		} else if ( type === 'iv' ) {
M
Mr.doob 已提交
2359

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

2363
		} else if ( type === 'fv1' ) {
M
Mr.doob 已提交
2364

2365 2366
			// flat array of floats (JS or typed array)
			_gl.uniform1fv( location, value );
M
Mr.doob 已提交
2367

2368
		} else if ( type === 'fv' ) {
M
Mr.doob 已提交
2369

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

2373
		} else if ( type === 'v2v' ) {
M
Mr.doob 已提交
2374

2375
			// array of THREE.Vector2
M
Mr.doob 已提交
2376

2377
			if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2378

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

2381
			}
M
Mr.doob 已提交
2382

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

2385 2386
				uniform._array[ i2 + 0 ] = value[ i ].x;
				uniform._array[ i2 + 1 ] = value[ i ].y;
M
Mr.doob 已提交
2387

2388
			}
2389

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

2392
		} else if ( type === 'v3v' ) {
M
Mr.doob 已提交
2393

2394
			// array of THREE.Vector3
2395

2396
			if ( uniform._array === undefined ) {
2397

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

2400
			}
M
Mr.doob 已提交
2401

2402
			for ( var i = 0, i3 = 0, il = value.length; i < il; i ++, i3 += 3 ) {
M
Mr.doob 已提交
2403

2404 2405 2406
				uniform._array[ i3 + 0 ] = value[ i ].x;
				uniform._array[ i3 + 1 ] = value[ i ].y;
				uniform._array[ i3 + 2 ] = value[ i ].z;
M
Mr.doob 已提交
2407

2408
			}
M
Mr.doob 已提交
2409

2410
			_gl.uniform3fv( location, uniform._array );
M
Mr.doob 已提交
2411

2412
		} else if ( type === 'v4v' ) {
M
Mr.doob 已提交
2413

2414
			// array of THREE.Vector4
M
Mr.doob 已提交
2415

2416
			if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2417

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

2420
			}
R
Ryan Tsao 已提交
2421

2422
			for ( var i = 0, i4 = 0, il = value.length; i < il; i ++, i4 += 4 ) {
R
Ryan Tsao 已提交
2423

2424 2425 2426 2427
				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;
R
Ryan Tsao 已提交
2428

2429
			}
R
Ryan Tsao 已提交
2430

2431
			_gl.uniform4fv( location, uniform._array );
R
Ryan Tsao 已提交
2432

2433
		} else if ( type === 'm2' ) {
R
Ryan Tsao 已提交
2434

2435 2436
			// single THREE.Matrix2
			_gl.uniformMatrix2fv( location, false, value.elements );
R
Ryan Tsao 已提交
2437

2438
		} else if ( type === 'm3' ) {
R
Ryan Tsao 已提交
2439

2440 2441
			// single THREE.Matrix3
			_gl.uniformMatrix3fv( location, false, value.elements );
M
Mr.doob 已提交
2442

2443
		} else if ( type === 'm3v' ) {
M
Mr.doob 已提交
2444

2445
			// array of THREE.Matrix3
M
Mr.doob 已提交
2446

2447
			if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2448

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

2451
			}
M
Mr.doob 已提交
2452

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

2455
				value[ i ].flattenToArrayOffset( uniform._array, i * 9 );
2456

2457
			}
2458

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

2461
		} else if ( type === 'm4' ) {
M
Mr.doob 已提交
2462

2463 2464
			// single THREE.Matrix4
			_gl.uniformMatrix4fv( location, false, value.elements );
M
Mr.doob 已提交
2465

2466
		} else if ( type === 'm4v' ) {
M
Mr.doob 已提交
2467

2468
			// array of THREE.Matrix4
M
Mr.doob 已提交
2469

2470
			if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2471

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

2474
			}
M
Mr.doob 已提交
2475

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

2478
				value[ i ].flattenToArrayOffset( uniform._array, i * 16 );
M
Mr.doob 已提交
2479

2480
			}
M
Mr.doob 已提交
2481

2482
			_gl.uniformMatrix4fv( location, false, uniform._array );
M
Mr.doob 已提交
2483

2484
		} else if ( type === 't' ) {
M
Mr.doob 已提交
2485

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

2488 2489
			texture = value;
			textureUnit = getTextureUnit();
M
Mr.doob 已提交
2490

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

2493
			if ( ! texture ) return;
M
Mr.doob 已提交
2494

2495 2496
			if ( texture instanceof THREE.CubeTexture ||
				 ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
M
Mr.doob 已提交
2497

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

2500
				setCubeTexture( texture, textureUnit );
2501

2502
			} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
2503

2504
				setCubeTextureDynamic( texture.texture, textureUnit );
2505

2506
			} else if ( texture instanceof THREE.WebGLRenderTarget ) {
2507

2508
				_this.setTexture( texture.texture, textureUnit );
2509

2510
			} else {
M
Mr.doob 已提交
2511

2512
				_this.setTexture( texture, textureUnit );
M
Mr.doob 已提交
2513

2514
			}
M
Mr.doob 已提交
2515

2516
		} else if ( type === 'tv' ) {
2517

2518
			// array of THREE.Texture (2d or cube)
M
Mr.doob 已提交
2519

2520
			if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2521

2522
				uniform._array = [];
G
gero3 已提交
2523

2524
			}
M
Mr.doob 已提交
2525

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

2528
				uniform._array[ i ] = getTextureUnit();
2529

2530
			}
M
Mr.doob 已提交
2531

2532
			_gl.uniform1iv( location, uniform._array );
M
Mr.doob 已提交
2533

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

2536 2537
				texture = uniform.value[ i ];
				textureUnit = uniform._array[ i ];
2538

2539
				if ( ! texture ) continue;
2540

2541
				if ( texture instanceof THREE.CubeTexture ||
2542
					 ( texture.image instanceof Array && texture.image.length === 6 ) ) {
2543

2544
					// CompressedTexture can have Array in image :/
2545

2546
					setCubeTexture( texture, textureUnit );
2547

2548
				} else if ( texture instanceof THREE.WebGLRenderTarget ) {
2549

2550
					_this.setTexture( texture.texture, textureUnit );
2551

2552
				} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
2553

2554
					setCubeTextureDynamic( texture.texture, textureUnit );
M
Mr.doob 已提交
2555

2556
				} else {
M
Mr.doob 已提交
2557

2558
					_this.setTexture( texture, textureUnit );
M
Mr.doob 已提交
2559

2560
				}
M
Mr.doob 已提交
2561

2562
			}
2563

2564
		} else {
2565

2566
			console.warn( 'THREE.WebGLRenderer: Unknown uniform type: ' + type );
2567

2568
		}
2569

2570
	}
2571

2572
	function loadUniformsGeneric( uniforms ) {
2573

2574
		for ( var i = 0, l = uniforms.length; i < l; i ++ ) {
2575

2576
			var uniform = uniforms[ i ][ 0 ];
2577

2578 2579
			// needsUpdate property is not added to all uniforms.
			if ( uniform.needsUpdate === false ) continue;
2580

2581 2582 2583
			var type = uniform.type;
			var location = uniforms[ i ][ 1 ];
			var value = uniform.value;
2584

2585
			loadUniform( uniform, type, location, value );
M
Mr.doob 已提交
2586 2587 2588

		}

M
Mr.doob 已提交
2589
	}
M
Mr.doob 已提交
2590

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

B
brason 已提交
2593
		var l, ll, light,
M
Mr.doob 已提交
2594
		r = 0, g = 0, b = 0,
B
Ben Houston 已提交
2595
		color,
B
brason 已提交
2596
		intensity,
M
Mr.doob 已提交
2597 2598
		distance,

2599
		viewMatrix = camera.matrixWorldInverse,
M
Mr.doob 已提交
2600

M
Mr.doob 已提交
2601
		directionalLength = 0,
M
Mr.doob 已提交
2602 2603
		pointLength = 0,
		spotLength = 0,
2604
		hemiLength = 0;
M
Mr.doob 已提交
2605

2606
		_lights.shadows = 0;
2607 2608
		_lights.shadowsPointLight = 0;

M
Mr.doob 已提交
2609 2610 2611 2612 2613 2614 2615 2616 2617 2618
		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 ) {

2619 2620 2621
				r += color.r * intensity;
				g += color.g * intensity;
				b += color.b * intensity;
M
Mr.doob 已提交
2622 2623 2624

			} else if ( light instanceof THREE.DirectionalLight ) {

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

2627
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
M
Mr.doob 已提交
2628
				uniforms.direction.setFromMatrixPosition( light.matrixWorld );
2629
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
M
Mr.doob 已提交
2630 2631 2632
				uniforms.direction.sub( _vector3 );
				uniforms.direction.transformDirection( viewMatrix );

2633
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2634

2635
				if ( light.castShadow ) {
M
Mr.doob 已提交
2636

2637 2638 2639
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;
2640

2641
					_lights.shadows ++;
2642

2643 2644
				}

2645 2646
				_lights.directionalShadowMap[ directionalLength ] = light.shadow.map;
				_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
2647
				_lights.directional[ directionalLength ++ ] = uniforms;
M
Mr.doob 已提交
2648

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

M
Mr.doob 已提交
2651
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2652 2653 2654

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

M
Mr.doob 已提交
2656 2657 2658 2659 2660 2661 2662 2663
				uniforms.color.copy( color ).multiplyScalar( intensity );
				uniforms.distance = distance;

				uniforms.direction.setFromMatrixPosition( light.matrixWorld );
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
				uniforms.direction.sub( _vector3 );
				uniforms.direction.transformDirection( viewMatrix );

2664 2665
				uniforms.coneCos = Math.cos( light.angle );
				uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
M
Mr.doob 已提交
2666
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
M
Mr.doob 已提交
2667

2668
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2669

2670 2671
				if ( light.castShadow ) {

2672 2673 2674
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;
2675

2676
					_lights.shadows ++;
2677

2678 2679
				}

2680 2681
				_lights.spotShadowMap[ spotLength ] = light.shadow.map;
				_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;
M
Mr.doob 已提交
2682
				_lights.spot[ spotLength ++ ] = uniforms;
2683

M
Mr.doob 已提交
2684
			} else if ( light instanceof THREE.PointLight ) {
M
Mr.doob 已提交
2685

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

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

M
Mr.doob 已提交
2691 2692
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
				uniforms.distance = light.distance;
M
Mr.doob 已提交
2693 2694
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;

2695
				uniforms.shadow = light.castShadow;
2696

M
Mr.doob 已提交
2697
				if ( light.castShadow ) {
2698

2699 2700 2701 2702
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;

2703
					_lights.shadows ++;
M
Mr.doob 已提交
2704

2705
				}
2706

2707
				_lights.pointShadowMap[ pointLength ] = light.shadow.map;
2708

2709 2710 2711
				if ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {

					_lights.pointShadowMatrix[ pointLength ] = new THREE.Matrix4();
2712

2713 2714
				}

2715 2716 2717 2718 2719
				// 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();
				_lights.pointShadowMatrix[ pointLength ].identity().setPosition( _vector3 );

M
Mr.doob 已提交
2720
				_lights.point[ pointLength ++ ] = uniforms;
2721

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

M
Mr.doob 已提交
2724
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2725 2726 2727 2728

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

M
Mr.doob 已提交
2730 2731
				uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
				uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
M
Mr.doob 已提交
2732

M
Mr.doob 已提交
2733
				_lights.hemi[ hemiLength ++ ] = uniforms;
M
Mr.doob 已提交
2734 2735 2736 2737 2738

			}

		}

M
Mr.doob 已提交
2739 2740 2741
		_lights.ambient[ 0 ] = r;
		_lights.ambient[ 1 ] = g;
		_lights.ambient[ 2 ] = b;
M
Mr.doob 已提交
2742

M
Mr.doob 已提交
2743 2744
		_lights.directional.length = directionalLength;
		_lights.spot.length = spotLength;
2745
		_lights.point.length = pointLength;
M
Mr.doob 已提交
2746
		_lights.hemi.length = hemiLength;
2747

2748
		_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + hemiLength + ',' + _lights.shadows;
2749

M
Mr.doob 已提交
2750
	}
M
Mr.doob 已提交
2751 2752 2753 2754 2755 2756 2757

	// GL state setting

	this.setFaceCulling = function ( cullFace, frontFaceDirection ) {

		if ( cullFace === THREE.CullFaceNone ) {

2758
			state.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785

		} 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 );

			}

2786
			state.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
2787 2788 2789 2790 2791 2792 2793

		}

	};

	// Textures

M
Mr.doob 已提交
2794
	function setTextureParameters ( textureType, texture, isPowerOfTwoImage ) {
M
Mr.doob 已提交
2795

2796 2797
		var extension;

M
Mr.doob 已提交
2798
		if ( isPowerOfTwoImage ) {
M
Mr.doob 已提交
2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809

			_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 已提交
2810 2811 2812

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

M
Mr.doob 已提交
2813
				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 已提交
2814

2815
			}
M
Mr.doob 已提交
2816 2817 2818 2819

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

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

M
Mr.doob 已提交
2822
				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 已提交
2823

2824
			}
M
Mr.doob 已提交
2825

M
Mr.doob 已提交
2826 2827
		}

2828 2829
		extension = extensions.get( 'EXT_texture_filter_anisotropic' );

2830
		if ( extension ) {
M
Mr.doob 已提交
2831

2832 2833
			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 已提交
2834

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

2837
				_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _this.getMaxAnisotropy() ) );
2838
				properties.get( texture ).__currentAnisotropy = texture.anisotropy;
M
Mr.doob 已提交
2839 2840 2841 2842 2843

			}

		}

M
Mr.doob 已提交
2844
	}
M
Mr.doob 已提交
2845

2846
	function uploadTexture( textureProperties, texture, slot ) {
2847

2848
		if ( textureProperties.__webglInit === undefined ) {
2849

2850
			textureProperties.__webglInit = true;
2851 2852 2853

			texture.addEventListener( 'dispose', onTextureDispose );

2854
			textureProperties.__webglTexture = _gl.createTexture();
2855

2856
			_infoMemory.textures ++;
2857 2858

		}
M
Mr.doob 已提交
2859

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

H
Henri Astre 已提交
2863 2864 2865 2866
		_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 );

2867
		var image = clampToMaxSize( texture.image, capabilities.maxTextureSize );
2868

2869
		if ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {
M
Mr.doob 已提交
2870

2871
			image = makePowerOfTwo( image );
M
Mr.doob 已提交
2872 2873 2874

		}

M
Mr.doob 已提交
2875
		var isPowerOfTwoImage = isPowerOfTwo( image ),
H
Henri Astre 已提交
2876 2877
		glFormat = paramThreeToGL( texture.format ),
		glType = paramThreeToGL( texture.type );
M
Mr.doob 已提交
2878

M
Mr.doob 已提交
2879
		setTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );
M
Mr.doob 已提交
2880

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

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

H
Henri Astre 已提交
2885 2886 2887
			// 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 已提交
2888

M
Mr.doob 已提交
2889
			if ( mipmaps.length > 0 && isPowerOfTwoImage ) {
H
Henri Astre 已提交
2890 2891

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

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

H
Henri Astre 已提交
2896
				}
M
Mr.doob 已提交
2897

H
Henri Astre 已提交
2898
				texture.generateMipmaps = false;
M
Mr.doob 已提交
2899

H
Henri Astre 已提交
2900
			} else {
M
Mr.doob 已提交
2901

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

H
Henri Astre 已提交
2904
			}
M
Mr.doob 已提交
2905

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

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

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

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

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

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

2918
					} else {
M
Mr.doob 已提交
2919

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

2922
					}
M
Mr.doob 已提交
2923

H
Henri Astre 已提交
2924
				} else {
M
Mr.doob 已提交
2925

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

M
Mr.doob 已提交
2928 2929
				}

H
Henri Astre 已提交
2930 2931
			}

G
gero3 已提交
2932 2933 2934
		} else {

			// regular Texture (image, video, canvas)
H
Henri Astre 已提交
2935 2936 2937 2938 2939

			// 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 已提交
2940
			if ( mipmaps.length > 0 && isPowerOfTwoImage ) {
M
Mr.doob 已提交
2941

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

					mipmap = mipmaps[ i ];
2945
					state.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );
M
Mr.doob 已提交
2946 2947 2948

				}

H
Henri Astre 已提交
2949
				texture.generateMipmaps = false;
M
Mr.doob 已提交
2950

H
Henri Astre 已提交
2951
			} else {
M
Mr.doob 已提交
2952

2953
				state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );
M
Mr.doob 已提交
2954

H
Henri Astre 已提交
2955
			}
M
Mr.doob 已提交
2956

H
Henri Astre 已提交
2957
		}
M
Mr.doob 已提交
2958

M
Mr.doob 已提交
2959
		if ( texture.generateMipmaps && isPowerOfTwoImage ) _gl.generateMipmap( _gl.TEXTURE_2D );
M
Mr.doob 已提交
2960

2961
		textureProperties.__version = texture.version;
M
Mr.doob 已提交
2962

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

2965
	}
M
Mr.doob 已提交
2966

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

2969 2970 2971
		var textureProperties = properties.get( texture );

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

2973
			var image = texture.image;
M
Mr.doob 已提交
2974

2975 2976
			if ( image === undefined ) {

2977
				console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );
2978 2979 2980 2981
				return;

			}

2982
			if ( image.complete === false ) {
M
Mr.doob 已提交
2983

2984
				console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );
2985 2986 2987 2988
				return;

			}

2989
			uploadTexture( textureProperties, texture, slot );
2990

2991
			return;
M
Mr.doob 已提交
2992 2993 2994

		}

B
Ben Adams 已提交
2995
		state.activeTexture( _gl.TEXTURE0 + slot );
2996
		state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
2997

M
Mr.doob 已提交
2998 2999 3000 3001
	};

	function clampToMaxSize ( image, maxSize ) {

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

3004 3005
			// Warning: Scaling through the canvas will only work with images that use
			// premultiplied alpha.
M
Mr.doob 已提交
3006

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

3009 3010 3011
			var canvas = document.createElement( 'canvas' );
			canvas.width = Math.floor( image.width * scale );
			canvas.height = Math.floor( image.height * scale );
M
Mr.doob 已提交
3012

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

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

3018 3019 3020
			return canvas;

		}
M
Mr.doob 已提交
3021

3022
		return image;
M
Mr.doob 已提交
3023 3024 3025

	}

M
Mr.doob 已提交
3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061
	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 已提交
3062 3063
	function setCubeTexture ( texture, slot ) {

3064
		var textureProperties = properties.get( texture );
3065

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

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

3070
				if ( ! textureProperties.__image__webglTextureCube ) {
M
Mr.doob 已提交
3071

3072 3073
					texture.addEventListener( 'dispose', onTextureDispose );

3074
					textureProperties.__image__webglTextureCube = _gl.createTexture();
M
Mr.doob 已提交
3075

3076
					_infoMemory.textures ++;
M
Mr.doob 已提交
3077 3078 3079

				}

B
Ben Adams 已提交
3080
				state.activeTexture( _gl.TEXTURE0 + slot );
3081
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
3082 3083 3084

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

M
Mr.doob 已提交
3085 3086
				var isCompressed = texture instanceof THREE.CompressedTexture;
				var isDataTexture = texture.image[ 0 ] instanceof THREE.DataTexture;
M
Mr.doob 已提交
3087 3088 3089 3090 3091

				var cubeImage = [];

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

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

G
gero3 已提交
3094
						cubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );
M
Mr.doob 已提交
3095 3096 3097

					} else {

3098
						cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];
M
Mr.doob 已提交
3099 3100 3101 3102 3103 3104

					}

				}

				var image = cubeImage[ 0 ],
M
Mr.doob 已提交
3105
				isPowerOfTwoImage = isPowerOfTwo( image ),
M
Mr.doob 已提交
3106 3107 3108
				glFormat = paramThreeToGL( texture.format ),
				glType = paramThreeToGL( texture.type );

M
Mr.doob 已提交
3109
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );
M
Mr.doob 已提交
3110 3111 3112

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

3113
					if ( ! isCompressed ) {
M
Mr.doob 已提交
3114

M
Mr.doob 已提交
3115
						if ( isDataTexture ) {
3116

3117
							state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );
3118

M
Mr.doob 已提交
3119
						} else {
3120

3121
							state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
3122

M
Mr.doob 已提交
3123 3124
						}

3125
					} else {
3126

M
Mr.doob 已提交
3127 3128
						var mipmap, mipmaps = cubeImage[ i ].mipmaps;

3129
						for ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {
M
Mr.doob 已提交
3130 3131

							mipmap = mipmaps[ j ];
M
Mr.doob 已提交
3132

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

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

3137
									state.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
M
Mr.doob 已提交
3138

3139
								} else {
M
Mr.doob 已提交
3140

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

3143
								}
M
Mr.doob 已提交
3144

3145
							} else {
M
Mr.doob 已提交
3146

3147
								state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
M
Mr.doob 已提交
3148

3149
							}
M
Mr.doob 已提交
3150

3151
						}
M
Mr.doob 已提交
3152

M
Mr.doob 已提交
3153
					}
M
Mr.doob 已提交
3154

M
Mr.doob 已提交
3155 3156
				}

M
Mr.doob 已提交
3157
				if ( texture.generateMipmaps && isPowerOfTwoImage ) {
M
Mr.doob 已提交
3158 3159 3160 3161 3162

					_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

				}

3163
				textureProperties.__version = texture.version;
M
Mr.doob 已提交
3164

B
Ben Adams 已提交
3165
				if ( texture.onUpdate ) texture.onUpdate( texture );
M
Mr.doob 已提交
3166 3167 3168

			} else {

B
Ben Adams 已提交
3169
				state.activeTexture( _gl.TEXTURE0 + slot );
3170
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
3171 3172 3173 3174 3175

			}

		}

M
Mr.doob 已提交
3176
	}
M
Mr.doob 已提交
3177 3178 3179

	function setCubeTextureDynamic ( texture, slot ) {

B
Ben Adams 已提交
3180
		state.activeTexture( _gl.TEXTURE0 + slot );
3181
		state.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );
M
Mr.doob 已提交
3182

M
Mr.doob 已提交
3183
	}
M
Mr.doob 已提交
3184 3185 3186

	// Render targets

3187 3188
	// Setup storage for target texture and bind it to correct framebuffer
	function setupFrameBufferTexture ( framebuffer, renderTarget, attachment, textureTarget ) {
M
Mr.doob 已提交
3189

3190 3191 3192
		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 已提交
3193
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
3194 3195
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
M
Mr.doob 已提交
3196

M
Mr.doob 已提交
3197
	}
M
Mr.doob 已提交
3198

3199 3200
	// Setup storage for internal depth/stencil buffers and bind to correct framebuffer
	function setupRenderBufferStorage ( renderbuffer, renderTarget ) {
M
Mr.doob 已提交
3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215

		_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 {

3216
			// FIXME: We don't support !depth !stencil
M
Mr.doob 已提交
3217 3218 3219 3220
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );

		}

3221
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
M
Mr.doob 已提交
3222

M
Mr.doob 已提交
3223
	}
M
Mr.doob 已提交
3224

3225
	// Setup GL resources for a non-texture depth buffer
M
Marius Kintel 已提交
3226
	function setupDepthRenderbuffer( renderTarget ) {
M
Mr.doob 已提交
3227

3228
		var renderTargetProperties = properties.get( renderTarget );
M
Mr.doob 已提交
3229 3230

		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
M
Mr.doob 已提交
3231

3232
		if ( isCube ) {
M
Mr.doob 已提交
3233

3234
			renderTargetProperties.__webglDepthbuffer = [];
M
Mr.doob 已提交
3235

3236
			for ( var i = 0; i < 6; i ++ ) {
M
Mr.doob 已提交
3237

M
Marius Kintel 已提交
3238
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );
3239 3240
				renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();
				setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );
M
Mr.doob 已提交
3241 3242

			}
B
Ben Adams 已提交
3243

M
Mr.doob 已提交
3244
		} else {
M
Mr.doob 已提交
3245

M
Marius Kintel 已提交
3246
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );
3247 3248
			renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
			setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );
M
Mr.doob 已提交
3249

3250
		}
M
Mr.doob 已提交
3251

M
Marius Kintel 已提交
3252
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
M
Mr.doob 已提交
3253

M
Mr.doob 已提交
3254
	}
M
Mr.doob 已提交
3255

3256
	// Set up GL resources for the render target
M
Marius Kintel 已提交
3257
	function setupRenderTarget( renderTarget ) {
M
Mr.doob 已提交
3258

3259 3260
		var renderTargetProperties = properties.get( renderTarget );
		var textureProperties = properties.get( renderTarget.texture );
M
Mr.doob 已提交
3261

3262
		renderTarget.addEventListener( 'dispose', onRenderTargetDispose );
M
Mr.doob 已提交
3263

3264
		textureProperties.__webglTexture = _gl.createTexture();
M
Mr.doob 已提交
3265

3266
		_infoMemory.textures ++;
M
Mr.doob 已提交
3267

3268 3269
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
		var isTargetPowerOfTwo = THREE.Math.isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height );
M
Mr.doob 已提交
3270

3271
		// Setup framebuffer
M
Mr.doob 已提交
3272

3273
		if ( isCube ) {
M
Mr.doob 已提交
3274

3275
			renderTargetProperties.__webglFramebuffer = [];
M
Mr.doob 已提交
3276

3277
			for ( var i = 0; i < 6; i ++ ) {
M
Mr.doob 已提交
3278

3279
				renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();
M
Mr.doob 已提交
3280

3281
			}
M
Mr.doob 已提交
3282

3283
		} else {
M
Mr.doob 已提交
3284

3285
			renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
M
Mr.doob 已提交
3286

3287
		}
M
Mr.doob 已提交
3288

3289
		// Setup color buffer
M
Mr.doob 已提交
3290

3291
		if ( isCube ) {
M
Mr.doob 已提交
3292

3293 3294
			state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
			setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );
M
Mr.doob 已提交
3295

3296
			for ( var i = 0; i < 6; i ++ ) {
M
Mr.doob 已提交
3297

3298
				setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
M
Mr.doob 已提交
3299 3300 3301

			}

3302 3303
			if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
			state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
M
Mr.doob 已提交
3304

3305
		} else {
M
Mr.doob 已提交
3306

3307 3308 3309
			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 已提交
3310

3311 3312
			if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
			state.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
3313

3314
		}
M
Mr.doob 已提交
3315

3316
		// Setup depth and stencil buffers
3317

3318
		if ( renderTarget.depthBuffer ) {
M
Mr.doob 已提交
3319

M
Marius Kintel 已提交
3320
			setupDepthRenderbuffer( renderTarget );
M
Mr.doob 已提交
3321

3322
		}
M
Mr.doob 已提交
3323

3324
	}
M
Mr.doob 已提交
3325

3326 3327 3328 3329 3330 3331
	this.getCurrentRenderTarget = function() {

		return _currentRenderTarget;

	}

3332
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
3333

3334 3335
		_currentRenderTarget = renderTarget;

3336
		if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {
M
Mr.doob 已提交
3337

M
Marius Kintel 已提交
3338
			setupRenderTarget( renderTarget );
M
Mr.doob 已提交
3339 3340 3341

		}

3342
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
3343
		var framebuffer;
M
Mr.doob 已提交
3344 3345 3346

		if ( renderTarget ) {

3347
			var renderTargetProperties = properties.get( renderTarget );
F
Fordy 已提交
3348

M
Mr.doob 已提交
3349 3350
			if ( isCube ) {

3351
				framebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
3352 3353 3354

			} else {

3355
				framebuffer = renderTargetProperties.__webglFramebuffer;
M
Mr.doob 已提交
3356 3357 3358

			}

3359 3360
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
3361

3362
			_currentViewport.copy( renderTarget.viewport );
M
Mr.doob 已提交
3363 3364 3365 3366 3367

		} else {

			framebuffer = null;

3368
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
3369
			_currentScissorTest = _scissorTest;
3370

3371
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
M
Mr.doob 已提交
3372 3373 3374

		}

M
Mr.doob 已提交
3375
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
3376 3377 3378 3379 3380 3381

			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
			_currentFramebuffer = framebuffer;

		}

3382 3383
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
3384

3385
		state.viewport( _currentViewport );
3386

M
Mr.doob 已提交
3387 3388 3389
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
3390
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
3391 3392 3393

		}

M
Mr.doob 已提交
3394 3395
	};

M
Mr.doob 已提交
3396
	this.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {
3397

M
Mr.doob 已提交
3398
		if ( renderTarget instanceof THREE.WebGLRenderTarget === false ) {
3399

3400
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
3401
			return;
3402

G
gero3 已提交
3403
		}
3404

M
Mr.doob 已提交
3405
		var framebuffer = properties.get( renderTarget ).__webglFramebuffer;
3406

M
Mr.doob 已提交
3407
		if ( framebuffer ) {
3408

G
gero3 已提交
3409
			var restore = false;
3410

M
Mr.doob 已提交
3411
			if ( framebuffer !== _currentFramebuffer ) {
3412

M
Mr.doob 已提交
3413
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
3414

G
gero3 已提交
3415
				restore = true;
3416

G
gero3 已提交
3417
			}
3418

M
Mr.doob 已提交
3419
			try {
3420

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

M
Mr.doob 已提交
3423 3424
				if ( texture.format !== THREE.RGBAFormat
					&& paramThreeToGL( texture.format ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
3425

M
Mr.doob 已提交
3426 3427
					console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );
					return;
3428

M
Mr.doob 已提交
3429
				}
3430

M
Mr.doob 已提交
3431 3432 3433 3434
				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' ) ) ) {
3435

M
Mr.doob 已提交
3436 3437
					console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );
					return;
3438

M
Mr.doob 已提交
3439
				}
3440

M
Mr.doob 已提交
3441
				if ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {
3442

M
Mr.doob 已提交
3443
					_gl.readPixels( x, y, width, height, paramThreeToGL( texture.format ), paramThreeToGL( texture.type ), buffer );
3444

M
Mr.doob 已提交
3445
				} else {
M
Mr.doob 已提交
3446

M
Mr.doob 已提交
3447 3448 3449
					console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );

				}
M
Mr.doob 已提交
3450

M
Mr.doob 已提交
3451
			} finally {
M
Mr.doob 已提交
3452

M
Mr.doob 已提交
3453 3454 3455
				if ( restore ) {

					_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );
M
Mr.doob 已提交
3456

M
Mr.doob 已提交
3457 3458 3459
				}

			}
M
Mr.doob 已提交
3460 3461 3462

		}

M
Mr.doob 已提交
3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473
	};

	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 已提交
3474
	}
M
Mr.doob 已提交
3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487

	// 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 已提交
3488
	}
M
Mr.doob 已提交
3489 3490 3491 3492 3493

	// Map three.js constants to WebGL constants

	function paramThreeToGL ( p ) {

3494 3495
		var extension;

M
Mr.doob 已提交
3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519
		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;

3520 3521 3522 3523 3524 3525 3526 3527
		extension = extensions.get( 'OES_texture_half_float' );

		if ( extension !== null ) {

			if ( p === THREE.HalfFloatType ) return extension.HALF_FLOAT_OES;

		}

M
Mr.doob 已提交
3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550
		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;

3551
		extension = extensions.get( 'WEBGL_compressed_texture_s3tc' );
M
Mr.doob 已提交
3552

3553 3554 3555 3556 3557 3558
		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 已提交
3559 3560 3561

		}

3562 3563 3564
		extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );

		if ( extension !== null ) {
P
Pierre Lepers 已提交
3565

3566 3567 3568 3569
			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 已提交
3570 3571 3572

		}

3573 3574 3575 3576 3577 3578 3579 3580
		extension = extensions.get( 'WEBGL_compressed_texture_etc1' );

		if ( extension !== null ) {

			if ( p === THREE.RGB_ETC1_Format ) return extension.COMPRESSED_RGB_ETC1_WEBGL;

		}

3581 3582 3583
		extension = extensions.get( 'EXT_blend_minmax' );

		if ( extension !== null ) {
3584

3585 3586
			if ( p === THREE.MinEquation ) return extension.MIN_EXT;
			if ( p === THREE.MaxEquation ) return extension.MAX_EXT;
3587 3588 3589

		}

M
Mr.doob 已提交
3590 3591
		return 0;

M
Mr.doob 已提交
3592
	}
M
Mr.doob 已提交
3593 3594

};