WebGLRenderer.js 84.0 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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
	this.gammaInput = false;
	this.gammaOutput = false;

	// morphs

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

	// flags

	this.autoScaleCubemaps = true;

	// internal properties

	var _this = this,

	// internal state cache

	_currentProgram = null,
74
	_currentRenderTarget = null,
M
Mr.doob 已提交
75
	_currentFramebuffer = null,
76
	_currentMaterialId = - 1,
77
	_currentGeometryProgram = '',
M
Mr.doob 已提交
78 79
	_currentCamera = null,

80 81 82 83 84
	_currentScissor = new THREE.Vector4(),
	_currentScissorTest = null,

	_currentViewport = new THREE.Vector4(),

85 86
	//

M
Mr.doob 已提交
87 88
	_usedTextureUnits = 0,

M
Mr.doob 已提交
89 90 91 92 93 94 95 96 97 98 99
	//

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

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

	_pixelRatio = 1,

	_scissor = new THREE.Vector4( 0, 0, _width, _height ),
100 101
	_scissorTest = false,

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

M
Mr.doob 已提交
104 105 106 107
	// frustum

	_frustum = new THREE.Frustum(),

M
Mr.doob 已提交
108
	// camera matrices cache
M
Mr.doob 已提交
109 110 111 112 113 114 115 116 117

	_projScreenMatrix = new THREE.Matrix4(),

	_vector3 = new THREE.Vector3(),

	// light arrays cache

	_lights = {

118 119
		hash: '',

M
Mr.doob 已提交
120
		ambient: [ 0, 0, 0 ],
M
Mr.doob 已提交
121
		directional: [],
122 123
		directionalShadowMap: [],
		directionalShadowMatrix: [],
M
Mr.doob 已提交
124
		spot: [],
125 126
		spotShadowMap: [],
		spotShadowMatrix: [],
M
Mr.doob 已提交
127
		point: [],
128 129
		pointShadowMap: [],
		pointShadowMatrix: [],
130 131
		hemi: [],

132
		shadows: [],
133
		shadowsPointLight: 0
M
Mr.doob 已提交
134

135 136
	},

M
Mr.doob 已提交
137 138
	// info

139
	_infoMemory = {
140 141

		geometries: 0,
T
tschw 已提交
142
		textures: 0
143 144 145

	},

146
	_infoRender = {
147 148 149 150 151 152

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

M
Mr.doob 已提交
153 154
	};

M
Mr.doob 已提交
155
	this.info = {
156

M
Mr.doob 已提交
157 158
		render: _infoRender,
		memory: _infoMemory,
159
		programs: null
M
Mr.doob 已提交
160 161

	};
162

163

M
Mr.doob 已提交
164 165 166 167
	// initialize

	var _gl;

M
Mr.doob 已提交
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
	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 已提交
183
			if ( _canvas.getContext( 'webgl' ) !== null ) {
184 185 186 187 188 189 190 191

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

			} else {

				throw 'Error creating WebGL context.';

			}
M
Mr.doob 已提交
192 193 194

		}

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

M
Mr.doob 已提交
197 198
	} catch ( error ) {

199
		console.error( 'THREE.WebGLRenderer: ' + error );
M
Mr.doob 已提交
200 201 202

	}

203 204
	var extensions = new THREE.WebGLExtensions( _gl );

205 206
	extensions.get( 'OES_texture_float' );
	extensions.get( 'OES_texture_float_linear' );
207 208
	extensions.get( 'OES_texture_half_float' );
	extensions.get( 'OES_texture_half_float_linear' );
209
	extensions.get( 'OES_standard_derivatives' );
B
Ben Adams 已提交
210
	extensions.get( 'ANGLE_instanced_arrays' );
211

212 213
	if ( extensions.get( 'OES_element_index_uint' ) ) {

214
		THREE.BufferGeometry.MaxIndex = 4294967296;
215 216 217

	}

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

220 221 222
	var state = new THREE.WebGLState( _gl, extensions, paramThreeToGL );
	var properties = new THREE.WebGLProperties();
	var objects = new THREE.WebGLObjects( _gl, properties, this.info );
G
gero3 已提交
223
	var programCache = new THREE.WebGLPrograms( this, capabilities );
M
Mr.doob 已提交
224
	var lightCache = new THREE.WebGLLights();
225

226 227
	this.info.programs = programCache.programs;

228 229
	var bufferRenderer = new THREE.WebGLBufferRenderer( _gl, extensions, _infoRender );
	var indexedBufferRenderer = new THREE.WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
230

M
Mr.doob 已提交
231 232
	//

233 234
	function getTargetPixelRatio() {

235
		return _currentRenderTarget === null ? _pixelRatio : 1;
236 237 238

	}

239
	function glClearColor( r, g, b, a ) {
240 241 242

		if ( _premultipliedAlpha === true ) {

243
			r *= a; g *= a; b *= a;
244 245 246

		}

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

249
	}
250

251
	function setDefaultGLState() {
M
Mr.doob 已提交
252

M
Mr.doob 已提交
253
		state.init();
M
Mr.doob 已提交
254

255 256
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
M
Mr.doob 已提交
257

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

260
	}
261

262
	function resetGLState() {
263 264 265 266

		_currentProgram = null;
		_currentCamera = null;

267
		_currentGeometryProgram = '';
268 269
		_currentMaterialId = - 1;

M
Mr.doob 已提交
270 271
		state.reset();

272
	}
M
Mr.doob 已提交
273 274 275 276

	setDefaultGLState();

	this.context = _gl;
M
Mr.doob 已提交
277
	this.capabilities = capabilities;
278
	this.extensions = extensions;
279
	this.properties = properties;
M
Mr.doob 已提交
280
	this.state = state;
M
Mr.doob 已提交
281

M
Mr.doob 已提交
282 283
	// shadow map

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

286
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
287

M
Mr.doob 已提交
288

M
Mr.doob 已提交
289 290 291 292 293
	// Plugins

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

M
Mr.doob 已提交
294 295 296 297 298 299 300 301
	// API

	this.getContext = function () {

		return _gl;

	};

302 303 304 305 306 307
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

308 309 310 311 312 313
	this.forceContextLoss = function () {

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

	};

314
	this.getMaxAnisotropy = ( function () {
M
Mr.doob 已提交
315

316
		var value;
M
Mr.doob 已提交
317

318
		return function getMaxAnisotropy() {
319

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

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

M
Mr.doob 已提交
324
			if ( extension !== null ) {
325

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

M
Mr.doob 已提交
328 329 330 331 332
			} else {

				value = 0;

			}
333 334 335

			return value;

M
Mr.doob 已提交
336
		};
337 338

	} )();
M
Mr.doob 已提交
339 340 341

	this.getPrecision = function () {

G
gero3 已提交
342
		return capabilities.precision;
M
Mr.doob 已提交
343 344 345

	};

346 347
	this.getPixelRatio = function () {

348
		return _pixelRatio;
349 350 351 352 353

	};

	this.setPixelRatio = function ( value ) {

354 355 356 357 358
		if ( value === undefined ) return;

		_pixelRatio = value;

		this.setSize( _viewport.z, _viewport.w, false );
359 360 361

	};

362 363 364
	this.getSize = function () {

		return {
365 366
			width: _width,
			height: _height
367 368 369 370
		};

	};

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

373 374 375
		_width = width;
		_height = height;

376 377
		_canvas.width = width * _pixelRatio;
		_canvas.height = height * _pixelRatio;
378

379
		if ( updateStyle !== false ) {
380

G
gero3 已提交
381 382
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
383

G
gero3 已提交
384
		}
M
Mr.doob 已提交
385

386
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
387 388 389 390 391

	};

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

392
		state.viewport( _viewport.set( x, y, width, height ) );
M
Mr.doob 已提交
393 394 395

	};

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

398
		state.scissor( _scissor.set( x, y, width, height ) );
M
Mr.doob 已提交
399 400 401

	};

402 403
	this.setScissorTest = function ( boolean ) {

404
		state.setScissorTest( _scissorTest = boolean );
M
Mr.doob 已提交
405 406 407 408 409

	};

	// Clearing

M
Mr.doob 已提交
410
	this.getClearColor = function () {
M
Mr.doob 已提交
411

M
Mr.doob 已提交
412
		return _clearColor;
M
Mr.doob 已提交
413 414 415

	};

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

M
Mr.doob 已提交
418
		_clearColor.set( color );
419

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

422
		glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
M
Mr.doob 已提交
423 424 425

	};

M
Mr.doob 已提交
426
	this.getClearAlpha = function () {
M
Mr.doob 已提交
427

M
Mr.doob 已提交
428
		return _clearAlpha;
M
Mr.doob 已提交
429 430 431

	};

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

M
Mr.doob 已提交
434
		_clearAlpha = alpha;
M
Mr.doob 已提交
435

436
		glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
M
Mr.doob 已提交
437 438 439 440 441 442 443 444 445 446 447 448

	};

	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 );
449 450 451 452 453

	};

	this.clearColor = function () {

M
Mr.doob 已提交
454
		this.clear( true, false, false );
455 456 457 458 459

	};

	this.clearDepth = function () {

M
Mr.doob 已提交
460
		this.clear( false, true, false );
461 462 463 464 465

	};

	this.clearStencil = function () {

M
Mr.doob 已提交
466
		this.clear( false, false, true );
M
Mr.doob 已提交
467 468 469 470 471 472 473 474 475 476

	};

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

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

	};

M
Mr.doob 已提交
477 478
	// Reset

479
	this.resetGLState = resetGLState;
M
Mr.doob 已提交
480

D
dubejf 已提交
481 482 483 484 485 486
	this.dispose = function() {

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

	};

M
Mr.doob 已提交
487
	// Events
M
Mr.doob 已提交
488

D
dubejf 已提交
489 490 491 492 493 494 495 496 497
	function onContextLost( event ) {

		event.preventDefault();

		resetGLState();
		setDefaultGLState();

		properties.clear();

M
Mr.doob 已提交
498
	}
D
dubejf 已提交
499

500
	function onTextureDispose( event ) {
M
Mr.doob 已提交
501 502 503 504 505 506 507

		var texture = event.target;

		texture.removeEventListener( 'dispose', onTextureDispose );

		deallocateTexture( texture );

508
		_infoMemory.textures --;
M
Mr.doob 已提交
509 510


511
	}
M
Mr.doob 已提交
512

513
	function onRenderTargetDispose( event ) {
M
Mr.doob 已提交
514 515 516 517 518 519 520

		var renderTarget = event.target;

		renderTarget.removeEventListener( 'dispose', onRenderTargetDispose );

		deallocateRenderTarget( renderTarget );

521
		_infoMemory.textures --;
M
Mr.doob 已提交
522

523
	}
M
Mr.doob 已提交
524

525
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
526 527 528 529 530 531 532

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

533
	}
M
Mr.doob 已提交
534 535 536

	// Buffer deallocation

537
	function deallocateTexture( texture ) {
M
Mr.doob 已提交
538

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

541
		if ( texture.image && textureProperties.__image__webglTextureCube ) {
M
Mr.doob 已提交
542 543 544

			// cube texture

545
			_gl.deleteTexture( textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
546

547 548 549 550
		} else {

			// 2D texture

551
			if ( textureProperties.__webglInit === undefined ) return;
552

553
			_gl.deleteTexture( textureProperties.__webglTexture );
554

M
Mr.doob 已提交
555 556
		}

557
		// remove all webgl properties
558
		properties.delete( texture );
559

560
	}
M
Mr.doob 已提交
561

562
	function deallocateRenderTarget( renderTarget ) {
M
Mr.doob 已提交
563

564
		var renderTargetProperties = properties.get( renderTarget );
M
Mr.doob 已提交
565
		var textureProperties = properties.get( renderTarget.texture );
M
Mr.doob 已提交
566

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

M
Mr.doob 已提交
569
		_gl.deleteTexture( textureProperties.__webglTexture );
M
Mr.doob 已提交
570

M
Mr.doob 已提交
571 572 573 574
		if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {

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

575
				_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );
576
				_gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );
M
Mr.doob 已提交
577 578 579 580 581

			}

		} else {

582
			_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );
583
			_gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );
M
Mr.doob 已提交
584 585 586

		}

M
Mr.doob 已提交
587
		properties.delete( renderTarget.texture );
D
Daosheng Mu 已提交
588
		properties.delete( renderTarget );
M
Mr.doob 已提交
589

590
	}
M
Mr.doob 已提交
591

592
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
593

594 595 596 597
		releaseMaterialProgramReference( material );

		properties.delete( material );

598
	}
599 600


601
	function releaseMaterialProgramReference( material ) {
602

603
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
604 605 606

		material.program = undefined;

607
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
608

609
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
610

M
Mr.doob 已提交
611 612
		}

613
	}
M
Mr.doob 已提交
614 615 616 617 618

	// Buffer rendering

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

619
		state.initAttributes();
620

621
		var buffers = properties.get( object );
622

623 624 625 626
		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 已提交
627

628
		var attributes = program.getAttributes();
629

M
Mr.doob 已提交
630 631
		if ( object.hasPositions ) {

632
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
M
Mr.doob 已提交
633
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
634

635 636
			state.enableAttribute( attributes.position );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
637 638 639 640 641

		}

		if ( object.hasNormals ) {

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

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

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

648
					var array = object.normalArray;
M
Mr.doob 已提交
649

650 651 652
					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 已提交
653

654 655 656
					array[ i + 0 ] = nx;
					array[ i + 1 ] = ny;
					array[ i + 2 ] = nz;
M
Mr.doob 已提交
657

658 659 660
					array[ i + 3 ] = nx;
					array[ i + 4 ] = ny;
					array[ i + 5 ] = nz;
M
Mr.doob 已提交
661

662 663 664
					array[ i + 6 ] = nx;
					array[ i + 7 ] = ny;
					array[ i + 8 ] = nz;
M
Mr.doob 已提交
665 666 667 668 669 670

				}

			}

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

672
			state.enableAttribute( attributes.normal );
673

674
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
675 676 677 678 679

		}

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

680
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
M
Mr.doob 已提交
681
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
682

683
			state.enableAttribute( attributes.uv );
684

685
			_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
686 687 688 689 690

		}

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

691
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
M
Mr.doob 已提交
692
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
693

694
			state.enableAttribute( attributes.color );
695

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

		}

700
		state.disableUnusedAttributes();
701

M
Mr.doob 已提交
702 703 704 705 706 707
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

708
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
709

M
Mr.doob 已提交
710 711
		setMaterial( material );

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

M
Mr.doob 已提交
714 715
		var updateBuffers = false;
		var geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;
M
Mr.doob 已提交
716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738

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

			}

739
			activeInfluences.sort( absNumericalSort );
M
Mr.doob 已提交
740 741 742 743 744 745 746

			if ( activeInfluences.length > 8 ) {

				activeInfluences.length = 8;

			}

747 748
			var morphAttributes = geometry.morphAttributes;

M
Mr.doob 已提交
749 750 751 752 753 754 755
			for ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {

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

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

756
					var index = influence[ 1 ];
M
Mr.doob 已提交
757

758 759
					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 已提交
760 761 762

				} else {

763 764
					if ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );
					if ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );
M
Mr.doob 已提交
765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781

				}

			}

			var uniforms = program.getUniforms();

			if ( uniforms.morphTargetInfluences !== null ) {

				_gl.uniform1fv( uniforms.morphTargetInfluences, morphInfluences );

			}

			updateBuffers = true;

		}

M
Mr.doob 已提交
782 783
		//

784
		var index = geometry.index;
785 786
		var position = geometry.attributes.position;

787 788
		if ( material.wireframe === true ) {

789
			index = objects.getWireframeAttribute( geometry );
790 791 792

		}

793 794
		var renderer;

795
		if ( index !== null ) {
796

797 798
			renderer = indexedBufferRenderer;
			renderer.setIndex( index );
799

800
		} else {
801

802
			renderer = bufferRenderer;
803

804
		}
M
Mr.doob 已提交
805

806
		if ( updateBuffers ) {
M
Mr.doob 已提交
807

808
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
809

810
			if ( index !== null ) {
811

812
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );
813 814 815

			}

816
		}
817

M
Mr.doob 已提交
818
		//
819

M
Mr.doob 已提交
820 821
		var dataStart = 0;
		var dataCount = Infinity;
822

M
Mr.doob 已提交
823
		if ( index !== null ) {
824

M
Mr.doob 已提交
825
			dataCount = index.count;
826

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

M
Mr.doob 已提交
829
			dataCount = position.count;
830

M
Mr.doob 已提交
831
		}
832

M
Mr.doob 已提交
833 834
		var rangeStart = geometry.drawRange.start;
		var rangeCount = geometry.drawRange.count;
835

M
Mr.doob 已提交
836 837
		var groupStart = group !== null ? group.start : 0;
		var groupCount = group !== null ? group.count : Infinity;
838

M
Mr.doob 已提交
839 840 841 842 843 844
		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 );

		//
845

846
		if ( object instanceof THREE.Mesh ) {
847

848
			if ( material.wireframe === true ) {
849

850
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
851
				renderer.setMode( _gl.LINES );
852

853
			} else {
M
Mr.doob 已提交
854 855

				switch ( object.drawMode ) {
856

B
Ben Adams 已提交
857 858 859 860 861 862 863 864 865 866 867 868 869
					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;

				}
870

871
			}
872

873

874
		} else if ( object instanceof THREE.Line ) {
875

876
			var lineWidth = material.linewidth;
877

878
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
879

880
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
881

882
			if ( object instanceof THREE.LineSegments ) {
883

884
				renderer.setMode( _gl.LINES );
885

886
			} else {
887

888
				renderer.setMode( _gl.LINE_STRIP );
889 890

			}
M
Mr.doob 已提交
891

892
		} else if ( object instanceof THREE.Points ) {
893 894

			renderer.setMode( _gl.POINTS );
895 896

		}
897

898 899 900 901 902 903
		if ( geometry instanceof THREE.InstancedBufferGeometry && geometry.maxInstancedCount > 0 ) {

			renderer.renderInstances( geometry, drawStart, drawCount );

		} else {

M
Mr.doob 已提交
904
			renderer.render( drawStart, drawCount );
905

M
Mr.doob 已提交
906 907 908 909
		}

	};

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

M
Mr.doob 已提交
912
		var extension;
B
Ben Adams 已提交
913

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

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

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

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

M
Mr.doob 已提交
923 924 925
			}

		}
B
Ben Adams 已提交
926

927 928
		if ( startIndex === undefined ) startIndex = 0;

929 930
		state.initAttributes();

931
		var geometryAttributes = geometry.attributes;
932

933
		var programAttributes = program.getAttributes();
934

935
		var materialDefaultAttributeValues = material.defaultAttributeValues;
936

937
		for ( var name in programAttributes ) {
938

939
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
940

M
Mr.doob 已提交
941
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
942

943
				var geometryAttribute = geometryAttributes[ name ];
944

M
Mr.doob 已提交
945
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
946

947
					var size = geometryAttribute.itemSize;
G
gero3 已提交
948
					var buffer = objects.getAttributeBuffer( geometryAttribute );
949

B
Ben Adams 已提交
950
					if ( geometryAttribute instanceof THREE.InterleavedBufferAttribute ) {
951

M
Mr.doob 已提交
952 953 954 955 956
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

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

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

M
Mr.doob 已提交
960
							if ( geometry.maxInstancedCount === undefined ) {
961

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

M
Mr.doob 已提交
964
							}
B
Ben Adams 已提交
965

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

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

M
Mr.doob 已提交
970
						}
B
Ben Adams 已提交
971

M
Mr.doob 已提交
972 973
						_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 已提交
974

M
Mr.doob 已提交
975
					} else {
B
Ben Adams 已提交
976

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

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

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

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

M
Mr.doob 已提交
985
							}
B
Ben Adams 已提交
986

M
Mr.doob 已提交
987 988 989 990
						} else {

							state.enableAttribute( programAttribute );

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

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

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

998 999
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
1000
					var value = materialDefaultAttributeValues[ name ];
1001

1002
					if ( value !== undefined ) {
M
Mr.doob 已提交
1003

1004
						switch ( value.length ) {
M
Mr.doob 已提交
1005

1006 1007 1008
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
1009

1010 1011 1012
							case 3:
								_gl.vertexAttrib3fv( programAttribute, value );
								break;
M
Mr.doob 已提交
1013

1014 1015 1016
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
1017

1018 1019
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
1020 1021

						}
M
Mr.doob 已提交
1022 1023 1024 1025 1026 1027 1028 1029

					}

				}

			}

		}
1030

1031
		state.disableUnusedAttributes();
1032

M
Mr.doob 已提交
1033 1034
	}

M
Mr.doob 已提交
1035 1036
	// Sorting

1037
	function absNumericalSort( a, b ) {
1038

1039
		return Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );
1040 1041 1042

	}

M
Mr.doob 已提交
1043 1044
	function painterSortStable ( a, b ) {

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

U
unconed 已提交
1047
			return a.object.renderOrder - b.object.renderOrder;
1048

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

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

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

M
Mr.doob 已提交
1055
			return a.z - b.z;
M
Mr.doob 已提交
1056 1057 1058

		} else {

1059
			return a.id - b.id;
M
Mr.doob 已提交
1060 1061 1062

		}

1063
	}
M
Mr.doob 已提交
1064

1065 1066
	function reversePainterSortStable ( a, b ) {

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

U
unconed 已提交
1069
			return a.object.renderOrder - b.object.renderOrder;
1070 1071

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

M
Mr.doob 已提交
1073
			return b.z - a.z;
1074 1075 1076 1077 1078 1079 1080

		} else {

			return a.id - b.id;

		}

1081
	}
1082

M
Mr.doob 已提交
1083 1084 1085 1086 1087 1088
	// Rendering

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

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

1089
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1090 1091 1092 1093
			return;

		}

M
Mr.doob 已提交
1094
		var fog = scene.fog;
M
Mr.doob 已提交
1095 1096 1097

		// reset caching for this frame

1098
		_currentGeometryProgram = '';
1099
		_currentMaterialId = - 1;
1100
		_currentCamera = null;
M
Mr.doob 已提交
1101 1102 1103

		// update scene graph

1104
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1105 1106 1107

		// update camera matrices and frustum

1108
		if ( camera.parent === null ) camera.updateMatrixWorld();
M
Mr.doob 已提交
1109 1110 1111 1112 1113 1114

		camera.matrixWorldInverse.getInverse( camera.matrixWorld );

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

M
Mr.doob 已提交
1115
		lights.length = 0;
1116

M
Mr.doob 已提交
1117 1118
		opaqueObjectsLastIndex = - 1;
		transparentObjectsLastIndex = - 1;
1119

M
Mr.doob 已提交
1120 1121 1122
		sprites.length = 0;
		lensFlares.length = 0;

1123
		projectObject( scene, camera );
M
Mr.doob 已提交
1124

1125 1126 1127
		opaqueObjects.length = opaqueObjectsLastIndex + 1;
		transparentObjects.length = transparentObjectsLastIndex + 1;

M
Mr.doob 已提交
1128
		if ( _this.sortObjects === true ) {
1129 1130 1131

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

1133 1134
		}

1135 1136
		setupLights( lights, camera );

M
Mr.doob 已提交
1137
		//
M
Mr.doob 已提交
1138

M
Mr.doob 已提交
1139
		shadowMap.render( scene, camera );
M
Mr.doob 已提交
1140 1141 1142

		//

1143 1144 1145 1146
		_infoRender.calls = 0;
		_infoRender.vertices = 0;
		_infoRender.faces = 0;
		_infoRender.points = 0;
M
Mr.doob 已提交
1147

1148 1149 1150 1151 1152 1153
		if ( renderTarget === undefined ) {

			renderTarget = null;

		}

M
Mr.doob 已提交
1154 1155 1156 1157 1158 1159 1160 1161
		this.setRenderTarget( renderTarget );

		if ( this.autoClear || forceClear ) {

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

		}

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

		if ( scene.overrideMaterial ) {

1166
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1167

1168 1169
			renderObjects( opaqueObjects, camera, fog, overrideMaterial );
			renderObjects( transparentObjects, camera, fog, overrideMaterial );
1170

M
Mr.doob 已提交
1171 1172 1173 1174
		} else {

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

M
Mr.doob 已提交
1175
			state.setBlending( THREE.NoBlending );
1176
			renderObjects( opaqueObjects, camera, fog );
M
Mr.doob 已提交
1177 1178 1179

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

1180
			renderObjects( transparentObjects, camera, fog );
M
Mr.doob 已提交
1181 1182 1183 1184 1185

		}

		// custom render plugins (post pass)

M
Mr.doob 已提交
1186
		spritePlugin.render( scene, camera );
1187
		lensFlarePlugin.render( scene, camera, _currentViewport );
M
Mr.doob 已提交
1188 1189 1190

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

M
Mr.doob 已提交
1191 1192 1193
		if ( renderTarget ) {

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

M
Mr.doob 已提交
1195 1196 1197 1198 1199
			if ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&
					texture.minFilter !== THREE.NearestFilter &&
					texture.minFilter !== THREE.LinearFilter ) {

				updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1200 1201

			}
M
Mr.doob 已提交
1202 1203 1204

		}

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

M
Mr.doob 已提交
1207 1208
		state.setDepthTest( true );
		state.setDepthWrite( true );
1209
		state.setColorWrite( true );
M
Mr.doob 已提交
1210 1211 1212 1213

		// _gl.finish();

	};
M
Mr.doob 已提交
1214

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

1217
		var array, index;
M
Mr.doob 已提交
1218

1219
		// allocate the next position in the appropriate array
M
Mr.doob 已提交
1220 1221 1222

		if ( material.transparent ) {

1223 1224
			array = transparentObjects;
			index = ++ transparentObjectsLastIndex;
M
Mr.doob 已提交
1225 1226 1227

		} else {

1228 1229 1230 1231 1232
			array = opaqueObjects;
			index = ++ opaqueObjectsLastIndex;

		}

1233 1234
		// recycle existing render item or grow the array

1235 1236 1237 1238 1239 1240 1241 1242 1243 1244
		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 已提交
1245 1246 1247

		} else {

1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258
			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 已提交
1259 1260 1261 1262 1263

		}

	}

1264
	function projectObject( object, camera ) {
M
Mr.doob 已提交
1265

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

1268
		if ( object.layers.test( camera.layers ) ) {
M
Mr.doob 已提交
1269

1270
			if ( object instanceof THREE.Light ) {
M
Mr.doob 已提交
1271

1272
				lights.push( object );
M
Mr.doob 已提交
1273

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

1276 1277 1278 1279 1280
				if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) {

					sprites.push( object );

				}
M
Mr.doob 已提交
1281

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

1284
				lensFlares.push( object );
M
Mr.doob 已提交
1285

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

1288
				if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1289

1290 1291
					_vector3.setFromMatrixPosition( object.matrixWorld );
					_vector3.applyProjection( _projScreenMatrix );
M
Mr.doob 已提交
1292

1293
				}
1294

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

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

1299
				if ( object instanceof THREE.SkinnedMesh ) {
M
Mr.doob 已提交
1300

1301
					object.skeleton.update();
1302

1303
				}
1304

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

1307
					var material = object.material;
1308

1309
					if ( material.visible === true ) {
M
Mr.doob 已提交
1310

1311
						if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1312

1313 1314 1315 1316
							_vector3.setFromMatrixPosition( object.matrixWorld );
							_vector3.applyProjection( _projScreenMatrix );

						}
M
Mr.doob 已提交
1317

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

S
SUNAG 已提交
1320
						if ( material instanceof THREE.MultiMaterial ) {
1321

1322 1323
							var groups = geometry.groups;
							var materials = material.materials;
1324

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

1327 1328
								var group = groups[ i ];
								var groupMaterial = materials[ group.materialIndex ];
1329

1330
								if ( groupMaterial.visible === true ) {
1331

1332 1333 1334
									pushRenderItem( object, geometry, groupMaterial, _vector3.z, group );

								}
M
Mr.doob 已提交
1335

M
Mr.doob 已提交
1336
							}
M
Mr.doob 已提交
1337

1338
						} else {
M
Mr.doob 已提交
1339

1340
							pushRenderItem( object, geometry, material, _vector3.z, null );
1341

1342
						}
O
OpenShift guest 已提交
1343

1344
					}
M
Mr.doob 已提交
1345

1346
				}
M
Mr.doob 已提交
1347

1348
			}
M
Mr.doob 已提交
1349

M
Mr.doob 已提交
1350
		}
M
Mr.doob 已提交
1351

M
Mr.doob 已提交
1352
		var children = object.children;
M
Mr.doob 已提交
1353

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

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

1358
		}
1359

1360
	}
M
Mr.doob 已提交
1361

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

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

1366
			var renderItem = renderList[ i ];
M
Mr.doob 已提交
1367

1368
			var object = renderItem.object;
M
Mr.doob 已提交
1369 1370 1371
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
M
Mr.doob 已提交
1372

1373 1374
			object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
			object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
M
Mr.doob 已提交
1375

M
Mr.doob 已提交
1376
			if ( object instanceof THREE.ImmediateRenderObject ) {
M
Mr.doob 已提交
1377

M
Mr.doob 已提交
1378
				setMaterial( material );
M
Mr.doob 已提交
1379

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

M
Mr.doob 已提交
1382
				_currentGeometryProgram = '';
M
Mr.doob 已提交
1383

M
Mr.doob 已提交
1384
				object.render( function ( object ) {
M
Mr.doob 已提交
1385

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

M
Mr.doob 已提交
1388
				} );
1389

M
Mr.doob 已提交
1390
			} else {
M
Mr.doob 已提交
1391

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

M
Mr.doob 已提交
1394
			}
M
Mr.doob 已提交
1395

1396
		}
M
Mr.doob 已提交
1397

1398
	}
G
gero3 已提交
1399

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

1402
		var materialProperties = properties.get( material );
G
gero3 已提交
1403

1404
		var parameters = programCache.getParameters( material, _lights, fog, object );
G
gero3 已提交
1405
		var code = programCache.getProgramCode( material, parameters );
G
gero3 已提交
1406

1407
		var program = materialProperties.program;
T
tschw 已提交
1408
		var programChange = true;
1409

1410
		if ( program === undefined ) {
B
Ben Adams 已提交
1411

M
Mr.doob 已提交
1412 1413
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1414

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

M
Mr.doob 已提交
1417
			// changed glsl or parameters
1418
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1419

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

T
tschw 已提交
1422
			// same glsl and uniform list
T
tschw 已提交
1423 1424
			return;

T
tschw 已提交
1425
		} else {
B
Ben Adams 已提交
1426

T
tschw 已提交
1427 1428
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1429 1430 1431

		}

1432
		if ( programChange ) {
B
Ben Adams 已提交
1433

1434
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1435

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

1438 1439 1440 1441 1442 1443
				materialProperties.__webglShader = {
					name: material.type,
					uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
					vertexShader: shader.vertexShader,
					fragmentShader: shader.fragmentShader
				};
B
Ben Adams 已提交
1444

1445
			} else {
B
Ben Adams 已提交
1446

1447 1448 1449 1450 1451 1452
				materialProperties.__webglShader = {
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
					fragmentShader: material.fragmentShader
				};
G
gero3 已提交
1453

1454
			}
G
gero3 已提交
1455

1456
			material.__webglShader = materialProperties.__webglShader;
G
gero3 已提交
1457

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

1460 1461
			materialProperties.program = program;
			material.program = program;
1462 1463 1464

		}

1465
		var attributes = program.getAttributes();
M
Mr.doob 已提交
1466 1467 1468 1469 1470

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

M
Mr.doob 已提交
1473
				if ( attributes[ 'morphTarget' + i ] >= 0 ) {
M
Mr.doob 已提交
1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

M
Mr.doob 已提交
1489
				if ( attributes[ 'morphNormal' + i ] >= 0 ) {
M
Mr.doob 已提交
1490 1491 1492 1493 1494 1495 1496 1497 1498

					material.numSupportedMorphNormals ++;

				}

			}

		}

1499
		materialProperties.uniformsList = [];
M
Mr.doob 已提交
1500

1501 1502
		var uniforms = materialProperties.__webglShader.uniforms,
			uniformLocations = materialProperties.program.getUniforms();
M
Mr.doob 已提交
1503

1504
		for ( var u in uniforms ) {
M
Mr.doob 已提交
1505

1506
			var location = uniformLocations[ u ];
1507 1508

			if ( location ) {
G
gero3 已提交
1509

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

1512
			}
M
Mr.doob 已提交
1513 1514 1515

		}

1516 1517
		if ( material instanceof THREE.MeshPhongMaterial ||
				material instanceof THREE.MeshLambertMaterial ||
1518
				material instanceof THREE.MeshStandardMaterial ||
1519 1520
				material.lights ) {

1521 1522
			// store the light setup it was created for

1523 1524
			materialProperties.lightsHash = _lights.hash;

1525 1526 1527 1528 1529
			// 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 已提交
1530
			uniforms.pointLights.value = _lights.point;
1531 1532
			uniforms.hemisphereLights.value = _lights.hemi;

1533 1534 1535 1536 1537 1538
			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;
1539

1540 1541
		}

A
arose 已提交
1542 1543 1544 1545 1546 1547 1548 1549
		// detect dynamic uniforms

		materialProperties.hasDynamicUniforms = false;

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

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

1550
			if ( uniform.dynamic === true ) {
A
arose 已提交
1551 1552 1553 1554 1555 1556 1557 1558

				materialProperties.hasDynamicUniforms = true;
				break;

			}

		}

M
Mr.doob 已提交
1559
	}
M
Mr.doob 已提交
1560

1561 1562
	function setMaterial( material ) {

M
Mr.doob 已提交
1563 1564
		setMaterialFaces( material );

1565 1566
		if ( material.transparent === true ) {

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

1569 1570 1571 1572
		} else {

			state.setBlending( THREE.NoBlending );

1573 1574
		}

B
Ben Adams 已提交
1575
		state.setDepthFunc( material.depthFunc );
M
Mr.doob 已提交
1576 1577
		state.setDepthTest( material.depthTest );
		state.setDepthWrite( material.depthWrite );
1578
		state.setColorWrite( material.colorWrite );
M
Mr.doob 已提交
1579
		state.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
1580 1581 1582

	}

M
Mr.doob 已提交
1583 1584
	function setMaterialFaces( material ) {

1585
		material.side !== THREE.DoubleSide ? state.enable( _gl.CULL_FACE ) : state.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
1586 1587 1588 1589
		state.setFlipSided( material.side === THREE.BackSide );

	}

1590
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1591 1592 1593

		_usedTextureUnits = 0;

1594
		var materialProperties = properties.get( material );
1595

1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609
		if ( materialProperties.program === undefined ) {

			material.needsUpdate = true;

		}

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

			material.needsUpdate = true;

		}

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

1611
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1612 1613 1614 1615
			material.needsUpdate = false;

		}

1616
		var refreshProgram = false;
M
Mr.doob 已提交
1617
		var refreshMaterial = false;
1618
		var refreshLights = false;
M
Mr.doob 已提交
1619

1620
		var program = materialProperties.program,
1621
			p_uniforms = program.getUniforms(),
1622
			m_uniforms = materialProperties.__webglShader.uniforms;
M
Mr.doob 已提交
1623

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

1626 1627
			_gl.useProgram( program.program );
			_currentProgram = program.id;
M
Mr.doob 已提交
1628

1629
			refreshProgram = true;
M
Mr.doob 已提交
1630
			refreshMaterial = true;
1631
			refreshLights = true;
M
Mr.doob 已提交
1632 1633 1634 1635 1636 1637

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1638

M
Mr.doob 已提交
1639 1640 1641 1642
			refreshMaterial = true;

		}

1643
		if ( refreshProgram || camera !== _currentCamera ) {
M
Mr.doob 已提交
1644 1645 1646

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

G
gero3 已提交
1647
			if ( capabilities.logarithmicDepthBuffer ) {
1648

1649
				_gl.uniform1f( p_uniforms.logDepthBufFC, 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1650 1651 1652 1653

			}


1654 1655 1656 1657 1658 1659 1660 1661 1662
			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 已提交
1663
				refreshLights = true;		// remains set until update done
1664 1665

			}
M
Mr.doob 已提交
1666

1667 1668 1669 1670 1671
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
1672
				 material instanceof THREE.MeshStandardMaterial ||
1673 1674
				 material.envMap ) {

1675
				if ( p_uniforms.cameraPosition !== undefined ) {
1676 1677 1678 1679 1680 1681 1682 1683 1684 1685

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

				}

			}

			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
1686
				 material instanceof THREE.MeshBasicMaterial ||
1687
				 material instanceof THREE.MeshStandardMaterial ||
1688 1689 1690
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {

1691
				if ( p_uniforms.viewMatrix !== undefined ) {
1692 1693

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

1695 1696 1697 1698
				}

			}

M
Mr.doob 已提交
1699 1700 1701 1702 1703 1704 1705 1706
		}

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

1707
			if ( object.bindMatrix && p_uniforms.bindMatrix !== undefined ) {
1708 1709 1710 1711 1712

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

			}

1713
			if ( object.bindMatrixInverse && p_uniforms.bindMatrixInverse !== undefined ) {
1714 1715 1716 1717 1718

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

			}

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

1721
				if ( p_uniforms.boneTexture !== undefined ) {
M
Mr.doob 已提交
1722 1723 1724 1725

					var textureUnit = getTextureUnit();

					_gl.uniform1i( p_uniforms.boneTexture, textureUnit );
1726
					_this.setTexture( object.skeleton.boneTexture, textureUnit );
M
Mr.doob 已提交
1727 1728 1729

				}

1730
				if ( p_uniforms.boneTextureWidth !== undefined ) {
1731

1732
					_gl.uniform1i( p_uniforms.boneTextureWidth, object.skeleton.boneTextureWidth );
1733 1734 1735

				}

1736
				if ( p_uniforms.boneTextureHeight !== undefined ) {
1737

1738
					_gl.uniform1i( p_uniforms.boneTextureHeight, object.skeleton.boneTextureHeight );
1739 1740 1741

				}

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

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

1746
					_gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.skeleton.boneMatrices );
M
Mr.doob 已提交
1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757

				}

			}

		}

		if ( refreshMaterial ) {

			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
1758
				 material instanceof THREE.MeshStandardMaterial ||
M
Mr.doob 已提交
1759 1760
				 material.lights ) {

1761
				// the current material requires lighting info
M
Mr.doob 已提交
1762

T
tschw 已提交
1763 1764 1765 1766 1767 1768
				// 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 已提交
1769

T
tschw 已提交
1770
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1771

T
tschw 已提交
1772
			}
G
gero3 已提交
1773

T
tschw 已提交
1774
			// refresh uniforms common to several materials
G
gero3 已提交
1775

T
tschw 已提交
1776
			if ( fog && material.fog ) {
G
gero3 已提交
1777

T
tschw 已提交
1778
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1779 1780 1781 1782 1783

			}

			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
W
WestLangley 已提交
1784
				 material instanceof THREE.MeshPhongMaterial ||
1785
				 material instanceof THREE.MeshStandardMaterial ) {
M
Mr.doob 已提交
1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801

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

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

M
Mr.doob 已提交
1804
				refreshUniformsPoints( m_uniforms, material );
M
Mr.doob 已提交
1805

1806 1807 1808 1809
			} else if ( material instanceof THREE.MeshLambertMaterial ) {

				refreshUniformsLambert( m_uniforms, material );

M
Mr.doob 已提交
1810 1811 1812 1813
			} else if ( material instanceof THREE.MeshPhongMaterial ) {

				refreshUniformsPhong( m_uniforms, material );

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

1816
				refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1817

M
Mr.doob 已提交
1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831
			} 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

1832
			loadUniformsGeneric( materialProperties.uniformsList );
M
Mr.doob 已提交
1833 1834 1835 1836 1837

		}

		loadUniformsMatrices( p_uniforms, object );

1838
		if ( p_uniforms.modelMatrix !== undefined ) {
M
Mr.doob 已提交
1839 1840

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

M
Mr.doob 已提交
1842 1843
		}

1844
		if ( materialProperties.hasDynamicUniforms === true ) {
A
arose 已提交
1845

1846
			updateDynamicUniforms( materialProperties.uniformsList, object, camera );
A
arose 已提交
1847 1848 1849

		}

M
Mr.doob 已提交
1850 1851
		return program;

M
Mr.doob 已提交
1852
	}
M
Mr.doob 已提交
1853

1854
	function updateDynamicUniforms ( uniforms, object, camera ) {
A
arose 已提交
1855 1856 1857 1858 1859 1860

		var dynamicUniforms = [];

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

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

1863
			if ( onUpdateCallback !== undefined ) {
A
arose 已提交
1864

1865
				onUpdateCallback.bind( uniform )( object, camera );
A
arose 已提交
1866 1867 1868 1869 1870 1871 1872 1873 1874 1875
				dynamicUniforms.push( uniforms[ j ] );

			}

		}

		loadUniformsGeneric( dynamicUniforms );

	}

M
Mr.doob 已提交
1876 1877 1878 1879 1880 1881
	// Uniforms (refresh uniforms objects)

	function refreshUniformsCommon ( uniforms, material ) {

		uniforms.opacity.value = material.opacity;

1882
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
1883

1884
		if ( material.emissive ) {
M
Mr.doob 已提交
1885

1886
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
1887 1888 1889

		}

1890 1891 1892
		uniforms.map.value = material.map;
		uniforms.specularMap.value = material.specularMap;
		uniforms.alphaMap.value = material.alphaMap;
M
Mr.doob 已提交
1893

1894
		if ( material.aoMap ) {
1895

1896 1897
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1898 1899 1900

		}

M
Mr.doob 已提交
1901
		// uv repeat and offset setting priorities
M
Mr.doob 已提交
1902 1903 1904 1905 1906
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
1907
		// 6. emissive map
M
Mr.doob 已提交
1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

1919 1920 1921 1922
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
1923 1924 1925 1926 1927 1928 1929 1930
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

1931 1932 1933 1934 1935 1936 1937 1938
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

1939 1940 1941 1942
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

1943 1944 1945 1946
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
1947 1948 1949 1950
		}

		if ( uvScaleMap !== undefined ) {

M
Mr.doob 已提交
1951 1952 1953 1954 1955 1956
			if ( uvScaleMap instanceof THREE.WebGLRenderTarget ) {

				uvScaleMap = uvScaleMap.texture;

			}

M
Mr.doob 已提交
1957 1958 1959 1960 1961 1962 1963 1964
			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;
1965
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : - 1;
M
Mr.doob 已提交
1966

1967
		uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
1968 1969
		uniforms.refractionRatio.value = material.refractionRatio;

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

	function refreshUniformsLine ( uniforms, material ) {

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

M
Mr.doob 已提交
1977
	}
M
Mr.doob 已提交
1978 1979 1980 1981 1982 1983 1984

	function refreshUniformsDash ( uniforms, material ) {

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

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

M
Mr.doob 已提交
1987
	function refreshUniformsPoints ( uniforms, material ) {
M
Mr.doob 已提交
1988

1989
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
1990
		uniforms.opacity.value = material.opacity;
1991 1992
		uniforms.size.value = material.size * _pixelRatio;
		uniforms.scale.value = _canvas.clientHeight / 2.0; // TODO: Cache this.
M
Mr.doob 已提交
1993 1994 1995

		uniforms.map.value = material.map;

1996 1997 1998 1999 2000 2001 2002 2003 2004
		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 已提交
2005
	}
M
Mr.doob 已提交
2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021

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

2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040
	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 已提交
2041 2042
	function refreshUniformsPhong ( uniforms, material ) {

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

2046 2047 2048 2049
		if ( material.lightMap ) {

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

2051
		}
2052

2053
		if ( material.emissiveMap ) {
2054

2055
			uniforms.emissiveMap.value = material.emissiveMap;
2056

2057
		}
M
Mr.doob 已提交
2058

2059 2060 2061 2062
		if ( material.bumpMap ) {

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

2064
		}
M
Mr.doob 已提交
2065

2066 2067 2068 2069 2070 2071
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2072

2073 2074 2075 2076 2077
		if ( material.displacementMap ) {

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

2079
		}
2080 2081 2082

	}

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

		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;

		}

	}

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

M
Mr.doob 已提交
2146
	function markUniformsLightsNeedsUpdate ( uniforms, value ) {
2147

M
Mr.doob 已提交
2148
		uniforms.ambientLightColor.needsUpdate = value;
2149

B
Ben Houston 已提交
2150 2151 2152 2153
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
		uniforms.hemisphereLights.needsUpdate = value;
2154

M
Mr.doob 已提交
2155
	}
2156

M
Mr.doob 已提交
2157 2158 2159 2160
	// Uniforms (load to GPU)

	function loadUniformsMatrices ( uniforms, object ) {

2161
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object.modelViewMatrix.elements );
M
Mr.doob 已提交
2162 2163 2164

		if ( uniforms.normalMatrix ) {

2165
			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object.normalMatrix.elements );
M
Mr.doob 已提交
2166 2167 2168

		}

M
Mr.doob 已提交
2169
	}
M
Mr.doob 已提交
2170 2171 2172 2173 2174

	function getTextureUnit() {

		var textureUnit = _usedTextureUnits;

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

G
gero3 已提交
2177
			console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
M
Mr.doob 已提交
2178 2179 2180 2181 2182 2183 2184

		}

		_usedTextureUnits += 1;

		return textureUnit;

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

2187
	function loadUniformsGeneric ( uniforms ) {
M
Mr.doob 已提交
2188

M
Mr.doob 已提交
2189
		var texture, textureUnit;
M
Mr.doob 已提交
2190

M
Mr.doob 已提交
2191 2192 2193
		for ( var j = 0, jl = uniforms.length; j < jl; j ++ ) {

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

2195 2196
			// needsUpdate property is not added to all uniforms.
			if ( uniform.needsUpdate === false ) continue;
2197

M
Mr.doob 已提交
2198 2199
			var type = uniform.type;
			var value = uniform.value;
2200
			var location = uniforms[ j ][ 1 ];
M
Mr.doob 已提交
2201

2202
			switch ( type ) {
M
Mr.doob 已提交
2203

2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247
				case '1i':
					_gl.uniform1i( location, value );
					break;

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

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

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

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

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

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

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

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

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

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

2248 2249 2250 2251
				case 'Matrix2fv':
					_gl.uniformMatrix2fv( location, false, value );
					break;

2252 2253 2254 2255 2256 2257 2258 2259 2260 2261
				case 'Matrix3fv':
					_gl.uniformMatrix3fv( location, false, value );
					break;

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

				//

M
Mr.doob 已提交
2262
				case 'i':
M
Mr.doob 已提交
2263

2264 2265
					// single integer
					_gl.uniform1i( location, value );
M
Mr.doob 已提交
2266

2267
					break;
M
Mr.doob 已提交
2268

2269
				case 'f':
M
Mr.doob 已提交
2270

2271 2272
					// single float
					_gl.uniform1f( location, value );
M
Mr.doob 已提交
2273

2274
					break;
M
Mr.doob 已提交
2275

2276
				case 'v2':
M
Mr.doob 已提交
2277

2278 2279
					// single THREE.Vector2
					_gl.uniform2f( location, value.x, value.y );
M
Mr.doob 已提交
2280

2281
					break;
M
Mr.doob 已提交
2282

2283
				case 'v3':
M
Mr.doob 已提交
2284

2285 2286
					// single THREE.Vector3
					_gl.uniform3f( location, value.x, value.y, value.z );
M
Mr.doob 已提交
2287

2288
					break;
M
Mr.doob 已提交
2289

M
Mr.doob 已提交
2290
				case 'v4':
M
Mr.doob 已提交
2291

2292 2293
					// single THREE.Vector4
					_gl.uniform4f( location, value.x, value.y, value.z, value.w );
M
Mr.doob 已提交
2294

2295
					break;
M
Mr.doob 已提交
2296

2297
				case 'c':
M
Mr.doob 已提交
2298

2299 2300
					// single THREE.Color
					_gl.uniform3f( location, value.r, value.g, value.b );
M
Mr.doob 已提交
2301

2302
					break;
M
Mr.doob 已提交
2303

2304
				/*
2305 2306 2307
				case 's':

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

B
Ben Houston 已提交
2310 2311 2312
						var property = uniform.properties[ propertyName ];
						var locationProperty =  location[ propertyName ];
						var valueProperty = value[ propertyName ];
M
Mr.doob 已提交
2313

2314
						switch( property.type ) {
2315 2316 2317
							case 'i':
								_gl.uniform1i( locationProperty, valueProperty );
								break;
2318
							case 'f':
B
Ben Houston 已提交
2319
								_gl.uniform1f( locationProperty, valueProperty );
2320 2321
								break;
							case 'v2':
B
Ben Houston 已提交
2322
								_gl.uniform2f( locationProperty, valueProperty.x, valueProperty.y );
2323 2324
								break;
							case 'v3':
B
Ben Houston 已提交
2325
								_gl.uniform3f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z );
2326 2327
								break;
							case 'v4':
B
Ben Houston 已提交
2328
								_gl.uniform4f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w );
2329 2330
								break;
							case 'c':
B
Ben Houston 已提交
2331
								_gl.uniform3f( locationProperty, valueProperty.r, valueProperty.g, valueProperty.b );
2332 2333
								break;
						};
2334 2335 2336 2337

					}

					break;
2338
				*/
2339

2340
				case 'sa':
2341

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

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

B
Ben Houston 已提交
2347 2348
							var property = uniform.properties[ propertyName ];
							var locationProperty =  location[ i ][ propertyName ];
2349
							var valueProperty = value[ i ][ propertyName ];
M
Mr.doob 已提交
2350

2351
							switch ( property.type ) {
2352 2353 2354
								case 'i':
									_gl.uniform1i( locationProperty, valueProperty );
									break;
2355
								case 'f':
B
Ben Houston 已提交
2356
									_gl.uniform1f( locationProperty, valueProperty );
2357 2358
									break;
								case 'v2':
B
Ben Houston 已提交
2359
									_gl.uniform2f( locationProperty, valueProperty.x, valueProperty.y );
2360 2361
									break;
								case 'v3':
B
Ben Houston 已提交
2362
									_gl.uniform3f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z );
2363 2364
									break;
								case 'v4':
B
Ben Houston 已提交
2365
									_gl.uniform4f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w );
2366 2367
									break;
								case 'c':
B
Ben Houston 已提交
2368
									_gl.uniform3f( locationProperty, valueProperty.r, valueProperty.g, valueProperty.b );
2369
									break;
M
Mr.doob 已提交
2370 2371 2372
								case 'm4':
									_gl.uniformMatrix4fv( locationProperty, false, valueProperty.elements );
									break;
M
Mr.doob 已提交
2373
							}
2374

2375
						}
2376 2377

					}
M
Mr.doob 已提交
2378

2379 2380
					break;

2381
				case 'iv1':
M
Mr.doob 已提交
2382

2383 2384
					// flat array of integers (JS or typed array)
					_gl.uniform1iv( location, value );
M
Mr.doob 已提交
2385

2386
					break;
M
Mr.doob 已提交
2387

2388
				case 'iv':
M
Mr.doob 已提交
2389

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

2393
					break;
M
Mr.doob 已提交
2394

2395
				case 'fv1':
M
Mr.doob 已提交
2396

2397 2398
					// flat array of floats (JS or typed array)
					_gl.uniform1fv( location, value );
M
Mr.doob 已提交
2399

2400
					break;
M
Mr.doob 已提交
2401

2402
				case 'fv':
M
Mr.doob 已提交
2403

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

2407
					break;
M
Mr.doob 已提交
2408

2409
				case 'v2v':
M
Mr.doob 已提交
2410

2411
					// array of THREE.Vector2
M
Mr.doob 已提交
2412

2413
					if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2414

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

2417
					}
M
Mr.doob 已提交
2418

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

M
Mr.doob 已提交
2421 2422
						uniform._array[ i2 + 0 ] = value[ i ].x;
						uniform._array[ i2 + 1 ] = value[ i ].y;
M
Mr.doob 已提交
2423

2424
					}
M
Mr.doob 已提交
2425

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

2428
					break;
M
Mr.doob 已提交
2429

2430
				case 'v3v':
M
Mr.doob 已提交
2431

2432
					// array of THREE.Vector3
M
Mr.doob 已提交
2433

2434
					if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2435

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

2438
					}
M
Mr.doob 已提交
2439

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

M
Mr.doob 已提交
2442 2443 2444
						uniform._array[ i3 + 0 ] = value[ i ].x;
						uniform._array[ i3 + 1 ] = value[ i ].y;
						uniform._array[ i3 + 2 ] = value[ i ].z;
R
Ryan Tsao 已提交
2445

2446
					}
R
Ryan Tsao 已提交
2447

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

2450
					break;
R
Ryan Tsao 已提交
2451

2452
				case 'v4v':
R
Ryan Tsao 已提交
2453

2454
					// array of THREE.Vector4
R
Ryan Tsao 已提交
2455

2456
					if ( uniform._array === undefined ) {
R
Ryan Tsao 已提交
2457

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

2460
					}
M
Mr.doob 已提交
2461

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

M
Mr.doob 已提交
2464 2465 2466 2467
						uniform._array[ i4 + 0 ] = value[ i ].x;
						uniform._array[ i4 + 1 ] = value[ i ].y;
						uniform._array[ i4 + 2 ] = value[ i ].z;
						uniform._array[ i4 + 3 ] = value[ i ].w;
M
Mr.doob 已提交
2468

2469
					}
M
Mr.doob 已提交
2470

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

2473
					break;
M
Mr.doob 已提交
2474

2475 2476 2477 2478 2479 2480 2481
				case 'm2':

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

					break;

2482
				case 'm3':
M
Mr.doob 已提交
2483

2484 2485
					// single THREE.Matrix3
					_gl.uniformMatrix3fv( location, false, value.elements );
M
Mr.doob 已提交
2486

2487
					break;
M
Mr.doob 已提交
2488

2489
				case 'm3v':
M
Mr.doob 已提交
2490

2491
					// array of THREE.Matrix3
M
Mr.doob 已提交
2492

2493
					if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2494

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

2497
					}
M
Mr.doob 已提交
2498

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

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

2503
					}
M
Mr.doob 已提交
2504

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

2507
					break;
M
Mr.doob 已提交
2508

2509
				case 'm4':
M
Mr.doob 已提交
2510

2511 2512
					// single THREE.Matrix4
					_gl.uniformMatrix4fv( location, false, value.elements );
M
Mr.doob 已提交
2513

2514
					break;
M
Mr.doob 已提交
2515

2516
				case 'm4v':
M
Mr.doob 已提交
2517

2518
					// array of THREE.Matrix4
M
Mr.doob 已提交
2519

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

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

2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534
					}

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

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

					}

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

					break;
M
Mr.doob 已提交
2535

2536
				case 't':
M
Mr.doob 已提交
2537

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

2540 2541 2542 2543
					texture = value;
					textureUnit = getTextureUnit();

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

2545
					if ( ! texture ) continue;
M
Mr.doob 已提交
2546

2547
					if ( texture instanceof THREE.CubeTexture ||
G
gero3 已提交
2548 2549 2550
						 ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {

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

2552
						setCubeTexture( texture, textureUnit );
M
Mr.doob 已提交
2553

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

M
Mr.doob 已提交
2556 2557 2558 2559 2560
						setCubeTextureDynamic( texture.texture, textureUnit );

					} else if ( texture instanceof THREE.WebGLRenderTarget ) {

						_this.setTexture( texture.texture, textureUnit );
2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571

					} else {

						_this.setTexture( texture, textureUnit );

					}

					break;

				case 'tv':

M
Mr.doob 已提交
2572
					// array of THREE.Texture (2d or cube)
2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594

					if ( uniform._array === undefined ) {

						uniform._array = [];

					}

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

						uniform._array[ i ] = getTextureUnit();

					}

					_gl.uniform1iv( location, uniform._array );

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

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

						if ( ! texture ) continue;

M
Mr.doob 已提交
2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614
						if ( texture instanceof THREE.CubeTexture ||
							 ( texture.image instanceof Array && texture.image.length === 6 ) ) {

							// CompressedTexture can have Array in image :/

							setCubeTexture( texture, textureUnit );

						} else if ( texture instanceof THREE.WebGLRenderTarget ) {

							_this.setTexture( texture.texture, textureUnit );

						} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {

							setCubeTextureDynamic( texture.texture, textureUnit );

						} else {

							_this.setTexture( texture, textureUnit );

						}
2615 2616 2617 2618 2619 2620

					}

					break;

				default:
2621

2622
					console.warn( 'THREE.WebGLRenderer: Unknown uniform type: ' + type );
2623

M
Mr.doob 已提交
2624 2625 2626 2627
			}

		}

M
Mr.doob 已提交
2628
	}
M
Mr.doob 已提交
2629

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

B
brason 已提交
2632
		var l, ll, light,
M
Mr.doob 已提交
2633
		r = 0, g = 0, b = 0,
B
Ben Houston 已提交
2634
		color,
B
brason 已提交
2635
		intensity,
M
Mr.doob 已提交
2636 2637
		distance,

2638
		viewMatrix = camera.matrixWorldInverse,
M
Mr.doob 已提交
2639

M
Mr.doob 已提交
2640
		directionalLength = 0,
M
Mr.doob 已提交
2641 2642
		pointLength = 0,
		spotLength = 0,
2643 2644 2645
		hemiLength = 0,

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

2647 2648
		_lights.shadowsPointLight = 0;

M
Mr.doob 已提交
2649 2650 2651 2652 2653 2654 2655 2656 2657 2658
		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 ) {

2659 2660 2661
				r += color.r * intensity;
				g += color.g * intensity;
				b += color.b * intensity;
M
Mr.doob 已提交
2662 2663 2664

			} else if ( light instanceof THREE.DirectionalLight ) {

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

2667
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
M
Mr.doob 已提交
2668
				uniforms.direction.setFromMatrixPosition( light.matrixWorld );
2669
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
M
Mr.doob 已提交
2670 2671 2672
				uniforms.direction.sub( _vector3 );
				uniforms.direction.transformDirection( viewMatrix );

2673
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2674

2675
				if ( light.castShadow ) {
M
Mr.doob 已提交
2676

2677 2678 2679
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;
2680

2681
					_lights.shadows[ shadowsLength ++ ] = light;
2682

2683 2684
				}

2685 2686
				_lights.directionalShadowMap[ directionalLength ] = light.shadow.map;
				_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
2687
				_lights.directional[ directionalLength ++ ] = uniforms;
M
Mr.doob 已提交
2688

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

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

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

M
Mr.doob 已提交
2696 2697 2698 2699 2700 2701 2702 2703
				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 );

2704 2705
				uniforms.coneCos = Math.cos( light.angle );
				uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
M
Mr.doob 已提交
2706
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
M
Mr.doob 已提交
2707

2708
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2709

2710 2711
				if ( light.castShadow ) {

2712 2713 2714
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;
2715

2716
					_lights.shadows[ shadowsLength ++ ] = light;
2717

2718 2719
				}

2720 2721
				_lights.spotShadowMap[ spotLength ] = light.shadow.map;
				_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;
M
Mr.doob 已提交
2722
				_lights.spot[ spotLength ++ ] = uniforms;
2723

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

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

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

M
Mr.doob 已提交
2731 2732
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
				uniforms.distance = light.distance;
M
Mr.doob 已提交
2733 2734
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;

2735
				uniforms.shadow = light.castShadow;
2736

M
Mr.doob 已提交
2737
				if ( light.castShadow ) {
2738

2739 2740 2741 2742 2743
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;

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

2745
				}
2746

2747
				_lights.pointShadowMap[ pointLength ] = light.shadow.map;
2748

2749 2750 2751
				if ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {

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

2753 2754
				}

2755 2756 2757 2758 2759
				// 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 已提交
2760
				_lights.point[ pointLength ++ ] = uniforms;
2761

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

M
Mr.doob 已提交
2764
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2765 2766 2767 2768

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

M
Mr.doob 已提交
2770 2771
				uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
				uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
M
Mr.doob 已提交
2772

M
Mr.doob 已提交
2773
				_lights.hemi[ hemiLength ++ ] = uniforms;
M
Mr.doob 已提交
2774 2775 2776 2777 2778

			}

		}

M
Mr.doob 已提交
2779 2780 2781
		_lights.ambient[ 0 ] = r;
		_lights.ambient[ 1 ] = g;
		_lights.ambient[ 2 ] = b;
M
Mr.doob 已提交
2782

M
Mr.doob 已提交
2783 2784
		_lights.directional.length = directionalLength;
		_lights.spot.length = spotLength;
2785
		_lights.point.length = pointLength;
M
Mr.doob 已提交
2786
		_lights.hemi.length = hemiLength;
2787

2788 2789
		_lights.shadows.length = shadowsLength;

2790
		_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + hemiLength + ',' + shadowsLength;
2791

M
Mr.doob 已提交
2792
	}
M
Mr.doob 已提交
2793 2794 2795 2796 2797 2798 2799

	// GL state setting

	this.setFaceCulling = function ( cullFace, frontFaceDirection ) {

		if ( cullFace === THREE.CullFaceNone ) {

2800
			state.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827

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

			}

2828
			state.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
2829 2830 2831 2832 2833 2834 2835

		}

	};

	// Textures

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

2838 2839
		var extension;

M
Mr.doob 已提交
2840
		if ( isPowerOfTwoImage ) {
M
Mr.doob 已提交
2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851

			_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 已提交
2852 2853 2854

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

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

2857
			}
M
Mr.doob 已提交
2858 2859 2860 2861

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

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

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

2866
			}
M
Mr.doob 已提交
2867

M
Mr.doob 已提交
2868 2869
		}

2870 2871
		extension = extensions.get( 'EXT_texture_filter_anisotropic' );

2872
		if ( extension ) {
M
Mr.doob 已提交
2873

2874 2875
			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 已提交
2876

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

2879
				_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _this.getMaxAnisotropy() ) );
2880
				properties.get( texture ).__currentAnisotropy = texture.anisotropy;
M
Mr.doob 已提交
2881 2882 2883 2884 2885

			}

		}

M
Mr.doob 已提交
2886
	}
M
Mr.doob 已提交
2887

2888
	function uploadTexture( textureProperties, texture, slot ) {
2889

2890
		if ( textureProperties.__webglInit === undefined ) {
2891

2892
			textureProperties.__webglInit = true;
2893 2894 2895

			texture.addEventListener( 'dispose', onTextureDispose );

2896
			textureProperties.__webglTexture = _gl.createTexture();
2897

2898
			_infoMemory.textures ++;
2899 2900

		}
M
Mr.doob 已提交
2901

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

H
Henri Astre 已提交
2905 2906 2907 2908
		_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 );

2909
		var image = clampToMaxSize( texture.image, capabilities.maxTextureSize );
2910

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

2913
			image = makePowerOfTwo( image );
M
Mr.doob 已提交
2914 2915 2916

		}

M
Mr.doob 已提交
2917
		var isPowerOfTwoImage = isPowerOfTwo( image ),
H
Henri Astre 已提交
2918 2919
		glFormat = paramThreeToGL( texture.format ),
		glType = paramThreeToGL( texture.type );
M
Mr.doob 已提交
2920

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

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

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

H
Henri Astre 已提交
2927 2928 2929
			// 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 已提交
2930

M
Mr.doob 已提交
2931
			if ( mipmaps.length > 0 && isPowerOfTwoImage ) {
H
Henri Astre 已提交
2932 2933

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

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

H
Henri Astre 已提交
2938
				}
M
Mr.doob 已提交
2939

H
Henri Astre 已提交
2940
				texture.generateMipmaps = false;
M
Mr.doob 已提交
2941

H
Henri Astre 已提交
2942
			} else {
M
Mr.doob 已提交
2943

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

H
Henri Astre 已提交
2946
			}
M
Mr.doob 已提交
2947

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

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

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

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

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

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

2960
					} else {
M
Mr.doob 已提交
2961

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

2964
					}
M
Mr.doob 已提交
2965

H
Henri Astre 已提交
2966
				} else {
M
Mr.doob 已提交
2967

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

M
Mr.doob 已提交
2970 2971
				}

H
Henri Astre 已提交
2972 2973
			}

G
gero3 已提交
2974 2975 2976
		} else {

			// regular Texture (image, video, canvas)
H
Henri Astre 已提交
2977 2978 2979 2980 2981

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

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

					mipmap = mipmaps[ i ];
2987
					state.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );
M
Mr.doob 已提交
2988 2989 2990

				}

H
Henri Astre 已提交
2991
				texture.generateMipmaps = false;
M
Mr.doob 已提交
2992

H
Henri Astre 已提交
2993
			} else {
M
Mr.doob 已提交
2994

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

H
Henri Astre 已提交
2997
			}
M
Mr.doob 已提交
2998

H
Henri Astre 已提交
2999
		}
M
Mr.doob 已提交
3000

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

3003
		textureProperties.__version = texture.version;
M
Mr.doob 已提交
3004

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

3007
	}
M
Mr.doob 已提交
3008

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

3011 3012 3013
		var textureProperties = properties.get( texture );

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

3015
			var image = texture.image;
M
Mr.doob 已提交
3016

3017 3018
			if ( image === undefined ) {

3019
				console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );
3020 3021 3022 3023
				return;

			}

3024
			if ( image.complete === false ) {
M
Mr.doob 已提交
3025

3026
				console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );
3027 3028 3029 3030
				return;

			}

3031
			uploadTexture( textureProperties, texture, slot );
3032

3033
			return;
M
Mr.doob 已提交
3034 3035 3036

		}

B
Ben Adams 已提交
3037
		state.activeTexture( _gl.TEXTURE0 + slot );
3038
		state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
3039

M
Mr.doob 已提交
3040 3041 3042 3043
	};

	function clampToMaxSize ( image, maxSize ) {

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

3046 3047
			// Warning: Scaling through the canvas will only work with images that use
			// premultiplied alpha.
M
Mr.doob 已提交
3048

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

3051 3052 3053
			var canvas = document.createElement( 'canvas' );
			canvas.width = Math.floor( image.width * scale );
			canvas.height = Math.floor( image.height * scale );
M
Mr.doob 已提交
3054

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

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

3060 3061 3062
			return canvas;

		}
M
Mr.doob 已提交
3063

3064
		return image;
M
Mr.doob 已提交
3065 3066 3067

	}

M
Mr.doob 已提交
3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103
	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 已提交
3104 3105
	function setCubeTexture ( texture, slot ) {

3106
		var textureProperties = properties.get( texture );
3107

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

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

3112
				if ( ! textureProperties.__image__webglTextureCube ) {
M
Mr.doob 已提交
3113

3114 3115
					texture.addEventListener( 'dispose', onTextureDispose );

3116
					textureProperties.__image__webglTextureCube = _gl.createTexture();
M
Mr.doob 已提交
3117

3118
					_infoMemory.textures ++;
M
Mr.doob 已提交
3119 3120 3121

				}

B
Ben Adams 已提交
3122
				state.activeTexture( _gl.TEXTURE0 + slot );
3123
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
3124 3125 3126

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

M
Mr.doob 已提交
3127 3128
				var isCompressed = texture instanceof THREE.CompressedTexture;
				var isDataTexture = texture.image[ 0 ] instanceof THREE.DataTexture;
M
Mr.doob 已提交
3129 3130 3131 3132 3133

				var cubeImage = [];

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

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

G
gero3 已提交
3136
						cubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );
M
Mr.doob 已提交
3137 3138 3139

					} else {

3140
						cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];
M
Mr.doob 已提交
3141 3142 3143 3144 3145 3146

					}

				}

				var image = cubeImage[ 0 ],
M
Mr.doob 已提交
3147
				isPowerOfTwoImage = isPowerOfTwo( image ),
M
Mr.doob 已提交
3148 3149 3150
				glFormat = paramThreeToGL( texture.format ),
				glType = paramThreeToGL( texture.type );

M
Mr.doob 已提交
3151
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );
M
Mr.doob 已提交
3152 3153 3154

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

3155
					if ( ! isCompressed ) {
M
Mr.doob 已提交
3156

M
Mr.doob 已提交
3157
						if ( isDataTexture ) {
3158

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

M
Mr.doob 已提交
3161
						} else {
3162

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

M
Mr.doob 已提交
3165 3166
						}

3167
					} else {
3168

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

3171
						for ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {
M
Mr.doob 已提交
3172 3173

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

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

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

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

3181
								} else {
M
Mr.doob 已提交
3182

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

3185
								}
M
Mr.doob 已提交
3186

3187
							} else {
M
Mr.doob 已提交
3188

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

3191
							}
M
Mr.doob 已提交
3192

3193
						}
M
Mr.doob 已提交
3194

M
Mr.doob 已提交
3195
					}
M
Mr.doob 已提交
3196

M
Mr.doob 已提交
3197 3198
				}

M
Mr.doob 已提交
3199
				if ( texture.generateMipmaps && isPowerOfTwoImage ) {
M
Mr.doob 已提交
3200 3201 3202 3203 3204

					_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

				}

3205
				textureProperties.__version = texture.version;
M
Mr.doob 已提交
3206

B
Ben Adams 已提交
3207
				if ( texture.onUpdate ) texture.onUpdate( texture );
M
Mr.doob 已提交
3208 3209 3210

			} else {

B
Ben Adams 已提交
3211
				state.activeTexture( _gl.TEXTURE0 + slot );
3212
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
3213 3214 3215 3216 3217

			}

		}

M
Mr.doob 已提交
3218
	}
M
Mr.doob 已提交
3219 3220 3221

	function setCubeTextureDynamic ( texture, slot ) {

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

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

	// Render targets

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

3232 3233 3234
		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 已提交
3235
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
3236 3237
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
M
Mr.doob 已提交
3238

M
Mr.doob 已提交
3239
	}
M
Mr.doob 已提交
3240

3241 3242
	// Setup storage for internal depth/stencil buffers and bind to correct framebuffer
	function setupRenderBufferStorage ( renderbuffer, renderTarget ) {
M
Mr.doob 已提交
3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257

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

3258
			// FIXME: We don't support !depth !stencil
M
Mr.doob 已提交
3259 3260 3261 3262
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );

		}

3263
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
M
Mr.doob 已提交
3264

M
Mr.doob 已提交
3265
	}
M
Mr.doob 已提交
3266

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

3270
		var renderTargetProperties = properties.get( renderTarget );
M
Mr.doob 已提交
3271 3272

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

3274
		if ( isCube ) {
M
Mr.doob 已提交
3275

3276
			renderTargetProperties.__webglDepthbuffer = [];
M
Mr.doob 已提交
3277

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

M
Marius Kintel 已提交
3280
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );
3281 3282
				renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();
				setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );
M
Mr.doob 已提交
3283 3284

			}
B
Ben Adams 已提交
3285

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

M
Marius Kintel 已提交
3288
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );
3289 3290
			renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
			setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );
M
Mr.doob 已提交
3291

3292
		}
M
Mr.doob 已提交
3293

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

M
Mr.doob 已提交
3296
	}
M
Mr.doob 已提交
3297

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

3301 3302
		var renderTargetProperties = properties.get( renderTarget );
		var textureProperties = properties.get( renderTarget.texture );
M
Mr.doob 已提交
3303

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

3306
		textureProperties.__webglTexture = _gl.createTexture();
M
Mr.doob 已提交
3307

3308
		_infoMemory.textures ++;
M
Mr.doob 已提交
3309

3310 3311
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
		var isTargetPowerOfTwo = THREE.Math.isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height );
M
Mr.doob 已提交
3312

3313
		// Setup framebuffer
M
Mr.doob 已提交
3314

3315
		if ( isCube ) {
M
Mr.doob 已提交
3316

3317
			renderTargetProperties.__webglFramebuffer = [];
M
Mr.doob 已提交
3318

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

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

3323
			}
M
Mr.doob 已提交
3324

3325
		} else {
M
Mr.doob 已提交
3326

3327
			renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
M
Mr.doob 已提交
3328

3329
		}
M
Mr.doob 已提交
3330

3331
		// Setup color buffer
M
Mr.doob 已提交
3332

3333
		if ( isCube ) {
M
Mr.doob 已提交
3334

3335 3336
			state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
			setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );
M
Mr.doob 已提交
3337

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

3340
				setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
M
Mr.doob 已提交
3341 3342 3343

			}

3344 3345
			if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
			state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
M
Mr.doob 已提交
3346

3347
		} else {
M
Mr.doob 已提交
3348

3349 3350 3351
			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 已提交
3352

3353 3354
			if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
			state.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
3355

3356
		}
M
Mr.doob 已提交
3357

3358
		// Setup depth and stencil buffers
3359

3360
		if ( renderTarget.depthBuffer ) {
M
Mr.doob 已提交
3361

M
Marius Kintel 已提交
3362
			setupDepthRenderbuffer( renderTarget );
M
Mr.doob 已提交
3363

3364
		}
M
Mr.doob 已提交
3365

3366
	}
M
Mr.doob 已提交
3367

3368
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
3369

3370 3371
		_currentRenderTarget = renderTarget;

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

M
Marius Kintel 已提交
3374
			setupRenderTarget( renderTarget );
M
Mr.doob 已提交
3375 3376 3377

		}

3378
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
3379
		var framebuffer;
M
Mr.doob 已提交
3380 3381 3382

		if ( renderTarget ) {

3383
			var renderTargetProperties = properties.get( renderTarget );
F
Fordy 已提交
3384

M
Mr.doob 已提交
3385 3386
			if ( isCube ) {

3387
				framebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
3388 3389 3390

			} else {

3391
				framebuffer = renderTargetProperties.__webglFramebuffer;
M
Mr.doob 已提交
3392 3393 3394

			}

3395 3396
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
3397

3398
			_currentViewport.copy( renderTarget.viewport );
M
Mr.doob 已提交
3399 3400 3401 3402 3403

		} else {

			framebuffer = null;

3404
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
3405
			_currentScissorTest = _scissorTest;
3406

3407
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
M
Mr.doob 已提交
3408 3409 3410

		}

M
Mr.doob 已提交
3411
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
3412 3413 3414 3415 3416 3417

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

		}

3418 3419
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
3420

3421
		state.viewport( _currentViewport );
3422

M
Mr.doob 已提交
3423 3424 3425 3426 3427 3428 3429
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, 0 );

		}

M
Mr.doob 已提交
3430 3431
	};

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

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

3436
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
3437
			return;
3438

G
gero3 已提交
3439
		}
3440

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

M
Mr.doob 已提交
3443
		if ( framebuffer ) {
3444

G
gero3 已提交
3445
			var restore = false;
3446

M
Mr.doob 已提交
3447
			if ( framebuffer !== _currentFramebuffer ) {
3448

M
Mr.doob 已提交
3449
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
3450

G
gero3 已提交
3451
				restore = true;
3452

G
gero3 已提交
3453
			}
3454

M
Mr.doob 已提交
3455
			try {
3456

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

M
Mr.doob 已提交
3459 3460
				if ( texture.format !== THREE.RGBAFormat
					&& paramThreeToGL( texture.format ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
3461

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

M
Mr.doob 已提交
3465
				}
3466

M
Mr.doob 已提交
3467 3468 3469 3470
				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' ) ) ) {
3471

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

M
Mr.doob 已提交
3475
				}
3476

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

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

M
Mr.doob 已提交
3481
				} else {
M
Mr.doob 已提交
3482

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

				}
M
Mr.doob 已提交
3486

M
Mr.doob 已提交
3487
			} finally {
M
Mr.doob 已提交
3488

M
Mr.doob 已提交
3489 3490 3491
				if ( restore ) {

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

M
Mr.doob 已提交
3493 3494 3495
				}

			}
M
Mr.doob 已提交
3496 3497 3498

		}

M
Mr.doob 已提交
3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509
	};

	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 已提交
3510
	}
M
Mr.doob 已提交
3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523

	// 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 已提交
3524
	}
M
Mr.doob 已提交
3525 3526 3527 3528 3529

	// Map three.js constants to WebGL constants

	function paramThreeToGL ( p ) {

3530 3531
		var extension;

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

3556 3557 3558 3559 3560 3561 3562 3563
		extension = extensions.get( 'OES_texture_half_float' );

		if ( extension !== null ) {

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

		}

M
Mr.doob 已提交
3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586
		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;

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

3589 3590 3591 3592 3593 3594
		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 已提交
3595 3596 3597

		}

3598 3599 3600
		extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );

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

3602 3603 3604 3605
			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 已提交
3606 3607 3608

		}

3609 3610 3611 3612 3613 3614 3615 3616
		extension = extensions.get( 'WEBGL_compressed_texture_etc1' );

		if ( extension !== null ) {

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

		}

3617 3618 3619
		extension = extensions.get( 'EXT_blend_minmax' );

		if ( extension !== null ) {
3620

3621 3622
			if ( p === THREE.MinEquation ) return extension.MIN_EXT;
			if ( p === THREE.MaxEquation ) return extension.MAX_EXT;
3623 3624 3625

		}

M
Mr.doob 已提交
3626 3627
		return 0;

M
Mr.doob 已提交
3628
	}
M
Mr.doob 已提交
3629 3630

};