WebGLRenderer.js 83.4 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: [],
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

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

1161 1162
		setupLights( lights, camera );

M
Mr.doob 已提交
1163
		//
M
Mr.doob 已提交
1164

M
Mr.doob 已提交
1165
		shadowMap.render( scene, camera );
M
Mr.doob 已提交
1166 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 1628 1629 1630 1631 1632 1633 1634 1635
		if ( materialProperties.program === undefined ) {

			material.needsUpdate = true;

		}

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

			material.needsUpdate = true;

		}

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

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

		}

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

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

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

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

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

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1664

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

		}

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

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

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

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

			}


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

			}
M
Mr.doob 已提交
1692

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

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

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

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

				}

			}

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

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

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

1721 1722 1723 1724
				}

			}

B
Ben Houston 已提交
1725 1726 1727 1728

			if ( p_uniforms.toneMappingExposure !== undefined ) {

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

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

			if ( p_uniforms.toneMappingWhitePoint !== undefined ) {

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

			}
M
Mr.doob 已提交
1737

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

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

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

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

			}

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

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

			}

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

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

					var textureUnit = getTextureUnit();

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

				}

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

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

				}

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

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

				}

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

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

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

				}

			}

		}

		if ( refreshMaterial ) {

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

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

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

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

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

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

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

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

			}

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

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

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

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

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

				refreshUniformsLambert( m_uniforms, material );

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

				refreshUniformsPhong( m_uniforms, material );

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

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

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

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

		}

		loadUniformsMatrices( p_uniforms, object );

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

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

M
Mr.doob 已提交
1881 1882
		}

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

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

		}

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

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

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

		var dynamicUniforms = [];

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

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

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

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

			}

		}

		loadUniformsGeneric( dynamicUniforms );

	}

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

	function refreshUniformsCommon ( uniforms, material ) {

		uniforms.opacity.value = material.opacity;

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

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

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

		}

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

1933
		if ( material.aoMap ) {
1934

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

		}

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

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

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

			uvScaleMap = material.displacementMap;

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

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

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

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

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

			uvScaleMap = material.alphaMap;

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

			uvScaleMap = material.emissiveMap;

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

		if ( uvScaleMap !== undefined ) {

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

				uvScaleMap = uvScaleMap.texture;

			}

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

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

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

	function refreshUniformsLine ( uniforms, material ) {

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

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

	function refreshUniformsDash ( uniforms, material ) {

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

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

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

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

		uniforms.map.value = material.map;

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

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

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

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

2085 2086 2087 2088
		if ( material.lightMap ) {

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

2090
		}
2091

2092
		if ( material.emissiveMap ) {
2093

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

2096
		}
M
Mr.doob 已提交
2097

2098 2099 2100 2101
		if ( material.bumpMap ) {

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

2103
		}
M
Mr.doob 已提交
2104

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

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

		}
M
Mr.doob 已提交
2111

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

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

2118
		}
2119 2120 2121

	}

2122
	function refreshUniformsStandard ( uniforms, material ) {
W
WestLangley 已提交
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 2182

		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;

		}

	}

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

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

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

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

M
Mr.doob 已提交
2194
	}
2195

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

	function loadUniformsMatrices ( uniforms, object ) {

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

		if ( uniforms.normalMatrix ) {

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

		}

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

	function getTextureUnit() {

		var textureUnit = _usedTextureUnits;

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

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

		}

		_usedTextureUnits += 1;

		return textureUnit;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2252
			_gl.uniform1iv( location, value );
2253

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

2256
			_gl.uniform3iv( location, value );
2257

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

2260
			_gl.uniform1fv( location, value );
2261

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

2264
			_gl.uniform2fv( location, value );
2265

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

2268
			_gl.uniform3fv( location, value );
2269

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

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

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

2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286
			_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 已提交
2287

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2322
			var properties = uniform.properties;
2323

2324
			for ( var name in properties ) {
2325

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

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

			}
2333

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

			// TODO: Optimize this

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

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

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

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

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

2350 2351
				}

2352
			}
2353

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

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

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

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

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

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

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

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

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

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

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

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

2382
			}
M
Mr.doob 已提交
2383

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

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

2389
			}
2390

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

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

2395
			// array of THREE.Vector3
2396

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

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

2401
			}
M
Mr.doob 已提交
2402

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

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

2409
			}
M
Mr.doob 已提交
2410

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

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

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

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

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

2421
			}
R
Ryan Tsao 已提交
2422

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

2425 2426 2427 2428
				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 已提交
2429

2430
			}
R
Ryan Tsao 已提交
2431

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

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

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

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

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

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

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

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

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

2452
			}
M
Mr.doob 已提交
2453

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

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

2458
			}
2459

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

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

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

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

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

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

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

2475
			}
M
Mr.doob 已提交
2476

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

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

2481
			}
M
Mr.doob 已提交
2482

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

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

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

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

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

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

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

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

2501
				setCubeTexture( texture, textureUnit );
2502

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

2505
				setCubeTextureDynamic( texture.texture, textureUnit );
2506

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

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

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

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

2515
			}
M
Mr.doob 已提交
2516

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

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

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

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

2525
			}
M
Mr.doob 已提交
2526

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

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

2531
			}
M
Mr.doob 已提交
2532

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

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

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

2540
				if ( ! texture ) continue;
2541

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

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

2547
					setCubeTexture( texture, textureUnit );
2548

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

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

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

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

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

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

2561
				}
M
Mr.doob 已提交
2562

2563
			}
2564

2565
		} else {
2566

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

2569
		}
2570

2571
	}
2572

2573
	function loadUniformsGeneric( uniforms ) {
2574

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

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

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

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

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

		}

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

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

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

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

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

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

2609 2610
		_lights.shadowsPointLight = 0;

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

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

			} else if ( light instanceof THREE.DirectionalLight ) {

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

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

2635
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2636

2637
				if ( light.castShadow ) {
M
Mr.doob 已提交
2638

2639 2640 2641
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;
2642

2643
					_lights.shadows[ shadowsLength ++ ] = light;
2644

2645 2646
				}

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

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

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

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

M
Mr.doob 已提交
2658 2659 2660 2661 2662 2663 2664 2665
				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 );

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

2670
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2671

2672 2673
				if ( light.castShadow ) {

2674 2675 2676
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;
2677

2678
					_lights.shadows[ shadowsLength ++ ] = light;
2679

2680 2681
				}

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

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

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

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

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

2697
				uniforms.shadow = light.castShadow;
2698

M
Mr.doob 已提交
2699
				if ( light.castShadow ) {
2700

2701 2702 2703 2704 2705
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;

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

2707
				}
2708

2709
				_lights.pointShadowMap[ pointLength ] = light.shadow.map;
2710

2711 2712 2713
				if ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {

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

2715 2716
				}

2717 2718 2719 2720 2721
				// 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 已提交
2722
				_lights.point[ pointLength ++ ] = uniforms;
2723

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

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

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

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

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

			}

		}

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

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

2750 2751
		_lights.shadows.length = shadowsLength;

2752
		_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + hemiLength + ',' + shadowsLength;
2753

M
Mr.doob 已提交
2754
	}
M
Mr.doob 已提交
2755 2756 2757 2758 2759 2760 2761

	// GL state setting

	this.setFaceCulling = function ( cullFace, frontFaceDirection ) {

		if ( cullFace === THREE.CullFaceNone ) {

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

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

			}

2790
			state.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
2791 2792 2793 2794 2795 2796 2797

		}

	};

	// Textures

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

2800 2801
		var extension;

M
Mr.doob 已提交
2802
		if ( isPowerOfTwoImage ) {
M
Mr.doob 已提交
2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813

			_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 已提交
2814 2815 2816

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

M
Mr.doob 已提交
2817
				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 已提交
2818

2819
			}
M
Mr.doob 已提交
2820 2821 2822 2823

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

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

M
Mr.doob 已提交
2826
				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 已提交
2827

2828
			}
M
Mr.doob 已提交
2829

M
Mr.doob 已提交
2830 2831
		}

2832 2833
		extension = extensions.get( 'EXT_texture_filter_anisotropic' );

2834
		if ( extension ) {
M
Mr.doob 已提交
2835

2836 2837
			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 已提交
2838

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

2841
				_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _this.getMaxAnisotropy() ) );
2842
				properties.get( texture ).__currentAnisotropy = texture.anisotropy;
M
Mr.doob 已提交
2843 2844 2845 2846 2847

			}

		}

M
Mr.doob 已提交
2848
	}
M
Mr.doob 已提交
2849

2850
	function uploadTexture( textureProperties, texture, slot ) {
2851

2852
		if ( textureProperties.__webglInit === undefined ) {
2853

2854
			textureProperties.__webglInit = true;
2855 2856 2857

			texture.addEventListener( 'dispose', onTextureDispose );

2858
			textureProperties.__webglTexture = _gl.createTexture();
2859

2860
			_infoMemory.textures ++;
2861 2862

		}
M
Mr.doob 已提交
2863

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

H
Henri Astre 已提交
2867 2868 2869 2870
		_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 );

2871
		var image = clampToMaxSize( texture.image, capabilities.maxTextureSize );
2872

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

2875
			image = makePowerOfTwo( image );
M
Mr.doob 已提交
2876 2877 2878

		}

M
Mr.doob 已提交
2879
		var isPowerOfTwoImage = isPowerOfTwo( image ),
H
Henri Astre 已提交
2880 2881
		glFormat = paramThreeToGL( texture.format ),
		glType = paramThreeToGL( texture.type );
M
Mr.doob 已提交
2882

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

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

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

H
Henri Astre 已提交
2889 2890 2891
			// 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 已提交
2892

M
Mr.doob 已提交
2893
			if ( mipmaps.length > 0 && isPowerOfTwoImage ) {
H
Henri Astre 已提交
2894 2895

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

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

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

H
Henri Astre 已提交
2902
				texture.generateMipmaps = false;
M
Mr.doob 已提交
2903

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

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

H
Henri Astre 已提交
2908
			}
M
Mr.doob 已提交
2909

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

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

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

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

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

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

2922
					} else {
M
Mr.doob 已提交
2923

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

2926
					}
M
Mr.doob 已提交
2927

H
Henri Astre 已提交
2928
				} else {
M
Mr.doob 已提交
2929

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

M
Mr.doob 已提交
2932 2933
				}

H
Henri Astre 已提交
2934 2935
			}

G
gero3 已提交
2936 2937 2938
		} else {

			// regular Texture (image, video, canvas)
H
Henri Astre 已提交
2939 2940 2941 2942 2943

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

M
Mr.doob 已提交
2944
			if ( mipmaps.length > 0 && isPowerOfTwoImage ) {
M
Mr.doob 已提交
2945

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

					mipmap = mipmaps[ i ];
2949
					state.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );
M
Mr.doob 已提交
2950 2951 2952

				}

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

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

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

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

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

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

2965
		textureProperties.__version = texture.version;
M
Mr.doob 已提交
2966

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

2969
	}
M
Mr.doob 已提交
2970

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

2973 2974 2975
		var textureProperties = properties.get( texture );

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

2977
			var image = texture.image;
M
Mr.doob 已提交
2978

2979 2980
			if ( image === undefined ) {

2981
				console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );
2982 2983 2984 2985
				return;

			}

2986
			if ( image.complete === false ) {
M
Mr.doob 已提交
2987

2988
				console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );
2989 2990 2991 2992
				return;

			}

2993
			uploadTexture( textureProperties, texture, slot );
2994

2995
			return;
M
Mr.doob 已提交
2996 2997 2998

		}

B
Ben Adams 已提交
2999
		state.activeTexture( _gl.TEXTURE0 + slot );
3000
		state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
3001

M
Mr.doob 已提交
3002 3003 3004 3005
	};

	function clampToMaxSize ( image, maxSize ) {

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

3008 3009
			// Warning: Scaling through the canvas will only work with images that use
			// premultiplied alpha.
M
Mr.doob 已提交
3010

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

3013 3014 3015
			var canvas = document.createElement( 'canvas' );
			canvas.width = Math.floor( image.width * scale );
			canvas.height = Math.floor( image.height * scale );
M
Mr.doob 已提交
3016

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

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

3022 3023 3024
			return canvas;

		}
M
Mr.doob 已提交
3025

3026
		return image;
M
Mr.doob 已提交
3027 3028 3029

	}

M
Mr.doob 已提交
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 3062 3063 3064 3065
	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 已提交
3066 3067
	function setCubeTexture ( texture, slot ) {

3068
		var textureProperties = properties.get( texture );
3069

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

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

3074
				if ( ! textureProperties.__image__webglTextureCube ) {
M
Mr.doob 已提交
3075

3076 3077
					texture.addEventListener( 'dispose', onTextureDispose );

3078
					textureProperties.__image__webglTextureCube = _gl.createTexture();
M
Mr.doob 已提交
3079

3080
					_infoMemory.textures ++;
M
Mr.doob 已提交
3081 3082 3083

				}

B
Ben Adams 已提交
3084
				state.activeTexture( _gl.TEXTURE0 + slot );
3085
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
3086 3087 3088

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

M
Mr.doob 已提交
3089 3090
				var isCompressed = texture instanceof THREE.CompressedTexture;
				var isDataTexture = texture.image[ 0 ] instanceof THREE.DataTexture;
M
Mr.doob 已提交
3091 3092 3093 3094 3095

				var cubeImage = [];

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

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

G
gero3 已提交
3098
						cubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );
M
Mr.doob 已提交
3099 3100 3101

					} else {

3102
						cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];
M
Mr.doob 已提交
3103 3104 3105 3106 3107 3108

					}

				}

				var image = cubeImage[ 0 ],
M
Mr.doob 已提交
3109
				isPowerOfTwoImage = isPowerOfTwo( image ),
M
Mr.doob 已提交
3110 3111 3112
				glFormat = paramThreeToGL( texture.format ),
				glType = paramThreeToGL( texture.type );

M
Mr.doob 已提交
3113
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );
M
Mr.doob 已提交
3114 3115 3116

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

3117
					if ( ! isCompressed ) {
M
Mr.doob 已提交
3118

M
Mr.doob 已提交
3119
						if ( isDataTexture ) {
3120

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

M
Mr.doob 已提交
3123
						} else {
3124

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

M
Mr.doob 已提交
3127 3128
						}

3129
					} else {
3130

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

3133
						for ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {
M
Mr.doob 已提交
3134 3135

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

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

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

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

3143
								} else {
M
Mr.doob 已提交
3144

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

3147
								}
M
Mr.doob 已提交
3148

3149
							} else {
M
Mr.doob 已提交
3150

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

3153
							}
M
Mr.doob 已提交
3154

3155
						}
M
Mr.doob 已提交
3156

M
Mr.doob 已提交
3157
					}
M
Mr.doob 已提交
3158

M
Mr.doob 已提交
3159 3160
				}

M
Mr.doob 已提交
3161
				if ( texture.generateMipmaps && isPowerOfTwoImage ) {
M
Mr.doob 已提交
3162 3163 3164 3165 3166

					_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

				}

3167
				textureProperties.__version = texture.version;
M
Mr.doob 已提交
3168

B
Ben Adams 已提交
3169
				if ( texture.onUpdate ) texture.onUpdate( texture );
M
Mr.doob 已提交
3170 3171 3172

			} else {

B
Ben Adams 已提交
3173
				state.activeTexture( _gl.TEXTURE0 + slot );
3174
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
3175 3176 3177 3178 3179

			}

		}

M
Mr.doob 已提交
3180
	}
M
Mr.doob 已提交
3181 3182 3183

	function setCubeTextureDynamic ( texture, slot ) {

B
Ben Adams 已提交
3184
		state.activeTexture( _gl.TEXTURE0 + slot );
3185
		state.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );
M
Mr.doob 已提交
3186

M
Mr.doob 已提交
3187
	}
M
Mr.doob 已提交
3188 3189 3190

	// Render targets

3191 3192
	// Setup storage for target texture and bind it to correct framebuffer
	function setupFrameBufferTexture ( framebuffer, renderTarget, attachment, textureTarget ) {
M
Mr.doob 已提交
3193

3194 3195 3196
		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 已提交
3197
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
3198 3199
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
M
Mr.doob 已提交
3200

M
Mr.doob 已提交
3201
	}
M
Mr.doob 已提交
3202

3203 3204
	// Setup storage for internal depth/stencil buffers and bind to correct framebuffer
	function setupRenderBufferStorage ( renderbuffer, renderTarget ) {
M
Mr.doob 已提交
3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219

		_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 {

3220
			// FIXME: We don't support !depth !stencil
M
Mr.doob 已提交
3221 3222 3223 3224
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );

		}

3225
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
M
Mr.doob 已提交
3226

M
Mr.doob 已提交
3227
	}
M
Mr.doob 已提交
3228

3229
	// Setup GL resources for a non-texture depth buffer
M
Marius Kintel 已提交
3230
	function setupDepthRenderbuffer( renderTarget ) {
M
Mr.doob 已提交
3231

3232
		var renderTargetProperties = properties.get( renderTarget );
M
Mr.doob 已提交
3233 3234

		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
M
Mr.doob 已提交
3235

3236
		if ( isCube ) {
M
Mr.doob 已提交
3237

3238
			renderTargetProperties.__webglDepthbuffer = [];
M
Mr.doob 已提交
3239

3240
			for ( var i = 0; i < 6; i ++ ) {
M
Mr.doob 已提交
3241

M
Marius Kintel 已提交
3242
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );
3243 3244
				renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();
				setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );
M
Mr.doob 已提交
3245 3246

			}
B
Ben Adams 已提交
3247

M
Mr.doob 已提交
3248
		} else {
M
Mr.doob 已提交
3249

M
Marius Kintel 已提交
3250
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );
3251 3252
			renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
			setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );
M
Mr.doob 已提交
3253

3254
		}
M
Mr.doob 已提交
3255

M
Marius Kintel 已提交
3256
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
M
Mr.doob 已提交
3257

M
Mr.doob 已提交
3258
	}
M
Mr.doob 已提交
3259

3260
	// Set up GL resources for the render target
M
Marius Kintel 已提交
3261
	function setupRenderTarget( renderTarget ) {
M
Mr.doob 已提交
3262

3263 3264
		var renderTargetProperties = properties.get( renderTarget );
		var textureProperties = properties.get( renderTarget.texture );
M
Mr.doob 已提交
3265

3266
		renderTarget.addEventListener( 'dispose', onRenderTargetDispose );
M
Mr.doob 已提交
3267

3268
		textureProperties.__webglTexture = _gl.createTexture();
M
Mr.doob 已提交
3269

3270
		_infoMemory.textures ++;
M
Mr.doob 已提交
3271

3272 3273
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
		var isTargetPowerOfTwo = THREE.Math.isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height );
M
Mr.doob 已提交
3274

3275
		// Setup framebuffer
M
Mr.doob 已提交
3276

3277
		if ( isCube ) {
M
Mr.doob 已提交
3278

3279
			renderTargetProperties.__webglFramebuffer = [];
M
Mr.doob 已提交
3280

3281
			for ( var i = 0; i < 6; i ++ ) {
M
Mr.doob 已提交
3282

3283
				renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();
M
Mr.doob 已提交
3284

3285
			}
M
Mr.doob 已提交
3286

3287
		} else {
M
Mr.doob 已提交
3288

3289
			renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
M
Mr.doob 已提交
3290

3291
		}
M
Mr.doob 已提交
3292

3293
		// Setup color buffer
M
Mr.doob 已提交
3294

3295
		if ( isCube ) {
M
Mr.doob 已提交
3296

3297 3298
			state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
			setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );
M
Mr.doob 已提交
3299

3300
			for ( var i = 0; i < 6; i ++ ) {
M
Mr.doob 已提交
3301

3302
				setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
M
Mr.doob 已提交
3303 3304 3305

			}

3306 3307
			if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
			state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
M
Mr.doob 已提交
3308

3309
		} else {
M
Mr.doob 已提交
3310

3311 3312 3313
			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 已提交
3314

3315 3316
			if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
			state.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
3317

3318
		}
M
Mr.doob 已提交
3319

3320
		// Setup depth and stencil buffers
3321

3322
		if ( renderTarget.depthBuffer ) {
M
Mr.doob 已提交
3323

M
Marius Kintel 已提交
3324
			setupDepthRenderbuffer( renderTarget );
M
Mr.doob 已提交
3325

3326
		}
M
Mr.doob 已提交
3327

3328
	}
M
Mr.doob 已提交
3329

3330 3331 3332 3333 3334 3335
	this.getCurrentRenderTarget = function() {

		return _currentRenderTarget;

	}

3336
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
3337

3338 3339
		_currentRenderTarget = renderTarget;

3340
		if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {
M
Mr.doob 已提交
3341

M
Marius Kintel 已提交
3342
			setupRenderTarget( renderTarget );
M
Mr.doob 已提交
3343 3344 3345

		}

3346
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
3347
		var framebuffer;
M
Mr.doob 已提交
3348 3349 3350

		if ( renderTarget ) {

3351
			var renderTargetProperties = properties.get( renderTarget );
F
Fordy 已提交
3352

M
Mr.doob 已提交
3353 3354
			if ( isCube ) {

3355
				framebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
3356 3357 3358

			} else {

3359
				framebuffer = renderTargetProperties.__webglFramebuffer;
M
Mr.doob 已提交
3360 3361 3362

			}

3363 3364
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
3365

3366
			_currentViewport.copy( renderTarget.viewport );
M
Mr.doob 已提交
3367 3368 3369 3370 3371

		} else {

			framebuffer = null;

3372
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
3373
			_currentScissorTest = _scissorTest;
3374

3375
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
M
Mr.doob 已提交
3376 3377 3378

		}

M
Mr.doob 已提交
3379
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
3380 3381 3382 3383 3384 3385

			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
			_currentFramebuffer = framebuffer;

		}

3386 3387
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
3388

3389
		state.viewport( _currentViewport );
3390

M
Mr.doob 已提交
3391 3392 3393
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
3394
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
3395 3396 3397

		}

M
Mr.doob 已提交
3398 3399
	};

M
Mr.doob 已提交
3400
	this.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {
3401

M
Mr.doob 已提交
3402
		if ( renderTarget instanceof THREE.WebGLRenderTarget === false ) {
3403

3404
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
3405
			return;
3406

G
gero3 已提交
3407
		}
3408

M
Mr.doob 已提交
3409
		var framebuffer = properties.get( renderTarget ).__webglFramebuffer;
3410

M
Mr.doob 已提交
3411
		if ( framebuffer ) {
3412

G
gero3 已提交
3413
			var restore = false;
3414

M
Mr.doob 已提交
3415
			if ( framebuffer !== _currentFramebuffer ) {
3416

M
Mr.doob 已提交
3417
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
3418

G
gero3 已提交
3419
				restore = true;
3420

G
gero3 已提交
3421
			}
3422

M
Mr.doob 已提交
3423
			try {
3424

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

M
Mr.doob 已提交
3427 3428
				if ( texture.format !== THREE.RGBAFormat
					&& paramThreeToGL( texture.format ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
3429

M
Mr.doob 已提交
3430 3431
					console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );
					return;
3432

M
Mr.doob 已提交
3433
				}
3434

M
Mr.doob 已提交
3435 3436 3437 3438
				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' ) ) ) {
3439

M
Mr.doob 已提交
3440 3441
					console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );
					return;
3442

M
Mr.doob 已提交
3443
				}
3444

M
Mr.doob 已提交
3445
				if ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {
3446

M
Mr.doob 已提交
3447
					_gl.readPixels( x, y, width, height, paramThreeToGL( texture.format ), paramThreeToGL( texture.type ), buffer );
3448

M
Mr.doob 已提交
3449
				} else {
M
Mr.doob 已提交
3450

M
Mr.doob 已提交
3451 3452 3453
					console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );

				}
M
Mr.doob 已提交
3454

M
Mr.doob 已提交
3455
			} finally {
M
Mr.doob 已提交
3456

M
Mr.doob 已提交
3457 3458 3459
				if ( restore ) {

					_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );
M
Mr.doob 已提交
3460

M
Mr.doob 已提交
3461 3462 3463
				}

			}
M
Mr.doob 已提交
3464 3465 3466

		}

M
Mr.doob 已提交
3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477
	};

	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 已提交
3478
	}
M
Mr.doob 已提交
3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491

	// 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 已提交
3492
	}
M
Mr.doob 已提交
3493 3494 3495 3496 3497

	// Map three.js constants to WebGL constants

	function paramThreeToGL ( p ) {

3498 3499
		var extension;

M
Mr.doob 已提交
3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523
		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;

3524 3525 3526 3527 3528 3529 3530 3531
		extension = extensions.get( 'OES_texture_half_float' );

		if ( extension !== null ) {

			if ( p === THREE.HalfFloatType ) return extension.HALF_FLOAT_OES;

		}

M
Mr.doob 已提交
3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554
		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;

3555
		extension = extensions.get( 'WEBGL_compressed_texture_s3tc' );
M
Mr.doob 已提交
3556

3557 3558 3559 3560 3561 3562
		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 已提交
3563 3564 3565

		}

3566 3567 3568
		extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );

		if ( extension !== null ) {
P
Pierre Lepers 已提交
3569

3570 3571 3572 3573
			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 已提交
3574 3575 3576

		}

3577 3578 3579 3580 3581 3582 3583 3584
		extension = extensions.get( 'WEBGL_compressed_texture_etc1' );

		if ( extension !== null ) {

			if ( p === THREE.RGB_ETC1_Format ) return extension.COMPRESSED_RGB_ETC1_WEBGL;

		}

3585 3586 3587
		extension = extensions.get( 'EXT_blend_minmax' );

		if ( extension !== null ) {
3588

3589 3590
			if ( p === THREE.MinEquation ) return extension.MIN_EXT;
			if ( p === THREE.MaxEquation ) return extension.MAX_EXT;
3591 3592 3593

		}

M
Mr.doob 已提交
3594 3595
		return 0;

M
Mr.doob 已提交
3596
	}
M
Mr.doob 已提交
3597 3598

};