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

THREE.WebGLRenderer = function ( parameters ) {

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

	parameters = parameters || {};

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

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

20 21
	pixelRatio = 1,

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

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

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

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

39 40
	var morphInfluences = new Float32Array( 8 );

41

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

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

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

	// clearing

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

	// scene graph

	this.sortObjects = true;

	// physically based shading

63
	this.gammaFactor = 2.0;	// for backwards compatibility
M
Mr.doob 已提交
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
	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,
	_currentFramebuffer = null,
84
	_currentMaterialId = - 1,
85
	_currentGeometryProgram = '',
M
Mr.doob 已提交
86 87 88 89 90 91
	_currentCamera = null,

	_usedTextureUnits = 0,

	_viewportX = 0,
	_viewportY = 0,
92 93
	_viewportWidth = _canvas.width,
	_viewportHeight = _canvas.height,
M
Mr.doob 已提交
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
	_currentWidth = 0,
	_currentHeight = 0,

	// frustum

	_frustum = new THREE.Frustum(),

	 // camera matrices cache

	_projScreenMatrix = new THREE.Matrix4(),

	_vector3 = new THREE.Vector3(),

	// light arrays cache

	_lights = {

		ambient: [ 0, 0, 0 ],
M
Mr.doob 已提交
112 113 114 115
		directional: [],
		point: [],
		spot: [],
		hemi: []
M
Mr.doob 已提交
116

117 118
	},

M
Mr.doob 已提交
119 120
	_lightsNeedUpdate = true,

M
Mr.doob 已提交
121 122
	// info

123
	_infoMemory = {
124 125

		geometries: 0,
T
tschw 已提交
126
		textures: 0
127 128 129

	},

130
	_infoRender = {
131 132 133 134 135 136

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

M
Mr.doob 已提交
137 138
	};

M
Mr.doob 已提交
139
	this.info = {
140

M
Mr.doob 已提交
141 142
		render: _infoRender,
		memory: _infoMemory,
143
		programs: null
M
Mr.doob 已提交
144 145

	};
146

147

M
Mr.doob 已提交
148 149 150 151
	// initialize

	var _gl;

M
Mr.doob 已提交
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
	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 已提交
167
			if ( _canvas.getContext( 'webgl' ) !== null ) {
168 169 170 171 172 173 174 175

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

			} else {

				throw 'Error creating WebGL context.';

			}
M
Mr.doob 已提交
176 177 178

		}

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

M
Mr.doob 已提交
181 182
	} catch ( error ) {

183
		console.error( 'THREE.WebGLRenderer: ' + error );
M
Mr.doob 已提交
184 185 186

	}

187 188
	var extensions = new THREE.WebGLExtensions( _gl );

189 190
	extensions.get( 'OES_texture_float' );
	extensions.get( 'OES_texture_float_linear' );
191 192
	extensions.get( 'OES_texture_half_float' );
	extensions.get( 'OES_texture_half_float_linear' );
193
	extensions.get( 'OES_standard_derivatives' );
B
Ben Adams 已提交
194
	extensions.get( 'ANGLE_instanced_arrays' );
195

196 197
	if ( extensions.get( 'OES_element_index_uint' ) ) {

198
		THREE.BufferGeometry.MaxIndex = 4294967296;
199 200 201

	}

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

204 205 206
	var state = new THREE.WebGLState( _gl, extensions, paramThreeToGL );
	var properties = new THREE.WebGLProperties();
	var objects = new THREE.WebGLObjects( _gl, properties, this.info );
G
gero3 已提交
207
	var programCache = new THREE.WebGLPrograms( this, capabilities );
208

209 210
	this.info.programs = programCache.programs;

211 212
	var bufferRenderer = new THREE.WebGLBufferRenderer( _gl, extensions, _infoRender );
	var indexedBufferRenderer = new THREE.WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
213

M
Mr.doob 已提交
214 215
	//

216
	function glClearColor( r, g, b, a ) {
217 218 219

		if ( _premultipliedAlpha === true ) {

220
			r *= a; g *= a; b *= a;
221 222 223

		}

224 225
		_gl.clearColor( r, g, b, a );

226
	}
227

228
	function setDefaultGLState() {
M
Mr.doob 已提交
229

M
Mr.doob 已提交
230
		state.init();
M
Mr.doob 已提交
231 232 233

		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );

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

236
	}
237

238
	function resetGLState() {
239 240 241 242

		_currentProgram = null;
		_currentCamera = null;

243
		_currentGeometryProgram = '';
244 245 246 247
		_currentMaterialId = - 1;

		_lightsNeedUpdate = true;

M
Mr.doob 已提交
248 249
		state.reset();

250
	}
M
Mr.doob 已提交
251 252 253 254

	setDefaultGLState();

	this.context = _gl;
M
Mr.doob 已提交
255
	this.capabilities = capabilities;
256
	this.extensions = extensions;
M
Mr.doob 已提交
257
	this.state = state;
M
Mr.doob 已提交
258

M
Mr.doob 已提交
259 260
	// shadow map

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

263
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
264

M
Mr.doob 已提交
265

M
Mr.doob 已提交
266 267 268 269 270
	// Plugins

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

M
Mr.doob 已提交
271 272 273 274 275 276 277 278
	// API

	this.getContext = function () {

		return _gl;

	};

279 280 281 282 283 284
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

285 286 287 288 289 290
	this.forceContextLoss = function () {

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

	};

291
	this.getMaxAnisotropy = ( function () {
M
Mr.doob 已提交
292

293
		var value;
M
Mr.doob 已提交
294

295
		return function getMaxAnisotropy() {
296

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

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

M
Mr.doob 已提交
301
			if ( extension !== null ) {
302

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

M
Mr.doob 已提交
305 306 307 308 309
			} else {

				value = 0;

			}
310 311 312 313 314 315

			return value;

		}

	} )();
M
Mr.doob 已提交
316 317 318

	this.getPrecision = function () {

G
gero3 已提交
319
		return capabilities.precision;
M
Mr.doob 已提交
320 321 322

	};

323 324 325 326 327 328 329 330
	this.getPixelRatio = function () {

		return pixelRatio;

	};

	this.setPixelRatio = function ( value ) {

331
		if ( value !== undefined ) pixelRatio = value;
332 333 334

	};

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

		return {
			width: _width,
			height: _height
		};

	};

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

346 347 348
		_width = width;
		_height = height;

349 350
		_canvas.width = width * pixelRatio;
		_canvas.height = height * pixelRatio;
351

352
		if ( updateStyle !== false ) {
353

G
gero3 已提交
354 355
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
356

G
gero3 已提交
357
		}
M
Mr.doob 已提交
358

359
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
360 361 362 363 364

	};

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

365 366
		_viewportX = x * pixelRatio;
		_viewportY = y * pixelRatio;
M
Mr.doob 已提交
367

368 369
		_viewportWidth = width * pixelRatio;
		_viewportHeight = height * pixelRatio;
M
Mr.doob 已提交
370 371 372 373 374

		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );

	};

M
Mr.doob 已提交
375 376 377 378 379 380 381 382 383 384
	this.getViewport = function ( dimensions ) {

		dimensions.x = _viewportX / pixelRatio;
		dimensions.y = _viewportY / pixelRatio;

		dimensions.z = _viewportWidth / pixelRatio;
		dimensions.w = _viewportHeight / pixelRatio;

	};

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

387
		_gl.scissor(
388 389 390 391
			x * pixelRatio,
			y * pixelRatio,
			width * pixelRatio,
			height * pixelRatio
392
		);
M
Mr.doob 已提交
393 394 395

	};

396
	this.enableScissorTest = function ( boolean ) {
M
Mr.doob 已提交
397

M
Mr.doob 已提交
398
		state.setScissorTest( boolean );
M
Mr.doob 已提交
399 400 401 402 403

	};

	// Clearing

M
Mr.doob 已提交
404
	this.getClearColor = function () {
M
Mr.doob 已提交
405

M
Mr.doob 已提交
406
		return _clearColor;
M
Mr.doob 已提交
407 408 409

	};

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

M
Mr.doob 已提交
412
		_clearColor.set( color );
413

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

416
		glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
M
Mr.doob 已提交
417 418 419

	};

M
Mr.doob 已提交
420
	this.getClearAlpha = function () {
M
Mr.doob 已提交
421

M
Mr.doob 已提交
422
		return _clearAlpha;
M
Mr.doob 已提交
423 424 425

	};

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

M
Mr.doob 已提交
428
		_clearAlpha = alpha;
M
Mr.doob 已提交
429

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

	};

	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 );
443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460

	};

	this.clearColor = function () {

		_gl.clear( _gl.COLOR_BUFFER_BIT );

	};

	this.clearDepth = function () {

		_gl.clear( _gl.DEPTH_BUFFER_BIT );

	};

	this.clearStencil = function () {

		_gl.clear( _gl.STENCIL_BUFFER_BIT );
M
Mr.doob 已提交
461 462 463 464 465 466 467 468 469 470

	};

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

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

	};

M
Mr.doob 已提交
471 472
	// Reset

473
	this.resetGLState = resetGLState;
M
Mr.doob 已提交
474

D
dubejf 已提交
475 476 477 478 479 480
	this.dispose = function() {

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

	};

M
Mr.doob 已提交
481
	// Events
M
Mr.doob 已提交
482

D
dubejf 已提交
483 484 485 486 487 488 489 490 491 492 493
	function onContextLost( event ) {

		event.preventDefault();

		resetGLState();
		setDefaultGLState();

		properties.clear();

	};

494
	function onTextureDispose( event ) {
M
Mr.doob 已提交
495 496 497 498 499 500 501

		var texture = event.target;

		texture.removeEventListener( 'dispose', onTextureDispose );

		deallocateTexture( texture );

502
		_infoMemory.textures --;
M
Mr.doob 已提交
503 504


505
	}
M
Mr.doob 已提交
506

507
	function onRenderTargetDispose( event ) {
M
Mr.doob 已提交
508 509 510 511 512 513 514

		var renderTarget = event.target;

		renderTarget.removeEventListener( 'dispose', onRenderTargetDispose );

		deallocateRenderTarget( renderTarget );

515
		_infoMemory.textures --;
M
Mr.doob 已提交
516

517
	}
M
Mr.doob 已提交
518

519
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
520 521 522 523 524 525 526

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

527
	}
M
Mr.doob 已提交
528 529 530

	// Buffer deallocation

531
	function deallocateTexture( texture ) {
M
Mr.doob 已提交
532

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

535
		if ( texture.image && textureProperties.__image__webglTextureCube ) {
M
Mr.doob 已提交
536 537 538

			// cube texture

539
			_gl.deleteTexture( textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
540

541 542 543 544
		} else {

			// 2D texture

545
			if ( textureProperties.__webglInit === undefined ) return;
546

547
			_gl.deleteTexture( textureProperties.__webglTexture );
548

M
Mr.doob 已提交
549 550
		}

551
		// remove all webgl properties
552
		properties.delete( texture );
553

554
	}
M
Mr.doob 已提交
555

556
	function deallocateRenderTarget( renderTarget ) {
M
Mr.doob 已提交
557

558
		var renderTargetProperties = properties.get( renderTarget );
M
Mr.doob 已提交
559
		var textureProperties = properties.get( renderTarget.texture );
M
Mr.doob 已提交
560

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

M
Mr.doob 已提交
563
		_gl.deleteTexture( textureProperties.__webglTexture );
M
Mr.doob 已提交
564

M
Mr.doob 已提交
565 566 567 568
		if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {

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

569 570
				_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );
				_gl.deleteRenderbuffer( renderTargetProperties.__webglRenderbuffer[ i ] );
M
Mr.doob 已提交
571 572 573 574 575

			}

		} else {

576 577
			_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );
			_gl.deleteRenderbuffer( renderTargetProperties.__webglRenderbuffer );
M
Mr.doob 已提交
578 579 580

		}

M
Mr.doob 已提交
581
		properties.delete( renderTarget.texture );
D
Daosheng Mu 已提交
582
		properties.delete( renderTarget );
M
Mr.doob 已提交
583

584
	}
M
Mr.doob 已提交
585

586
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
587

588 589 590 591
		releaseMaterialProgramReference( material );

		properties.delete( material );

592
	}
593 594


595
	function releaseMaterialProgramReference( material ) {
596

597
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
598 599 600

		material.program = undefined;

601
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
602

603
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
604

M
Mr.doob 已提交
605 606
		}

607
	}
M
Mr.doob 已提交
608 609 610 611 612

	// Buffer rendering

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

613
		state.initAttributes();
614

615
		var buffers = properties.get( object );
616

617 618 619 620
		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 已提交
621

622
		var attributes = program.getAttributes();
623

M
Mr.doob 已提交
624 625
		if ( object.hasPositions ) {

626
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
M
Mr.doob 已提交
627
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
628

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

		}

		if ( object.hasNormals ) {

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

638
			if ( material.type !== 'MeshPhongMaterial' && material.type !== 'MeshPhysicalMaterial' && material.shading === THREE.FlatShading ) {
M
Mr.doob 已提交
639

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

642
					var array = object.normalArray;
M
Mr.doob 已提交
643

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

648 649 650
					array[ i + 0 ] = nx;
					array[ i + 1 ] = ny;
					array[ i + 2 ] = nz;
M
Mr.doob 已提交
651

652 653 654
					array[ i + 3 ] = nx;
					array[ i + 4 ] = ny;
					array[ i + 5 ] = nz;
M
Mr.doob 已提交
655

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

				}

			}

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

666
			state.enableAttribute( attributes.normal );
667

668
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
669 670 671 672 673

		}

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

674
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
M
Mr.doob 已提交
675
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
676

677
			state.enableAttribute( attributes.uv );
678

679
			_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
680 681 682 683 684

		}

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

685
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
M
Mr.doob 已提交
686
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
687

688
			state.enableAttribute( attributes.color );
689

690
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
691 692 693

		}

694
		state.disableUnusedAttributes();
695

M
Mr.doob 已提交
696 697 698 699 700 701
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

702 703
	this.renderBufferDirect = function ( camera, lights, fog, geometry, material, object, group ) {

M
Mr.doob 已提交
704 705 706 707
		setMaterial( material );

		var program = setProgram( camera, lights, fog, material, object );

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

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

			}

			activeInfluences.sort( numericalSort );

			if ( activeInfluences.length > 8 ) {

				activeInfluences.length = 8;

			}

741 742
			var morphAttributes = geometry.morphAttributes;

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

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

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

750
					var index = influence[ 1 ];
M
Mr.doob 已提交
751

752 753
					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 已提交
754 755 756

				} else {

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

				}

			}

			var uniforms = program.getUniforms();

			if ( uniforms.morphTargetInfluences !== null ) {

				_gl.uniform1fv( uniforms.morphTargetInfluences, morphInfluences );

			}

			updateBuffers = true;

		}

M
Mr.doob 已提交
776 777
		//

778
		var index = geometry.index;
779 780
		var position = geometry.attributes.position;

781 782
		if ( material.wireframe === true ) {

783
			index = objects.getWireframeAttribute( geometry );
784 785 786

		}

787 788
		var renderer;

789
		if ( index !== null ) {
790

791 792
			renderer = indexedBufferRenderer;
			renderer.setIndex( index );
793

794
		} else {
795

796
			renderer = bufferRenderer;
797

798
		}
M
Mr.doob 已提交
799

800
		if ( updateBuffers ) {
M
Mr.doob 已提交
801

802
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
803

804
			if ( index !== null ) {
805

806
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );
807 808 809

			}

810
		}
811

M
Mr.doob 已提交
812
		//
813

M
Mr.doob 已提交
814 815
		var dataStart = 0;
		var dataCount = Infinity;
816

M
Mr.doob 已提交
817
		if ( index !== null ) {
818

M
Mr.doob 已提交
819
			dataCount = index.count
820

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

M
Mr.doob 已提交
823
			dataCount = position.count;
824

M
Mr.doob 已提交
825
		}
826

M
Mr.doob 已提交
827 828
		var rangeStart = geometry.drawRange.start;
		var rangeCount = geometry.drawRange.count;
829

M
Mr.doob 已提交
830 831
		var groupStart = group !== null ? group.start : 0;
		var groupCount = group !== null ? group.count : Infinity;
832

M
Mr.doob 已提交
833 834 835 836 837 838
		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 );

		//
839

840
		if ( object instanceof THREE.Mesh ) {
841

842
			if ( material.wireframe === true ) {
843

844 845
				state.setLineWidth( material.wireframeLinewidth * pixelRatio );
				renderer.setMode( _gl.LINES );
846

847
			} else {
848

849
				renderer.setMode( _gl.TRIANGLES );
850

851
			}
852

853
			if ( geometry instanceof THREE.InstancedBufferGeometry && geometry.maxInstancedCount > 0 ) {
854

855
				renderer.renderInstances( geometry );
856

857
			} else {
858

M
Mr.doob 已提交
859
				renderer.render( drawStart, drawCount );
860

861
			}
862

863
		} else if ( object instanceof THREE.Line ) {
864

865
			var lineWidth = material.linewidth;
866

867
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
868

869
			state.setLineWidth( lineWidth * pixelRatio );
870

871
			if ( object instanceof THREE.LineSegments ) {
872

873
				renderer.setMode( _gl.LINES );
874

875
			} else {
876

877
				renderer.setMode( _gl.LINE_STRIP );
878 879

			}
M
Mr.doob 已提交
880

M
Mr.doob 已提交
881
			renderer.render( drawStart, drawCount );
882

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

			renderer.setMode( _gl.POINTS );
M
Mr.doob 已提交
886
			renderer.render( drawStart, drawCount );
887

M
Mr.doob 已提交
888 889 890 891
		}

	};

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

M
Mr.doob 已提交
894
		var extension;
B
Ben Adams 已提交
895

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

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

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

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

M
Mr.doob 已提交
905 906 907
			}

		}
B
Ben Adams 已提交
908

909 910
		if ( startIndex === undefined ) startIndex = 0;

911 912
		state.initAttributes();

913
		var geometryAttributes = geometry.attributes;
914

915
		var programAttributes = program.getAttributes();
916

917
		var materialDefaultAttributeValues = material.defaultAttributeValues;
918

919
		for ( var name in programAttributes ) {
920

921
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
922

M
Mr.doob 已提交
923
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
924

925
				var geometryAttribute = geometryAttributes[ name ];
926

M
Mr.doob 已提交
927
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
928

929
					var size = geometryAttribute.itemSize;
G
gero3 已提交
930
					var buffer = objects.getAttributeBuffer( geometryAttribute );
931

B
Ben Adams 已提交
932
					if ( geometryAttribute instanceof THREE.InterleavedBufferAttribute ) {
933

M
Mr.doob 已提交
934 935 936 937 938
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

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

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

M
Mr.doob 已提交
942
							if ( geometry.maxInstancedCount === undefined ) {
943

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

M
Mr.doob 已提交
946
							}
B
Ben Adams 已提交
947

M
Mr.doob 已提交
948
						} else {
B
Ben Adams 已提交
949

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

M
Mr.doob 已提交
952
						}
B
Ben Adams 已提交
953

M
Mr.doob 已提交
954 955
						_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 已提交
956

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

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

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

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

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

M
Mr.doob 已提交
967
							}
B
Ben Adams 已提交
968

M
Mr.doob 已提交
969 970 971 972
						} else {

							state.enableAttribute( programAttribute );

M
Mr.doob 已提交
973
						}
B
Ben Adams 已提交
974

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

B
Ben Adams 已提交
978
					}
M
Mr.doob 已提交
979

980 981
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
982
					var value = materialDefaultAttributeValues[ name ];
983

984
					if ( value !== undefined ) {
M
Mr.doob 已提交
985

986
						switch ( value.length ) {
M
Mr.doob 已提交
987

988 989 990
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
991

992 993 994
							case 3:
								_gl.vertexAttrib3fv( programAttribute, value );
								break;
M
Mr.doob 已提交
995

996 997 998
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
999

1000 1001
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
1002 1003

						}
M
Mr.doob 已提交
1004 1005 1006 1007 1008 1009 1010 1011

					}

				}

			}

		}
1012

1013
		state.disableUnusedAttributes();
1014

M
Mr.doob 已提交
1015 1016
	}

M
Mr.doob 已提交
1017 1018
	// Sorting

1019 1020 1021 1022 1023 1024
	function numericalSort ( a, b ) {

		return b[ 0 ] - a[ 0 ];

	}

M
Mr.doob 已提交
1025 1026
	function painterSortStable ( a, b ) {

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

U
unconed 已提交
1029
			return a.object.renderOrder - b.object.renderOrder;
1030

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

M
Mr.doob 已提交
1033
			return a.material.id - b.material.id;
1034 1035

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

M
Mr.doob 已提交
1037
			return a.z - b.z;
M
Mr.doob 已提交
1038 1039 1040

		} else {

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

		}

1045
	}
M
Mr.doob 已提交
1046

1047 1048
	function reversePainterSortStable ( a, b ) {

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

U
unconed 已提交
1051
			return a.object.renderOrder - b.object.renderOrder;
1052 1053

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

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

		} else {

			return a.id - b.id;

		}

1063
	}
1064

M
Mr.doob 已提交
1065 1066 1067 1068 1069 1070
	// Rendering

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

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

1071
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1072 1073 1074 1075
			return;

		}

M
Mr.doob 已提交
1076
		var fog = scene.fog;
M
Mr.doob 已提交
1077 1078 1079

		// reset caching for this frame

1080
		_currentGeometryProgram = '';
1081
		_currentMaterialId = - 1;
1082
		_currentCamera = null;
M
Mr.doob 已提交
1083 1084 1085 1086
		_lightsNeedUpdate = true;

		// update scene graph

1087
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1088 1089 1090

		// update camera matrices and frustum

1091
		if ( camera.parent === null ) camera.updateMatrixWorld();
M
Mr.doob 已提交
1092 1093 1094 1095 1096 1097

		camera.matrixWorldInverse.getInverse( camera.matrixWorld );

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

M
Mr.doob 已提交
1098
		lights.length = 0;
1099

M
Mr.doob 已提交
1100 1101
		opaqueObjectsLastIndex = - 1;
		transparentObjectsLastIndex = - 1;
1102

M
Mr.doob 已提交
1103 1104 1105
		sprites.length = 0;
		lensFlares.length = 0;

1106
		projectObject( scene, camera );
M
Mr.doob 已提交
1107

1108 1109 1110
		opaqueObjects.length = opaqueObjectsLastIndex + 1;
		transparentObjects.length = transparentObjectsLastIndex + 1;

M
Mr.doob 已提交
1111
		if ( _this.sortObjects === true ) {
1112 1113 1114

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

1116 1117
		}

M
Mr.doob 已提交
1118
		//
M
Mr.doob 已提交
1119

M
Mr.doob 已提交
1120
		shadowMap.render( scene, camera );
M
Mr.doob 已提交
1121 1122 1123

		//

1124 1125 1126 1127
		_infoRender.calls = 0;
		_infoRender.vertices = 0;
		_infoRender.faces = 0;
		_infoRender.points = 0;
M
Mr.doob 已提交
1128 1129 1130 1131 1132 1133 1134 1135 1136

		this.setRenderTarget( renderTarget );

		if ( this.autoClear || forceClear ) {

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

		}

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

		if ( scene.overrideMaterial ) {

1141
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1142

1143 1144
			renderObjects( opaqueObjects, camera, lights, fog, overrideMaterial );
			renderObjects( transparentObjects, camera, lights, fog, overrideMaterial );
1145

M
Mr.doob 已提交
1146 1147 1148 1149
		} else {

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

M
Mr.doob 已提交
1150
			state.setBlending( THREE.NoBlending );
1151
			renderObjects( opaqueObjects, camera, lights, fog );
M
Mr.doob 已提交
1152 1153 1154

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

1155
			renderObjects( transparentObjects, camera, lights, fog );
M
Mr.doob 已提交
1156 1157 1158 1159 1160

		}

		// custom render plugins (post pass)

M
Mr.doob 已提交
1161 1162
		spritePlugin.render( scene, camera );
		lensFlarePlugin.render( scene, camera, _currentWidth, _currentHeight );
M
Mr.doob 已提交
1163 1164 1165

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

M
Mr.doob 已提交
1166 1167 1168
		if ( renderTarget ) {

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

M
Mr.doob 已提交
1170 1171 1172 1173 1174
			if ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&
					texture.minFilter !== THREE.NearestFilter &&
					texture.minFilter !== THREE.LinearFilter ) {

				updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1175 1176

			}
M
Mr.doob 已提交
1177 1178 1179 1180 1181

		}

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

M
Mr.doob 已提交
1182 1183
		state.setDepthTest( true );
		state.setDepthWrite( true );
1184
		state.setColorWrite( true );
M
Mr.doob 已提交
1185 1186 1187 1188

		// _gl.finish();

	};
M
Mr.doob 已提交
1189

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

1192
		var array, index;
M
Mr.doob 已提交
1193

1194
		// allocate the next position in the appropriate array
M
Mr.doob 已提交
1195 1196 1197

		if ( material.transparent ) {

1198 1199
			array = transparentObjects;
			index = ++ transparentObjectsLastIndex;
M
Mr.doob 已提交
1200 1201 1202

		} else {

1203 1204 1205 1206 1207
			array = opaqueObjects;
			index = ++ opaqueObjectsLastIndex;

		}

1208 1209
		// recycle existing render item or grow the array

1210 1211 1212 1213 1214 1215 1216 1217 1218 1219
		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 已提交
1220 1221 1222

		} else {

1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233
			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 已提交
1234 1235 1236 1237 1238

		}

	}

1239
	function projectObject( object, camera ) {
M
Mr.doob 已提交
1240

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

1243
		if ( object.layers.test( camera.layers ) ) {
M
Mr.doob 已提交
1244

1245
			if ( object instanceof THREE.Light ) {
M
Mr.doob 已提交
1246

1247
				lights.push( object );
M
Mr.doob 已提交
1248

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

1251 1252 1253 1254 1255
				if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) {

					sprites.push( object );

				}
M
Mr.doob 已提交
1256

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

1259
				lensFlares.push( object );
M
Mr.doob 已提交
1260

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

1263
				if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1264

1265 1266
					_vector3.setFromMatrixPosition( object.matrixWorld );
					_vector3.applyProjection( _projScreenMatrix );
M
Mr.doob 已提交
1267

1268
				}
1269

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

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

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

1276
					object.skeleton.update();
1277

1278
				}
1279

1280
				if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) {
1281

1282
					var material = object.material;
1283

1284
					if ( material.visible === true ) {
M
Mr.doob 已提交
1285

1286
						if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1287

1288 1289 1290 1291
							_vector3.setFromMatrixPosition( object.matrixWorld );
							_vector3.applyProjection( _projScreenMatrix );

						}
M
Mr.doob 已提交
1292

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

1295
						if ( material instanceof THREE.MeshFaceMaterial ) {
1296

1297 1298
							var groups = geometry.groups;
							var materials = material.materials;
1299

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

1302 1303
								var group = groups[ i ];
								var groupMaterial = materials[ group.materialIndex ];
1304

1305
								if ( groupMaterial.visible === true ) {
1306

1307 1308 1309
									pushRenderItem( object, geometry, groupMaterial, _vector3.z, group );

								}
M
Mr.doob 已提交
1310

M
Mr.doob 已提交
1311
							}
M
Mr.doob 已提交
1312

1313
						} else {
M
Mr.doob 已提交
1314

1315
							pushRenderItem( object, geometry, material, _vector3.z, null );
1316

1317
						}
O
OpenShift guest 已提交
1318

1319
					}
M
Mr.doob 已提交
1320

1321
				}
M
Mr.doob 已提交
1322

1323
			}
M
Mr.doob 已提交
1324

M
Mr.doob 已提交
1325
		}
M
Mr.doob 已提交
1326

M
Mr.doob 已提交
1327
		var children = object.children;
M
Mr.doob 已提交
1328

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

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

1333
		}
1334

1335
	}
M
Mr.doob 已提交
1336

1337
	function renderObjects( renderList, camera, lights, fog, overrideMaterial ) {
M
Mr.doob 已提交
1338

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

1341
			var renderItem = renderList[ i ];
M
Mr.doob 已提交
1342

1343
			var object = renderItem.object;
M
Mr.doob 已提交
1344 1345 1346
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
M
Mr.doob 已提交
1347

1348 1349
			object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
			object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
M
Mr.doob 已提交
1350

M
Mr.doob 已提交
1351
			if ( object instanceof THREE.ImmediateRenderObject ) {
M
Mr.doob 已提交
1352

M
Mr.doob 已提交
1353
				setMaterial( material );
M
Mr.doob 已提交
1354

M
Mr.doob 已提交
1355
				var program = setProgram( camera, lights, fog, material, object );
M
Mr.doob 已提交
1356

M
Mr.doob 已提交
1357
				_currentGeometryProgram = '';
M
Mr.doob 已提交
1358

M
Mr.doob 已提交
1359
				object.render( function ( object ) {
M
Mr.doob 已提交
1360

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

M
Mr.doob 已提交
1363
				} );
1364

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

M
Mr.doob 已提交
1367
				_this.renderBufferDirect( camera, lights, fog, geometry, material, object, group );
M
Mr.doob 已提交
1368

M
Mr.doob 已提交
1369
			}
M
Mr.doob 已提交
1370

1371
		}
M
Mr.doob 已提交
1372

1373
	}
G
gero3 已提交
1374

1375
	function initMaterial( material, lights, fog, object ) {
M
Mr.doob 已提交
1376

1377
		var materialProperties = properties.get( material );
G
gero3 已提交
1378 1379

		var parameters = programCache.getParameters( material, lights, fog, object );
G
gero3 已提交
1380
		var code = programCache.getProgramCode( material, parameters );
G
gero3 已提交
1381

1382
		var program = materialProperties.program;
T
tschw 已提交
1383
		var programChange = true;
1384

1385
		if ( program === undefined ) {
B
Ben Adams 已提交
1386

M
Mr.doob 已提交
1387 1388
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1389

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

M
Mr.doob 已提交
1392
			// changed glsl or parameters
1393
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1394

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

T
tschw 已提交
1397
			// same glsl and uniform list
T
tschw 已提交
1398 1399
			return;

T
tschw 已提交
1400
		} else {
B
Ben Adams 已提交
1401

T
tschw 已提交
1402 1403
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1404 1405 1406

		}

1407
		if ( programChange ) {
B
Ben Adams 已提交
1408

1409
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1410

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

1413 1414 1415 1416 1417 1418
				materialProperties.__webglShader = {
					name: material.type,
					uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
					vertexShader: shader.vertexShader,
					fragmentShader: shader.fragmentShader
				};
B
Ben Adams 已提交
1419

1420
			} else {
B
Ben Adams 已提交
1421

1422 1423 1424 1425 1426 1427
				materialProperties.__webglShader = {
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
					fragmentShader: material.fragmentShader
				};
G
gero3 已提交
1428

1429
			}
G
gero3 已提交
1430

1431
			material.__webglShader = materialProperties.__webglShader;
G
gero3 已提交
1432

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

1435 1436
			materialProperties.program = program;
			material.program = program;
1437 1438 1439

		}

1440
		var attributes = program.getAttributes();
M
Mr.doob 已提交
1441 1442 1443 1444 1445

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

M
Mr.doob 已提交
1448
				if ( attributes[ 'morphTarget' + i ] >= 0 ) {
M
Mr.doob 已提交
1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

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

					material.numSupportedMorphNormals ++;

				}

			}

		}

1474
		materialProperties.uniformsList = [];
M
Mr.doob 已提交
1475

1476 1477
		var uniforms = materialProperties.__webglShader.uniforms,
			uniformLocations = materialProperties.program.getUniforms();
M
Mr.doob 已提交
1478

1479
		for ( var u in uniforms ) {
M
Mr.doob 已提交
1480

1481
			var location = uniformLocations[ u ];
1482 1483

			if ( location ) {
G
gero3 已提交
1484

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

1487
			}
M
Mr.doob 已提交
1488 1489 1490

		}

1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505
		if ( material instanceof THREE.MeshPhongMaterial ||
				material instanceof THREE.MeshLambertMaterial ||
				material instanceof THREE.MeshPhysicalMaterial ||
				material.lights ) {

			// wire up the material to this renderer's lighting state

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

		}

M
Mr.doob 已提交
1506
	}
M
Mr.doob 已提交
1507

1508 1509
	function setMaterial( material ) {

M
Mr.doob 已提交
1510 1511
		setMaterialFaces( material );

1512 1513
		if ( material.transparent === true ) {

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

1516 1517 1518 1519
		} else {

			state.setBlending( THREE.NoBlending );

1520 1521
		}

B
Ben Adams 已提交
1522
		state.setDepthFunc( material.depthFunc );
M
Mr.doob 已提交
1523 1524
		state.setDepthTest( material.depthTest );
		state.setDepthWrite( material.depthWrite );
1525
		state.setColorWrite( material.colorWrite );
M
Mr.doob 已提交
1526
		state.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
1527 1528 1529

	}

M
Mr.doob 已提交
1530 1531
	function setMaterialFaces( material ) {

1532
		material.side !== THREE.DoubleSide ? state.enable( _gl.CULL_FACE ) : state.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
1533 1534 1535 1536
		state.setFlipSided( material.side === THREE.BackSide );

	}

M
Mr.doob 已提交
1537 1538 1539 1540
	function setProgram( camera, lights, fog, material, object ) {

		_usedTextureUnits = 0;

1541
		var materialProperties = properties.get( material );
1542

1543
		if ( material.needsUpdate || ! materialProperties.program ) {
M
Mr.doob 已提交
1544

1545
			initMaterial( material, lights, fog, object );
M
Mr.doob 已提交
1546 1547 1548 1549
			material.needsUpdate = false;

		}

1550
		var refreshProgram = false;
M
Mr.doob 已提交
1551
		var refreshMaterial = false;
1552
		var refreshLights = false;
M
Mr.doob 已提交
1553

1554
		var program = materialProperties.program,
1555
			p_uniforms = program.getUniforms(),
1556
			m_uniforms = materialProperties.__webglShader.uniforms;
M
Mr.doob 已提交
1557

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

1560 1561
			_gl.useProgram( program.program );
			_currentProgram = program.id;
M
Mr.doob 已提交
1562

1563
			refreshProgram = true;
M
Mr.doob 已提交
1564
			refreshMaterial = true;
1565
			refreshLights = true;
M
Mr.doob 已提交
1566 1567 1568 1569 1570 1571

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1572

M
Mr.doob 已提交
1573 1574 1575 1576
			refreshMaterial = true;

		}

1577
		if ( refreshProgram || camera !== _currentCamera ) {
M
Mr.doob 已提交
1578 1579 1580

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

G
gero3 已提交
1581
			if ( capabilities.logarithmicDepthBuffer ) {
1582

1583
				_gl.uniform1f( p_uniforms.logDepthBufFC, 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1584 1585 1586 1587

			}


1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599
			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
				_lightsNeedUpdate = true;	// remains set until update done

			}
M
Mr.doob 已提交
1600

1601 1602 1603 1604 1605
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
1606
				 material instanceof THREE.MeshPhysicalMaterial ||
1607 1608
				 material.envMap ) {

1609
				if ( p_uniforms.cameraPosition !== undefined ) {
1610 1611 1612 1613 1614 1615 1616 1617 1618 1619

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

				}

			}

			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
1620
				 material instanceof THREE.MeshBasicMaterial ||
1621
				 material instanceof THREE.MeshPhysicalMaterial ||
1622 1623 1624
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {

1625
				if ( p_uniforms.viewMatrix !== undefined ) {
1626 1627

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

1629 1630 1631 1632
				}

			}

M
Mr.doob 已提交
1633 1634 1635 1636 1637 1638 1639 1640
		}

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

1641
			if ( object.bindMatrix && p_uniforms.bindMatrix !== undefined ) {
1642 1643 1644 1645 1646

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

			}

1647
			if ( object.bindMatrixInverse && p_uniforms.bindMatrixInverse !== undefined ) {
1648 1649 1650 1651 1652

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

			}

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

1655
				if ( p_uniforms.boneTexture !== undefined ) {
M
Mr.doob 已提交
1656 1657 1658 1659

					var textureUnit = getTextureUnit();

					_gl.uniform1i( p_uniforms.boneTexture, textureUnit );
1660
					_this.setTexture( object.skeleton.boneTexture, textureUnit );
M
Mr.doob 已提交
1661 1662 1663

				}

1664
				if ( p_uniforms.boneTextureWidth !== undefined ) {
1665

1666
					_gl.uniform1i( p_uniforms.boneTextureWidth, object.skeleton.boneTextureWidth );
1667 1668 1669

				}

1670
				if ( p_uniforms.boneTextureHeight !== undefined ) {
1671

1672
					_gl.uniform1i( p_uniforms.boneTextureHeight, object.skeleton.boneTextureHeight );
1673 1674 1675

				}

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

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

1680
					_gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.skeleton.boneMatrices );
M
Mr.doob 已提交
1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699

				}

			}

		}

		if ( refreshMaterial ) {

			// refresh uniforms common to several materials

			if ( fog && material.fog ) {

				refreshUniformsFog( m_uniforms, fog );

			}

			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
1700
				 material instanceof THREE.MeshPhysicalMaterial ||
M
Mr.doob 已提交
1701 1702
				 material.lights ) {

1703
				// the current material requires lighting info
M
Mr.doob 已提交
1704

1705 1706 1707
				// if we haven't done so since the start of the frame, after a
				// reset or camera change, update the lighting uniforms values
				// of all materials (by reference)
G
gero3 已提交
1708

1709
				if ( _lightsNeedUpdate ) {
M
Mr.doob 已提交
1710

1711
					_lightsNeedUpdate = false;
G
gero3 已提交
1712

1713 1714
					setupLights( lights, camera );
					refreshLights = true;
G
gero3 已提交
1715

1716
				}
G
gero3 已提交
1717

1718 1719
				// use the current material's .needsUpdate flags to set
				// the GL state when required
G
gero3 已提交
1720

1721
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
M
Mr.doob 已提交
1722 1723 1724 1725 1726

			}

			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
W
WestLangley 已提交
1727
				 material instanceof THREE.MeshPhongMaterial ||
1728
				 material instanceof THREE.MeshPhysicalMaterial ) {
M
Mr.doob 已提交
1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744

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

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

M
Mr.doob 已提交
1747
				refreshUniformsPoints( m_uniforms, material );
M
Mr.doob 已提交
1748 1749 1750 1751 1752

			} else if ( material instanceof THREE.MeshPhongMaterial ) {

				refreshUniformsPhong( m_uniforms, material );

1753
			} else if ( material instanceof THREE.MeshPhysicalMaterial ) {
W
WestLangley 已提交
1754 1755 1756

				refreshUniformsStandard( m_uniforms, material );

M
Mr.doob 已提交
1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768
			} else if ( material instanceof THREE.MeshDepthMaterial ) {

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

			} else if ( material instanceof THREE.MeshNormalMaterial ) {

				m_uniforms.opacity.value = material.opacity;

			}

M
Mr.doob 已提交
1769
			if ( shadowMap.enabled ) {
M
Mr.doob 已提交
1770

1771 1772 1773 1774 1775
				if ( object.receiveShadow && ! material._shadowPass ) {

					refreshUniformsShadow( m_uniforms, lights, camera );

				}
M
Mr.doob 已提交
1776 1777 1778 1779 1780

			}

			// load common uniforms

1781
			loadUniformsGeneric( materialProperties.uniformsList );
M
Mr.doob 已提交
1782 1783 1784 1785 1786

		}

		loadUniformsMatrices( p_uniforms, object );

1787
		if ( p_uniforms.modelMatrix !== undefined ) {
M
Mr.doob 已提交
1788 1789

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

M
Mr.doob 已提交
1791 1792 1793 1794
		}

		return program;

M
Mr.doob 已提交
1795
	}
M
Mr.doob 已提交
1796 1797 1798 1799 1800 1801 1802

	// Uniforms (refresh uniforms objects)

	function refreshUniformsCommon ( uniforms, material ) {

		uniforms.opacity.value = material.opacity;

1803
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
1804

1805
		if ( material.emissive ) {
M
Mr.doob 已提交
1806

1807
			uniforms.emissive.value = material.emissive;
M
Mr.doob 已提交
1808 1809 1810

		}

1811 1812 1813
		uniforms.map.value = material.map;
		uniforms.specularMap.value = material.specularMap;
		uniforms.alphaMap.value = material.alphaMap;
M
Mr.doob 已提交
1814

1815
		if ( material.aoMap ) {
1816

1817 1818
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1819 1820 1821

		}

M
Mr.doob 已提交
1822
		// uv repeat and offset setting priorities
M
Mr.doob 已提交
1823 1824 1825 1826 1827
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
1828
		// 6. emissive map
M
Mr.doob 已提交
1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

1840 1841 1842 1843
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
1844 1845 1846 1847 1848 1849 1850 1851
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

1852 1853 1854 1855
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

1856 1857 1858 1859
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
1860 1861 1862 1863
		}

		if ( uvScaleMap !== undefined ) {

M
Mr.doob 已提交
1864
			if ( uvScaleMap instanceof THREE.WebGLRenderTarget ) uvScaleMap = uvScaleMap.texture;
M
Mr.doob 已提交
1865 1866 1867 1868 1869 1870 1871 1872
			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;
1873
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : - 1;
M
Mr.doob 已提交
1874

1875
		uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
1876 1877
		uniforms.refractionRatio.value = material.refractionRatio;

M
Mr.doob 已提交
1878
	}
M
Mr.doob 已提交
1879 1880 1881 1882 1883 1884

	function refreshUniformsLine ( uniforms, material ) {

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

M
Mr.doob 已提交
1885
	}
M
Mr.doob 已提交
1886 1887 1888 1889 1890 1891 1892

	function refreshUniformsDash ( uniforms, material ) {

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

M
Mr.doob 已提交
1893
	}
M
Mr.doob 已提交
1894

M
Mr.doob 已提交
1895
	function refreshUniformsPoints ( uniforms, material ) {
M
Mr.doob 已提交
1896 1897 1898

		uniforms.psColor.value = material.color;
		uniforms.opacity.value = material.opacity;
1899
		uniforms.size.value = material.size * pixelRatio;
M
Mr.doob 已提交
1900 1901 1902 1903
		uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.

		uniforms.map.value = material.map;

1904 1905 1906 1907 1908 1909 1910 1911 1912
		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 已提交
1913
	}
M
Mr.doob 已提交
1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929

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

	function refreshUniformsPhong ( uniforms, material ) {

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

1937 1938 1939 1940
		if ( material.lightMap ) {

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

1942
		}
1943

1944
		if ( material.emissiveMap ) {
1945

1946
			uniforms.emissiveMap.value = material.emissiveMap;
1947

1948
		}
M
Mr.doob 已提交
1949

1950 1951 1952 1953
		if ( material.bumpMap ) {

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

1955
		}
M
Mr.doob 已提交
1956

1957 1958 1959 1960 1961 1962
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
1963

1964 1965 1966 1967 1968
		if ( material.displacementMap ) {

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

1970
		}
1971 1972 1973

	}

W
WestLangley 已提交
1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041
	function refreshUniformsStandard ( uniforms, material ) {

		uniforms.roughness.value = material.roughness;
		//uniforms.reflectivity.value = material.reflectivity; // part of uniforms common
		uniforms.metalness.value = material.metalness;

		if ( material.roughnessMap ) {

			uniforms.roughnessMap.value = material.roughnessMap;

		}

		if ( material.reflectivityMap ) {

			uniforms.reflectivityMap.value = material.reflectivityMap;

		}

		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;

		}

	}

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

M
Mr.doob 已提交
2044
	function markUniformsLightsNeedsUpdate ( uniforms, value ) {
2045

M
Mr.doob 已提交
2046
		uniforms.ambientLightColor.needsUpdate = value;
2047

B
Ben Houston 已提交
2048 2049 2050 2051
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
		uniforms.hemisphereLights.needsUpdate = value;
2052

M
Mr.doob 已提交
2053
	}
2054

M
Mr.doob 已提交
2055
	function refreshUniformsShadow ( uniforms, lights, camera ) {
M
Mr.doob 已提交
2056 2057 2058 2059 2060 2061 2062 2063 2064

		if ( uniforms.shadowMatrix ) {

			var j = 0;

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

				var light = lights[ i ];

M
Mr.doob 已提交
2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081
				if ( light.castShadow === true ) {

					if ( light instanceof THREE.PointLight || light instanceof THREE.SpotLight || light instanceof THREE.DirectionalLight ) {

						var shadow = light.shadow;

						if ( light instanceof THREE.PointLight ) {

							// for point lights we set the shadow matrix to be a translation-only matrix
							// equal to inverse of the light's position
							_vector3.setFromMatrixPosition( light.matrixWorld ).negate();
							shadow.matrix.identity().setPosition( _vector3 );

							// for point lights we set the sign of the shadowDarkness uniform to be negative
							uniforms.shadowDarkness.value[ j ] = - shadow.darkness;

						} else {
M
Mr.doob 已提交
2082

M
Mr.doob 已提交
2083
							uniforms.shadowDarkness.value[ j ] = shadow.darkness;
M
Mr.doob 已提交
2084

M
Mr.doob 已提交
2085
						}
M
Mr.doob 已提交
2086

M
Mr.doob 已提交
2087 2088 2089 2090
						uniforms.shadowMatrix.value[ j ] = shadow.matrix;
						uniforms.shadowMap.value[ j ] = shadow.map;
						uniforms.shadowMapSize.value[ j ] = shadow.mapSize;
						uniforms.shadowBias.value[ j ] = shadow.bias;
M
Mr.doob 已提交
2091

M
Mr.doob 已提交
2092
						j ++;
M
Mr.doob 已提交
2093

M
Mr.doob 已提交
2094
					}
M
Mr.doob 已提交
2095 2096 2097 2098 2099 2100 2101

				}

			}

		}

M
Mr.doob 已提交
2102
	}
M
Mr.doob 已提交
2103 2104 2105 2106 2107

	// Uniforms (load to GPU)

	function loadUniformsMatrices ( uniforms, object ) {

2108
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object.modelViewMatrix.elements );
M
Mr.doob 已提交
2109 2110 2111

		if ( uniforms.normalMatrix ) {

2112
			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object.normalMatrix.elements );
M
Mr.doob 已提交
2113 2114 2115

		}

M
Mr.doob 已提交
2116
	}
M
Mr.doob 已提交
2117 2118 2119 2120 2121

	function getTextureUnit() {

		var textureUnit = _usedTextureUnits;

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

G
gero3 已提交
2124
			console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
M
Mr.doob 已提交
2125 2126 2127 2128 2129 2130 2131

		}

		_usedTextureUnits += 1;

		return textureUnit;

M
Mr.doob 已提交
2132
	}
M
Mr.doob 已提交
2133

2134
	function loadUniformsGeneric ( uniforms ) {
M
Mr.doob 已提交
2135

M
Mr.doob 已提交
2136
		var texture, textureUnit;
M
Mr.doob 已提交
2137

M
Mr.doob 已提交
2138 2139 2140
		for ( var j = 0, jl = uniforms.length; j < jl; j ++ ) {

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

2142 2143
			// needsUpdate property is not added to all uniforms.
			if ( uniform.needsUpdate === false ) continue;
2144

M
Mr.doob 已提交
2145 2146
			var type = uniform.type;
			var value = uniform.value;
2147
			var location = uniforms[ j ][ 1 ];
M
Mr.doob 已提交
2148

2149
			switch ( type ) {
M
Mr.doob 已提交
2150

2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204
				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;

				case 'Matrix3fv':
					_gl.uniformMatrix3fv( location, false, value );
					break;

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

				//

M
Mr.doob 已提交
2205
				case 'i':
M
Mr.doob 已提交
2206

2207 2208
					// single integer
					_gl.uniform1i( location, value );
M
Mr.doob 已提交
2209

2210
					break;
M
Mr.doob 已提交
2211

2212
				case 'f':
M
Mr.doob 已提交
2213

2214 2215
					// single float
					_gl.uniform1f( location, value );
M
Mr.doob 已提交
2216

2217
					break;
M
Mr.doob 已提交
2218

2219
				case 'v2':
M
Mr.doob 已提交
2220

2221 2222
					// single THREE.Vector2
					_gl.uniform2f( location, value.x, value.y );
M
Mr.doob 已提交
2223

2224
					break;
M
Mr.doob 已提交
2225

2226
				case 'v3':
M
Mr.doob 已提交
2227

2228 2229
					// single THREE.Vector3
					_gl.uniform3f( location, value.x, value.y, value.z );
M
Mr.doob 已提交
2230

2231
					break;
M
Mr.doob 已提交
2232

M
Mr.doob 已提交
2233
				case 'v4':
M
Mr.doob 已提交
2234

2235 2236
					// single THREE.Vector4
					_gl.uniform4f( location, value.x, value.y, value.z, value.w );
M
Mr.doob 已提交
2237

2238
					break;
M
Mr.doob 已提交
2239

2240
				case 'c':
M
Mr.doob 已提交
2241

2242 2243
					// single THREE.Color
					_gl.uniform3f( location, value.r, value.g, value.b );
M
Mr.doob 已提交
2244

2245
					break;
M
Mr.doob 已提交
2246

2247 2248 2249
				case 's':

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

B
Ben Houston 已提交
2252 2253 2254
						var property = uniform.properties[ propertyName ];
						var locationProperty =  location[ propertyName ];
						var valueProperty = value[ propertyName ];
M
Mr.doob 已提交
2255

2256 2257
						switch( property.type ) {
							case 'f':
B
Ben Houston 已提交
2258
								_gl.uniform1f( locationProperty, valueProperty );
2259 2260
								break;
							case 'v2':
B
Ben Houston 已提交
2261
								_gl.uniform2f( locationProperty, valueProperty.x, valueProperty.y );
2262 2263
								break;
							case 'v3':
B
Ben Houston 已提交
2264
								_gl.uniform3f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z );
2265 2266
								break;
							case 'v4':
B
Ben Houston 已提交
2267
								_gl.uniform4f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w );
2268 2269
								break;
							case 'c':
B
Ben Houston 已提交
2270
								_gl.uniform3f( locationProperty, valueProperty.r, valueProperty.g, valueProperty.b );
2271 2272
								break;
						};
2273 2274 2275 2276 2277

					}

					break;

2278
				case 'sa':
2279

2280
					// TODO: Optimize this.
2281 2282
					for( var i = 0; i < value.length; i ++ ) {

B
Ben Houston 已提交
2283
						for( var propertyName in uniform.properties ) {
M
Mr.doob 已提交
2284

B
Ben Houston 已提交
2285 2286 2287
							var property = uniform.properties[ propertyName ];
							var locationProperty =  location[ i ][ propertyName ];
							var valueProperty = value[i][ propertyName ];
M
Mr.doob 已提交
2288

2289 2290
							switch( property.type ) {
								case 'f':
B
Ben Houston 已提交
2291
									_gl.uniform1f( locationProperty, valueProperty );
2292 2293
									break;
								case 'v2':
B
Ben Houston 已提交
2294
									_gl.uniform2f( locationProperty, valueProperty.x, valueProperty.y );
2295 2296
									break;
								case 'v3':
B
Ben Houston 已提交
2297
									_gl.uniform3f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z );
2298 2299
									break;
								case 'v4':
B
Ben Houston 已提交
2300
									_gl.uniform4f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w );
2301 2302
									break;
								case 'c':
B
Ben Houston 已提交
2303
									_gl.uniform3f( locationProperty, valueProperty.r, valueProperty.g, valueProperty.b );
2304 2305
									break;
							};
2306

2307
						}
2308 2309

					}
M
Mr.doob 已提交
2310

2311 2312
					break;

2313
				case 'iv1':
M
Mr.doob 已提交
2314

2315 2316
					// flat array of integers (JS or typed array)
					_gl.uniform1iv( location, value );
M
Mr.doob 已提交
2317

2318
					break;
M
Mr.doob 已提交
2319

2320
				case 'iv':
M
Mr.doob 已提交
2321

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

2325
					break;
M
Mr.doob 已提交
2326

2327
				case 'fv1':
M
Mr.doob 已提交
2328

2329 2330
					// flat array of floats (JS or typed array)
					_gl.uniform1fv( location, value );
M
Mr.doob 已提交
2331

2332
					break;
M
Mr.doob 已提交
2333

2334
				case 'fv':
M
Mr.doob 已提交
2335

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

2339
					break;
M
Mr.doob 已提交
2340

2341
				case 'v2v':
M
Mr.doob 已提交
2342

2343
					// array of THREE.Vector2
M
Mr.doob 已提交
2344

2345
					if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2346

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

2349
					}
M
Mr.doob 已提交
2350

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

M
Mr.doob 已提交
2353 2354
						uniform._array[ i2 + 0 ] = value[ i ].x;
						uniform._array[ i2 + 1 ] = value[ i ].y;
M
Mr.doob 已提交
2355

2356
					}
M
Mr.doob 已提交
2357

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

2360
					break;
M
Mr.doob 已提交
2361

2362
				case 'v3v':
M
Mr.doob 已提交
2363

2364
					// array of THREE.Vector3
M
Mr.doob 已提交
2365

2366
					if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2367

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

2370
					}
M
Mr.doob 已提交
2371

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

M
Mr.doob 已提交
2374 2375 2376
						uniform._array[ i3 + 0 ] = value[ i ].x;
						uniform._array[ i3 + 1 ] = value[ i ].y;
						uniform._array[ i3 + 2 ] = value[ i ].z;
R
Ryan Tsao 已提交
2377

2378
					}
R
Ryan Tsao 已提交
2379

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

2382
					break;
R
Ryan Tsao 已提交
2383

2384
				case 'v4v':
R
Ryan Tsao 已提交
2385

2386
					// array of THREE.Vector4
R
Ryan Tsao 已提交
2387

2388
					if ( uniform._array === undefined ) {
R
Ryan Tsao 已提交
2389

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

2392
					}
M
Mr.doob 已提交
2393

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

M
Mr.doob 已提交
2396 2397 2398 2399
						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 已提交
2400

2401
					}
M
Mr.doob 已提交
2402

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

2405
					break;
M
Mr.doob 已提交
2406

2407
				case 'm3':
M
Mr.doob 已提交
2408

2409 2410
					// single THREE.Matrix3
					_gl.uniformMatrix3fv( location, false, value.elements );
M
Mr.doob 已提交
2411

2412
					break;
M
Mr.doob 已提交
2413

2414
				case 'm3v':
M
Mr.doob 已提交
2415

2416
					// array of THREE.Matrix3
M
Mr.doob 已提交
2417

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

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

2422
					}
M
Mr.doob 已提交
2423

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

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

2428
					}
M
Mr.doob 已提交
2429

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

2432
					break;
M
Mr.doob 已提交
2433

2434
				case 'm4':
M
Mr.doob 已提交
2435

2436 2437
					// single THREE.Matrix4
					_gl.uniformMatrix4fv( location, false, value.elements );
M
Mr.doob 已提交
2438

2439
					break;
M
Mr.doob 已提交
2440

2441
				case 'm4v':
M
Mr.doob 已提交
2442

2443
					// array of THREE.Matrix4
M
Mr.doob 已提交
2444

2445
					if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2446

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

2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459
					}

					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 已提交
2460

2461
				case 't':
M
Mr.doob 已提交
2462

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

2465 2466 2467 2468
					texture = value;
					textureUnit = getTextureUnit();

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

2470
					if ( ! texture ) continue;
M
Mr.doob 已提交
2471

2472
					if ( texture instanceof THREE.CubeTexture ||
G
gero3 已提交
2473 2474 2475
						 ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {

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

2477
						setCubeTexture( texture, textureUnit );
M
Mr.doob 已提交
2478

2479 2480
					} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {

M
Mr.doob 已提交
2481 2482 2483 2484 2485
						setCubeTextureDynamic( texture.texture, textureUnit );

					} else if ( texture instanceof THREE.WebGLRenderTarget ) {

						_this.setTexture( texture.texture, textureUnit );
2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496

					} else {

						_this.setTexture( texture, textureUnit );

					}

					break;

				case 'tv':

M
Mr.doob 已提交
2497
					// array of THREE.Texture (2d or cube)
2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519

					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 已提交
2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539
						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 );

						}
2540 2541 2542 2543 2544 2545

					}

					break;

				default:
2546

2547
					console.warn( 'THREE.WebGLRenderer: Unknown uniform type: ' + type );
2548

M
Mr.doob 已提交
2549 2550 2551 2552
			}

		}

M
Mr.doob 已提交
2553
	}
M
Mr.doob 已提交
2554

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

B
brason 已提交
2557
		var l, ll, light,
M
Mr.doob 已提交
2558
		r = 0, g = 0, b = 0,
B
Ben Houston 已提交
2559
		color,
B
brason 已提交
2560
		intensity,
M
Mr.doob 已提交
2561 2562
		distance,

2563
		viewMatrix = camera.matrixWorldInverse,
M
Mr.doob 已提交
2564

2565 2566 2567 2568
		writeIndexDirectional = 0,
		writeIndexPoint = 0,
		writeIndexSpot = 0,
		writeIndexHemi = 0;
M
Mr.doob 已提交
2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579

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

2580 2581 2582
				r += color.r;
				g += color.g;
				b += color.b;
M
Mr.doob 已提交
2583 2584 2585

			} else if ( light instanceof THREE.DirectionalLight ) {

B
Ben Houston 已提交
2586 2587
				if( ! light.__webglUniforms ) {
					light.__webglUniforms = {
B
Ben Houston 已提交
2588 2589
						direction: new THREE.Vector3(),
						color: new THREE.Color()
B
Ben Houston 已提交
2590 2591
					}
				}
M
Mr.doob 已提交
2592

B
Ben Houston 已提交
2593
				var lightUniforms = light.__webglUniforms;
M
Mr.doob 已提交
2594
				_lights.directional[ writeIndexDirectional ++ ] = lightUniforms;
M
Mr.doob 已提交
2595

2596
				lightUniforms.direction.setFromMatrixPosition( light.matrixWorld );
2597
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
2598 2599
				lightUniforms.direction.sub( _vector3 );
				lightUniforms.direction.transformDirection( viewMatrix );
M
Mr.doob 已提交
2600

B
Ben Houston 已提交
2601
				lightUniforms.color.copy( light.color ).multiplyScalar( light.intensity );
M
Mr.doob 已提交
2602 2603 2604

			} else if ( light instanceof THREE.PointLight ) {

B
Ben Houston 已提交
2605 2606 2607 2608 2609 2610 2611 2612
				if( ! light.__webglUniforms ) {
					light.__webglUniforms = {
						position: new THREE.Vector3(),
						color: new THREE.Color(),
						distance: 0,
						decay: 0
					}
				}
M
Mr.doob 已提交
2613

B
Ben Houston 已提交
2614
				var lightUniforms = light.__webglUniforms;
M
Mr.doob 已提交
2615
				_lights.point[ writeIndexPoint ++ ] = lightUniforms;
M
Mr.doob 已提交
2616

2617 2618
				lightUniforms.position.setFromMatrixPosition( light.matrixWorld );
				lightUniforms.position.applyMatrix4( viewMatrix );
M
Mr.doob 已提交
2619

B
Ben Houston 已提交
2620 2621
				lightUniforms.color.copy( light.color ).multiplyScalar( light.intensity );
				lightUniforms.distance = light.distance;
B
Ben Houston 已提交
2622
				lightUniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
M
Mr.doob 已提交
2623 2624 2625

			} else if ( light instanceof THREE.SpotLight ) {

B
Ben Houston 已提交
2626 2627 2628 2629 2630 2631 2632 2633 2634 2635
				if( ! light.__webglUniforms ) {
					light.__webglUniforms = {
						position: new THREE.Vector3(),
						direction: new THREE.Vector3(),
						color: new THREE.Color(),
						distance: 0,
						decay: 0,
						angleCos: 0
					}
				}
M
Mr.doob 已提交
2636

B
Ben Houston 已提交
2637
				var lightUniforms = light.__webglUniforms;
M
Mr.doob 已提交
2638
				_lights.spot[ writeIndexSpot ++ ] = lightUniforms;
M
Mr.doob 已提交
2639

2640 2641
				lightUniforms.position.setFromMatrixPosition( light.matrixWorld );
				lightUniforms.position.applyMatrix4( viewMatrix );
M
Mr.doob 已提交
2642

B
Ben Houston 已提交
2643 2644
				lightUniforms.color.copy( color ).multiplyScalar( intensity );
				lightUniforms.distance = distance;
M
Mr.doob 已提交
2645

2646
				lightUniforms.direction.setFromMatrixPosition( light.matrixWorld );
2647
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
2648 2649
				lightUniforms.direction.sub( _vector3 );
				lightUniforms.direction.transformDirection( viewMatrix );
M
Mr.doob 已提交
2650

B
Ben Houston 已提交
2651 2652 2653
				lightUniforms.angleCos = Math.cos( light.angle );
				lightUniforms.exponent = light.exponent;
				lightUniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
M
Mr.doob 已提交
2654 2655 2656

			} else if ( light instanceof THREE.HemisphereLight ) {

B
Ben Houston 已提交
2657 2658
				if( ! light.__webglUniforms ) {
					light.__webglUniforms = {
2659
						direction: new THREE.Vector3(),
B
Ben Houston 已提交
2660 2661 2662 2663
						skyColor: new THREE.Color(),
						groundColor: new THREE.Color()
					}
				}
M
Mr.doob 已提交
2664

B
Ben Houston 已提交
2665
				var lightUniforms = light.__webglUniforms;
M
Mr.doob 已提交
2666
				_lights.hemi[ writeIndexHemi ++ ] = lightUniforms;
M
Mr.doob 已提交
2667

2668 2669 2670
				lightUniforms.direction.setFromMatrixPosition( light.matrixWorld );
				lightUniforms.direction.transformDirection( viewMatrix );
				lightUniforms.direction.normalize();
M
Mr.doob 已提交
2671

2672
				lightUniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
B
Ben Houston 已提交
2673
				lightUniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
M
Mr.doob 已提交
2674 2675 2676 2677 2678

			}

		}

M
Mr.doob 已提交
2679 2680 2681
		_lights.ambient[ 0 ] = r;
		_lights.ambient[ 1 ] = g;
		_lights.ambient[ 2 ] = b;
M
Mr.doob 已提交
2682

M
Mr.doob 已提交
2683 2684 2685 2686
		_lights.directional.length = writeIndexDirectional;
		_lights.point.length = writeIndexPoint;
		_lights.spot.length = writeIndexSpot;
		_lights.hemi.length = writeIndexHemi;
2687

M
Mr.doob 已提交
2688
	}
M
Mr.doob 已提交
2689 2690 2691 2692 2693 2694 2695

	// GL state setting

	this.setFaceCulling = function ( cullFace, frontFaceDirection ) {

		if ( cullFace === THREE.CullFaceNone ) {

2696
			state.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723

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

			}

2724
			state.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
2725 2726 2727 2728 2729 2730 2731 2732 2733

		}

	};

	// Textures

	function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {

2734 2735
		var extension;

M
Mr.doob 已提交
2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747
		if ( isImagePowerOfTwo ) {

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

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

		} else {

			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
M
Mr.doob 已提交
2748 2749 2750

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

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

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

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

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

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

2762
			}
M
Mr.doob 已提交
2763

M
Mr.doob 已提交
2764 2765
		}

2766 2767
		extension = extensions.get( 'EXT_texture_filter_anisotropic' );

2768
		if ( extension ) {
M
Mr.doob 已提交
2769

2770 2771
			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 已提交
2772

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

2775
				_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _this.getMaxAnisotropy() ) );
2776
				properties.get( texture ).__currentAnisotropy = texture.anisotropy;
M
Mr.doob 已提交
2777 2778 2779 2780 2781

			}

		}

M
Mr.doob 已提交
2782
	}
M
Mr.doob 已提交
2783

2784
	function uploadTexture( textureProperties, texture, slot ) {
2785

2786
		if ( textureProperties.__webglInit === undefined ) {
2787

2788
			textureProperties.__webglInit = true;
2789 2790 2791

			texture.addEventListener( 'dispose', onTextureDispose );

2792
			textureProperties.__webglTexture = _gl.createTexture();
2793

2794
			_infoMemory.textures ++;
2795 2796

		}
M
Mr.doob 已提交
2797

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

H
Henri Astre 已提交
2801 2802 2803 2804
		_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
		_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
		_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );

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

M
Mr.doob 已提交
2807 2808 2809 2810 2811 2812
		if ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( texture.image ) === false ) {

			texture.image = makePowerOfTwo( texture.image );

		}

H
Henri Astre 已提交
2813
		var image = texture.image,
M
Mr.doob 已提交
2814
		isImagePowerOfTwo = isPowerOfTwo( image ),
H
Henri Astre 已提交
2815 2816
		glFormat = paramThreeToGL( texture.format ),
		glType = paramThreeToGL( texture.type );
M
Mr.doob 已提交
2817

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

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

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

H
Henri Astre 已提交
2824 2825 2826
			// 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 已提交
2827

H
Henri Astre 已提交
2828 2829 2830
			if ( mipmaps.length > 0 && isImagePowerOfTwo ) {

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

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

H
Henri Astre 已提交
2835
				}
M
Mr.doob 已提交
2836

H
Henri Astre 已提交
2837
				texture.generateMipmaps = false;
M
Mr.doob 已提交
2838

H
Henri Astre 已提交
2839
			} else {
M
Mr.doob 已提交
2840

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

H
Henri Astre 已提交
2843
			}
M
Mr.doob 已提交
2844

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

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

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

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

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

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

2857
					} else {
M
Mr.doob 已提交
2858

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

2861
					}
M
Mr.doob 已提交
2862

H
Henri Astre 已提交
2863
				} else {
M
Mr.doob 已提交
2864

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

M
Mr.doob 已提交
2867 2868
				}

H
Henri Astre 已提交
2869 2870
			}

G
gero3 已提交
2871 2872 2873
		} else {

			// regular Texture (image, video, canvas)
H
Henri Astre 已提交
2874 2875 2876 2877 2878 2879

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

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

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

					mipmap = mipmaps[ i ];
2884
					state.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );
M
Mr.doob 已提交
2885 2886 2887

				}

H
Henri Astre 已提交
2888
				texture.generateMipmaps = false;
M
Mr.doob 已提交
2889

H
Henri Astre 已提交
2890
			} else {
M
Mr.doob 已提交
2891

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

H
Henri Astre 已提交
2894
			}
M
Mr.doob 已提交
2895

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

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

2900
		textureProperties.__version = texture.version;
M
Mr.doob 已提交
2901

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

2904
	}
M
Mr.doob 已提交
2905

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

2908 2909 2910
		var textureProperties = properties.get( texture );

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

2912
			var image = texture.image;
M
Mr.doob 已提交
2913

2914 2915
			if ( image === undefined ) {

2916
				console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );
2917 2918 2919 2920
				return;

			}

2921
			if ( image.complete === false ) {
M
Mr.doob 已提交
2922

2923
				console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );
2924 2925 2926 2927
				return;

			}

2928
			uploadTexture( textureProperties, texture, slot );
2929

2930
			return;
M
Mr.doob 已提交
2931 2932 2933

		}

B
Ben Adams 已提交
2934
		state.activeTexture( _gl.TEXTURE0 + slot );
2935
		state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
2936

M
Mr.doob 已提交
2937 2938 2939 2940
	};

	function clampToMaxSize ( image, maxSize ) {

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

2943 2944
			// Warning: Scaling through the canvas will only work with images that use
			// premultiplied alpha.
M
Mr.doob 已提交
2945

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

2948 2949 2950
			var canvas = document.createElement( 'canvas' );
			canvas.width = Math.floor( image.width * scale );
			canvas.height = Math.floor( image.height * scale );
M
Mr.doob 已提交
2951

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

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

2957 2958 2959
			return canvas;

		}
M
Mr.doob 已提交
2960

2961
		return image;
M
Mr.doob 已提交
2962 2963 2964

	}

M
Mr.doob 已提交
2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000
	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 已提交
3001 3002
	function setCubeTexture ( texture, slot ) {

3003
		var textureProperties = properties.get( texture );
3004

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

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

3009
				if ( ! textureProperties.__image__webglTextureCube ) {
M
Mr.doob 已提交
3010

3011 3012
					texture.addEventListener( 'dispose', onTextureDispose );

3013
					textureProperties.__image__webglTextureCube = _gl.createTexture();
M
Mr.doob 已提交
3014

3015
					_infoMemory.textures ++;
M
Mr.doob 已提交
3016 3017 3018

				}

B
Ben Adams 已提交
3019
				state.activeTexture( _gl.TEXTURE0 + slot );
3020
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
3021 3022 3023

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

M
Mr.doob 已提交
3024 3025
				var isCompressed = texture instanceof THREE.CompressedTexture;
				var isDataTexture = texture.image[ 0 ] instanceof THREE.DataTexture;
M
Mr.doob 已提交
3026 3027 3028 3029 3030

				var cubeImage = [];

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

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

G
gero3 已提交
3033
						cubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );
M
Mr.doob 已提交
3034 3035 3036

					} else {

3037
						cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];
M
Mr.doob 已提交
3038 3039 3040 3041 3042 3043

					}

				}

				var image = cubeImage[ 0 ],
M
Mr.doob 已提交
3044
				isImagePowerOfTwo = isPowerOfTwo( image ),
M
Mr.doob 已提交
3045 3046 3047 3048 3049 3050 3051
				glFormat = paramThreeToGL( texture.format ),
				glType = paramThreeToGL( texture.type );

				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo );

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

3052
					if ( ! isCompressed ) {
M
Mr.doob 已提交
3053

M
Mr.doob 已提交
3054
						if ( isDataTexture ) {
3055

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

M
Mr.doob 已提交
3058
						} else {
3059

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

M
Mr.doob 已提交
3062 3063
						}

3064
					} else {
3065

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

3068
						for ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {
M
Mr.doob 已提交
3069 3070

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

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

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

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

3078
								} else {
M
Mr.doob 已提交
3079

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

3082
								}
M
Mr.doob 已提交
3083

3084
							} else {
M
Mr.doob 已提交
3085

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

3088
							}
M
Mr.doob 已提交
3089

3090
						}
M
Mr.doob 已提交
3091

M
Mr.doob 已提交
3092
					}
M
Mr.doob 已提交
3093

M
Mr.doob 已提交
3094 3095 3096 3097 3098 3099 3100 3101
				}

				if ( texture.generateMipmaps && isImagePowerOfTwo ) {

					_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

				}

3102
				textureProperties.__version = texture.version;
M
Mr.doob 已提交
3103

B
Ben Adams 已提交
3104
				if ( texture.onUpdate ) texture.onUpdate( texture );
M
Mr.doob 已提交
3105 3106 3107

			} else {

B
Ben Adams 已提交
3108
				state.activeTexture( _gl.TEXTURE0 + slot );
3109
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
3110 3111 3112 3113 3114

			}

		}

M
Mr.doob 已提交
3115
	}
M
Mr.doob 已提交
3116 3117 3118

	function setCubeTextureDynamic ( texture, slot ) {

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

M
Mr.doob 已提交
3122
	}
M
Mr.doob 已提交
3123 3124 3125 3126 3127 3128

	// Render targets

	function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {

		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
M
Mr.doob 已提交
3129
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );
M
Mr.doob 已提交
3130

M
Mr.doob 已提交
3131
	}
M
Mr.doob 已提交
3132

M
Mr.doob 已提交
3133
	function setupRenderBuffer ( renderbuffer, renderTarget ) {
M
Mr.doob 已提交
3134 3135 3136 3137 3138 3139 3140 3141 3142

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

		/* For some reason this is not working. Defaulting to RGBA4.
3143
		} else if ( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
M
Mr.doob 已提交
3144 3145 3146 3147

			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.STENCIL_INDEX8, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
		*/
G
gero3 已提交
3148

M
Mr.doob 已提交
3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159
		} 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 {

			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );

		}

M
Mr.doob 已提交
3160
	}
M
Mr.doob 已提交
3161 3162 3163 3164 3165

	this.setRenderTarget = function ( renderTarget ) {

		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );

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

3168
			var renderTargetProperties = properties.get( renderTarget );
M
Mr.doob 已提交
3169
			var textureProperties = properties.get( renderTarget.texture );
M
Mr.doob 已提交
3170 3171 3172 3173 3174 3175

			if ( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
			if ( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;

			renderTarget.addEventListener( 'dispose', onRenderTargetDispose );

M
Mr.doob 已提交
3176
			textureProperties.__webglTexture = _gl.createTexture();
M
Mr.doob 已提交
3177

3178
			_infoMemory.textures ++;
M
Mr.doob 已提交
3179 3180 3181

			// Setup texture, create render and frame buffers

M
Mr.doob 已提交
3182 3183 3184
			var isTargetPowerOfTwo = isPowerOfTwo( renderTarget ),
				glFormat = paramThreeToGL( renderTarget.texture.format ),
				glType = paramThreeToGL( renderTarget.texture.type );
M
Mr.doob 已提交
3185 3186 3187

			if ( isCube ) {

3188 3189
				renderTargetProperties.__webglFramebuffer = [];
				renderTargetProperties.__webglRenderbuffer = [];
M
Mr.doob 已提交
3190

M
Mr.doob 已提交
3191
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
B
Ben Adams 已提交
3192

M
Mr.doob 已提交
3193
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );
M
Mr.doob 已提交
3194 3195 3196

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

3197 3198
					renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();
					renderTargetProperties.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
3199
					state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
M
Mr.doob 已提交
3200

3201 3202
					setupFrameBuffer( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
					setupRenderBuffer( renderTargetProperties.__webglRenderbuffer[ i ], renderTarget );
M
Mr.doob 已提交
3203 3204 3205

				}

M
Mr.doob 已提交
3206
				if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
M
Mr.doob 已提交
3207 3208 3209

			} else {

3210
				renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
M
Mr.doob 已提交
3211 3212 3213

				if ( renderTarget.shareDepthFrom ) {

3214
					renderTargetProperties.__webglRenderbuffer = renderTarget.shareDepthFrom.__webglRenderbuffer;
M
Mr.doob 已提交
3215 3216 3217

				} else {

3218
					renderTargetProperties.__webglRenderbuffer = _gl.createRenderbuffer();
M
Mr.doob 已提交
3219 3220 3221

				}

M
Mr.doob 已提交
3222 3223
				state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
				setTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );
M
Mr.doob 已提交
3224

3225
				state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
M
Mr.doob 已提交
3226

3227
				setupFrameBuffer( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
M
Mr.doob 已提交
3228 3229 3230 3231 3232

				if ( renderTarget.shareDepthFrom ) {

					if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {

3233
						_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTargetProperties.__webglRenderbuffer );
M
Mr.doob 已提交
3234 3235 3236

					} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {

3237
						_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderTargetProperties.__webglRenderbuffer );
M
Mr.doob 已提交
3238 3239 3240 3241 3242

					}

				} else {

3243
					setupRenderBuffer( renderTargetProperties.__webglRenderbuffer, renderTarget );
M
Mr.doob 已提交
3244 3245 3246

				}

M
Mr.doob 已提交
3247
				if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
M
Mr.doob 已提交
3248 3249 3250 3251 3252 3253 3254

			}

			// Release everything

			if ( isCube ) {

B
Ben Adams 已提交
3255
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
M
Mr.doob 已提交
3256 3257 3258

			} else {

B
Ben Adams 已提交
3259
				state.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271

			}

			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );

		}

		var framebuffer, width, height, vx, vy;

		if ( renderTarget ) {

3272
			var renderTargetProperties = properties.get( renderTarget );
F
Fordy 已提交
3273

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

3276
				framebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
3277 3278 3279

			} else {

3280
				framebuffer = renderTargetProperties.__webglFramebuffer;
M
Mr.doob 已提交
3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310

			}

			width = renderTarget.width;
			height = renderTarget.height;

			vx = 0;
			vy = 0;

		} else {

			framebuffer = null;

			width = _viewportWidth;
			height = _viewportHeight;

			vx = _viewportX;
			vy = _viewportY;

		}

		if ( framebuffer !== _currentFramebuffer ) {

			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
			_gl.viewport( vx, vy, width, height );

			_currentFramebuffer = framebuffer;

		}

M
Mr.doob 已提交
3311 3312 3313 3314 3315 3316 3317
		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 已提交
3318 3319 3320 3321 3322
		_currentWidth = width;
		_currentHeight = height;

	};

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

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

3327
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
3328
			return;
3329

G
gero3 已提交
3330
		}
3331

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

M
Mr.doob 已提交
3334
		if ( framebuffer ) {
3335

G
gero3 已提交
3336
			var restore = false;
3337

M
Mr.doob 已提交
3338
			if ( framebuffer !== _currentFramebuffer ) {
3339

M
Mr.doob 已提交
3340
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
3341

G
gero3 已提交
3342
				restore = true;
3343

G
gero3 已提交
3344
			}
3345

M
Mr.doob 已提交
3346
			try {
3347

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

M
Mr.doob 已提交
3350 3351
				if ( texture.format !== THREE.RGBAFormat
					&& paramThreeToGL( texture.format ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
3352

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

M
Mr.doob 已提交
3356
				}
3357

M
Mr.doob 已提交
3358 3359 3360 3361
				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' ) ) ) {
3362

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

M
Mr.doob 已提交
3366
				}
3367

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

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

M
Mr.doob 已提交
3372
				} else {
M
Mr.doob 已提交
3373

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

				}
M
Mr.doob 已提交
3377

M
Mr.doob 已提交
3378
			} finally {
M
Mr.doob 已提交
3379

M
Mr.doob 已提交
3380 3381 3382
				if ( restore ) {

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

M
Mr.doob 已提交
3384 3385 3386
				}

			}
M
Mr.doob 已提交
3387 3388 3389

		}

M
Mr.doob 已提交
3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400
	};

	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 已提交
3401
	}
M
Mr.doob 已提交
3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414

	// 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 已提交
3415
	}
M
Mr.doob 已提交
3416 3417 3418 3419 3420

	// Map three.js constants to WebGL constants

	function paramThreeToGL ( p ) {

3421 3422
		var extension;

M
Mr.doob 已提交
3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446
		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;

3447 3448 3449 3450 3451 3452 3453 3454
		extension = extensions.get( 'OES_texture_half_float' );

		if ( extension !== null ) {

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

		}

M
Mr.doob 已提交
3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477
		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;

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

3480 3481 3482 3483 3484 3485
		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 已提交
3486 3487 3488

		}

3489 3490 3491
		extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );

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

3493 3494 3495 3496
			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 已提交
3497 3498 3499

		}

3500 3501 3502
		extension = extensions.get( 'EXT_blend_minmax' );

		if ( extension !== null ) {
3503

3504 3505
			if ( p === THREE.MinEquation ) return extension.MIN_EXT;
			if ( p === THREE.MaxEquation ) return extension.MAX_EXT;
3506 3507 3508

		}

M
Mr.doob 已提交
3509 3510
		return 0;

M
Mr.doob 已提交
3511
	}
M
Mr.doob 已提交
3512 3513

};