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

THREE.WebGLRenderer = function ( parameters ) {

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

	parameters = parameters || {};

E
Eli Grey 已提交
15
	var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),
16
	_context = parameters.context !== undefined ? parameters.context : null,
M
Mr.doob 已提交
17

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

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

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

32 33
	var morphInfluences = new Float32Array( 8 );

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

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

T
tschw 已提交
53 54 55 56 57
	// user-defined clipping

	this.clippingPlanes = [];
	this.localClippingEnabled = false;

M
Mr.doob 已提交
58 59
	// physically based shading

60
	this.gammaFactor = 2.0;	// for backwards compatibility
M
Mr.doob 已提交
61 62 63
	this.gammaInput = false;
	this.gammaOutput = false;

64 65
	// physical lights

66
	this.physicallyCorrectLights = false;
67

B
Ben Houston 已提交
68 69 70 71 72 73
	// tone mapping

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

M
Mr.doob 已提交
74 75 76 77 78 79 80 81 82 83 84 85
	// morphs

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

	// internal properties

	var _this = this,

	// internal state cache

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

92 93 94 95 96
	_currentScissor = new THREE.Vector4(),
	_currentScissorTest = null,

	_currentViewport = new THREE.Vector4(),

97 98
	//

M
Mr.doob 已提交
99 100
	_usedTextureUnits = 0,

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

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

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

	_pixelRatio = 1,

	_scissor = new THREE.Vector4( 0, 0, _width, _height ),
112 113
	_scissorTest = false,

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

M
Mr.doob 已提交
116 117 118 119
	// frustum

	_frustum = new THREE.Frustum(),

T
tschw 已提交
120 121
	// clipping

T
tschw 已提交
122
	_clipping = new THREE.WebGLClipping(),
T
tschw 已提交
123 124 125 126 127
	_clippingEnabled = false,
	_localClippingEnabled = false,

	_sphere = new THREE.Sphere(),

M
Mr.doob 已提交
128
	// camera matrices cache
M
Mr.doob 已提交
129 130 131 132 133 134 135 136 137

	_projScreenMatrix = new THREE.Matrix4(),

	_vector3 = new THREE.Vector3(),

	// light arrays cache

	_lights = {

138 139
		hash: '',

M
Mr.doob 已提交
140
		ambient: [ 0, 0, 0 ],
M
Mr.doob 已提交
141
		directional: [],
142 143
		directionalShadowMap: [],
		directionalShadowMatrix: [],
M
Mr.doob 已提交
144
		spot: [],
145 146
		spotShadowMap: [],
		spotShadowMatrix: [],
M
Mr.doob 已提交
147
		point: [],
148 149
		pointShadowMap: [],
		pointShadowMatrix: [],
150 151
		hemi: [],

152
		shadows: []
M
Mr.doob 已提交
153

154 155
	},

M
Mr.doob 已提交
156 157
	// info

158
	_infoRender = {
159 160 161 162 163 164

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

M
Mr.doob 已提交
165 166
	};

M
Mr.doob 已提交
167
	this.info = {
168

M
Mr.doob 已提交
169
		render: _infoRender,
170 171 172 173 174 175
		memory: {

			geometries: 0,
			textures: 0

		},
176
		programs: null
M
Mr.doob 已提交
177 178

	};
179

180

M
Mr.doob 已提交
181 182 183 184
	// initialize

	var _gl;

M
Mr.doob 已提交
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
	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 已提交
200
			if ( _canvas.getContext( 'webgl' ) !== null ) {
201 202 203 204 205 206 207 208

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

			} else {

				throw 'Error creating WebGL context.';

			}
M
Mr.doob 已提交
209 210 211

		}

212 213 214 215 216 217 218 219 220 221 222 223
		// Some experimental-webgl implementations do not have getShaderPrecisionFormat

		if ( _gl.getShaderPrecisionFormat === undefined ) {

			_gl.getShaderPrecisionFormat = function () {

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

			};

		}

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

M
Mr.doob 已提交
226 227
	} catch ( error ) {

228
		console.error( 'THREE.WebGLRenderer: ' + error );
M
Mr.doob 已提交
229 230 231

	}

232 233
	var extensions = new THREE.WebGLExtensions( _gl );

234
	extensions.get( 'WEBGL_depth_texture' );
235 236
	extensions.get( 'OES_texture_float' );
	extensions.get( 'OES_texture_float_linear' );
237 238
	extensions.get( 'OES_texture_half_float' );
	extensions.get( 'OES_texture_half_float_linear' );
239
	extensions.get( 'OES_standard_derivatives' );
B
Ben Adams 已提交
240
	extensions.get( 'ANGLE_instanced_arrays' );
241

242 243
	if ( extensions.get( 'OES_element_index_uint' ) ) {

244
		THREE.BufferGeometry.MaxIndex = 4294967296;
245 246 247

	}

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

250 251
	var state = new THREE.WebGLState( _gl, extensions, paramThreeToGL );
	var properties = new THREE.WebGLProperties();
252
	var textures = new THREE.WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, this.info );
253
	var objects = new THREE.WebGLObjects( _gl, properties, this.info );
G
gero3 已提交
254
	var programCache = new THREE.WebGLPrograms( this, capabilities );
M
Mr.doob 已提交
255
	var lightCache = new THREE.WebGLLights();
256

257 258
	this.info.programs = programCache.programs;

259 260
	var bufferRenderer = new THREE.WebGLBufferRenderer( _gl, extensions, _infoRender );
	var indexedBufferRenderer = new THREE.WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
261

M
Mr.doob 已提交
262 263
	//

264 265
	function getTargetPixelRatio() {

266
		return _currentRenderTarget === null ? _pixelRatio : 1;
267 268 269

	}

270
	function glClearColor( r, g, b, a ) {
271 272 273

		if ( _premultipliedAlpha === true ) {

274
			r *= a; g *= a; b *= a;
275 276 277

		}

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

280
	}
281

282
	function setDefaultGLState() {
M
Mr.doob 已提交
283

M
Mr.doob 已提交
284
		state.init();
M
Mr.doob 已提交
285

286 287
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
M
Mr.doob 已提交
288

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

291
	}
292

293
	function resetGLState() {
294 295 296 297

		_currentProgram = null;
		_currentCamera = null;

298
		_currentGeometryProgram = '';
299 300
		_currentMaterialId = - 1;

M
Mr.doob 已提交
301 302
		state.reset();

303
	}
M
Mr.doob 已提交
304 305 306 307

	setDefaultGLState();

	this.context = _gl;
M
Mr.doob 已提交
308
	this.capabilities = capabilities;
309
	this.extensions = extensions;
310
	this.properties = properties;
M
Mr.doob 已提交
311
	this.state = state;
M
Mr.doob 已提交
312

M
Mr.doob 已提交
313 314
	// shadow map

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

317
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
318

M
Mr.doob 已提交
319

M
Mr.doob 已提交
320 321 322 323 324
	// Plugins

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

M
Mr.doob 已提交
325 326 327 328 329 330 331 332
	// API

	this.getContext = function () {

		return _gl;

	};

333 334 335 336 337 338
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

339 340 341 342 343 344
	this.forceContextLoss = function () {

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

	};

345
	this.getMaxAnisotropy = function () {
346

347
		return capabilities.getMaxAnisotropy();
348

349
	};
M
Mr.doob 已提交
350 351 352

	this.getPrecision = function () {

G
gero3 已提交
353
		return capabilities.precision;
M
Mr.doob 已提交
354 355 356

	};

357 358
	this.getPixelRatio = function () {

359
		return _pixelRatio;
360 361 362 363 364

	};

	this.setPixelRatio = function ( value ) {

365 366 367 368 369
		if ( value === undefined ) return;

		_pixelRatio = value;

		this.setSize( _viewport.z, _viewport.w, false );
370 371 372

	};

373 374 375
	this.getSize = function () {

		return {
376 377
			width: _width,
			height: _height
378 379 380 381
		};

	};

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

384 385 386
		_width = width;
		_height = height;

387 388
		_canvas.width = width * _pixelRatio;
		_canvas.height = height * _pixelRatio;
389

390
		if ( updateStyle !== false ) {
391

G
gero3 已提交
392 393
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
394

G
gero3 已提交
395
		}
M
Mr.doob 已提交
396

397
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
398 399 400 401 402

	};

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

403
		state.viewport( _viewport.set( x, y, width, height ) );
M
Mr.doob 已提交
404 405 406

	};

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

409
		state.scissor( _scissor.set( x, y, width, height ) );
M
Mr.doob 已提交
410 411 412

	};

413 414
	this.setScissorTest = function ( boolean ) {

415
		state.setScissorTest( _scissorTest = boolean );
M
Mr.doob 已提交
416 417 418 419 420

	};

	// Clearing

M
Mr.doob 已提交
421
	this.getClearColor = function () {
M
Mr.doob 已提交
422

M
Mr.doob 已提交
423
		return _clearColor;
M
Mr.doob 已提交
424 425 426

	};

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

M
Mr.doob 已提交
429
		_clearColor.set( color );
430

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

433
		glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
M
Mr.doob 已提交
434 435 436

	};

M
Mr.doob 已提交
437
	this.getClearAlpha = function () {
M
Mr.doob 已提交
438

M
Mr.doob 已提交
439
		return _clearAlpha;
M
Mr.doob 已提交
440 441 442

	};

M
Mr.doob 已提交
443
	this.setClearAlpha = function ( alpha ) {
M
Mr.doob 已提交
444

M
Mr.doob 已提交
445
		_clearAlpha = alpha;
M
Mr.doob 已提交
446

447
		glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
M
Mr.doob 已提交
448 449 450 451 452 453 454 455 456 457 458 459

	};

	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 );
460 461 462 463 464

	};

	this.clearColor = function () {

M
Mr.doob 已提交
465
		this.clear( true, false, false );
466 467 468 469 470

	};

	this.clearDepth = function () {

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

	};

	this.clearStencil = function () {

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

	};

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

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

	};

M
Mr.doob 已提交
488 489
	// Reset

490
	this.resetGLState = resetGLState;
M
Mr.doob 已提交
491

D
dubejf 已提交
492 493
	this.dispose = function() {

494 495 496 497 498
		transparentObjects = [];
		transparentObjectsLastIndex = -1;
		opaqueObjects = [];
		opaqueObjectsLastIndex = -1;

D
dubejf 已提交
499 500 501 502
		_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );

	};

M
Mr.doob 已提交
503
	// Events
M
Mr.doob 已提交
504

D
dubejf 已提交
505 506 507 508 509 510 511 512 513
	function onContextLost( event ) {

		event.preventDefault();

		resetGLState();
		setDefaultGLState();

		properties.clear();

M
Mr.doob 已提交
514
	}
D
dubejf 已提交
515

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

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

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

	// Buffer deallocation

528
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
529

530 531 532 533
		releaseMaterialProgramReference( material );

		properties.delete( material );

534
	}
535 536


537
	function releaseMaterialProgramReference( material ) {
538

539
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
540 541 542

		material.program = undefined;

543
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
544

545
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
546

M
Mr.doob 已提交
547 548
		}

549
	}
M
Mr.doob 已提交
550 551 552 553 554

	// Buffer rendering

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

555
		state.initAttributes();
556

557
		var buffers = properties.get( object );
558

559 560 561 562
		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 已提交
563

564
		var attributes = program.getAttributes();
565

M
Mr.doob 已提交
566 567
		if ( object.hasPositions ) {

568
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
M
Mr.doob 已提交
569
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
570

571 572
			state.enableAttribute( attributes.position );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
573 574 575 576 577

		}

		if ( object.hasNormals ) {

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

W
WestLangley 已提交
580
			if ( material.type !== 'MeshPhongMaterial' && material.type !== 'MeshStandardMaterial' && material.type !== 'MeshPhysicalMaterial' && material.shading === THREE.FlatShading ) {
M
Mr.doob 已提交
581

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

584
					var array = object.normalArray;
M
Mr.doob 已提交
585

586 587 588
					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 已提交
589

590 591 592
					array[ i + 0 ] = nx;
					array[ i + 1 ] = ny;
					array[ i + 2 ] = nz;
M
Mr.doob 已提交
593

594 595 596
					array[ i + 3 ] = nx;
					array[ i + 4 ] = ny;
					array[ i + 5 ] = nz;
M
Mr.doob 已提交
597

598 599 600
					array[ i + 6 ] = nx;
					array[ i + 7 ] = ny;
					array[ i + 8 ] = nz;
M
Mr.doob 已提交
601 602 603 604 605 606

				}

			}

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

608
			state.enableAttribute( attributes.normal );
609

610
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
611 612 613 614 615

		}

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

616
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
M
Mr.doob 已提交
617
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
618

619
			state.enableAttribute( attributes.uv );
620

621
			_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
622 623 624 625 626

		}

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

627
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
M
Mr.doob 已提交
628
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
629

630
			state.enableAttribute( attributes.color );
631

632
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
633 634 635

		}

636
		state.disableUnusedAttributes();
637

M
Mr.doob 已提交
638 639 640 641 642 643
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

644
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
645

M
Mr.doob 已提交
646 647
		setMaterial( material );

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

M
Mr.doob 已提交
650 651
		var updateBuffers = false;
		var geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;
M
Mr.doob 已提交
652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674

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

			}

675
			activeInfluences.sort( absNumericalSort );
M
Mr.doob 已提交
676 677 678 679 680 681 682

			if ( activeInfluences.length > 8 ) {

				activeInfluences.length = 8;

			}

683 684
			var morphAttributes = geometry.morphAttributes;

M
Mr.doob 已提交
685 686 687 688 689 690 691
			for ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {

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

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

692
					var index = influence[ 1 ];
M
Mr.doob 已提交
693

694 695
					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 已提交
696 697 698

				} else {

699 700
					if ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );
					if ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );
M
Mr.doob 已提交
701 702 703 704 705

				}

			}

T
tschw 已提交
706 707
			program.getUniforms().setValue(
					_gl, 'morphTargetInfluences', morphInfluences );
M
Mr.doob 已提交
708 709 710 711 712

			updateBuffers = true;

		}

713 714
		//

715
		var index = geometry.index;
716 717
		var position = geometry.attributes.position;

718 719
		if ( material.wireframe === true ) {

720
			index = objects.getWireframeAttribute( geometry );
721 722 723

		}

724 725
		var renderer;

726
		if ( index !== null ) {
727

728 729
			renderer = indexedBufferRenderer;
			renderer.setIndex( index );
730

731
		} else {
732

733
			renderer = bufferRenderer;
734

735
		}
M
Mr.doob 已提交
736

737
		if ( updateBuffers ) {
M
Mr.doob 已提交
738

739
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
740

741
			if ( index !== null ) {
742

743
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );
744 745 746

			}

747
		}
748

749 750
		//

M
Mr.doob 已提交
751 752
		var dataStart = 0;
		var dataCount = Infinity;
753

M
Mr.doob 已提交
754
		if ( index !== null ) {
755

M
Mr.doob 已提交
756
			dataCount = index.count;
757

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

M
Mr.doob 已提交
760
			dataCount = position.count;
761

M
Mr.doob 已提交
762
		}
763

M
Mr.doob 已提交
764 765
		var rangeStart = geometry.drawRange.start;
		var rangeCount = geometry.drawRange.count;
766

M
Mr.doob 已提交
767 768
		var groupStart = group !== null ? group.start : 0;
		var groupCount = group !== null ? group.count : Infinity;
769

M
Mr.doob 已提交
770 771 772 773 774 775
		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 );

		//
776

777
		if ( object instanceof THREE.Mesh ) {
778

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

781
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
782
				renderer.setMode( _gl.LINES );
783

784
			} else {
M
Mr.doob 已提交
785 786

				switch ( object.drawMode ) {
787

B
Ben Adams 已提交
788 789 790 791 792 793 794 795 796 797 798 799 800
					case THREE.TrianglesDrawMode:
						renderer.setMode( _gl.TRIANGLES );
						break;

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

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

				}
801

802
			}
803

804

805
		} else if ( object instanceof THREE.Line ) {
806

807
			var lineWidth = material.linewidth;
808

809
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
810

811
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
812

813
			if ( object instanceof THREE.LineSegments ) {
814

815
				renderer.setMode( _gl.LINES );
816

817
			} else {
818

819
				renderer.setMode( _gl.LINE_STRIP );
820 821

			}
M
Mr.doob 已提交
822

823
		} else if ( object instanceof THREE.Points ) {
824 825

			renderer.setMode( _gl.POINTS );
826 827

		}
828

J
jfranc 已提交
829
		if ( geometry instanceof THREE.InstancedBufferGeometry ) {
M
Mr.doob 已提交
830 831 832

			if ( geometry.maxInstancedCount > 0 ) {

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

J
jfranc 已提交
835
			}
836 837 838

		} else {

M
Mr.doob 已提交
839
			renderer.render( drawStart, drawCount );
840

M
Mr.doob 已提交
841 842 843 844
		}

	};

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

M
Mr.doob 已提交
847
		var extension;
B
Ben Adams 已提交
848

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

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

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

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

M
Mr.doob 已提交
858 859 860
			}

		}
B
Ben Adams 已提交
861

862 863
		if ( startIndex === undefined ) startIndex = 0;

864 865
		state.initAttributes();

866
		var geometryAttributes = geometry.attributes;
867

868
		var programAttributes = program.getAttributes();
869

870
		var materialDefaultAttributeValues = material.defaultAttributeValues;
871

872
		for ( var name in programAttributes ) {
873

874
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
875

M
Mr.doob 已提交
876
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
877

878
				var geometryAttribute = geometryAttributes[ name ];
879

M
Mr.doob 已提交
880
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
881

882
					var type = _gl.FLOAT;
883
					var array = geometryAttribute.array;
884 885
					var normalized = geometryAttribute.normalized;

886 887
					if ( array instanceof Float32Array ) {

888
						type = _gl.FLOAT;
889 890 891 892 893 894 895

					} else if ( array instanceof Float64Array ) {

						console.warn("Unsupported data buffer format: Float64Array");

					} else if ( array instanceof Uint16Array ) {

896 897
						type = _gl.UNSIGNED_SHORT;

898 899
					} else if ( array instanceof Int16Array ) {

900
						type = _gl.SHORT;
901 902 903

					} else if ( array instanceof Uint32Array ) {

904
						type = _gl.UNSIGNED_INT;
905 906 907

					} else if ( array instanceof Int32Array ) {

908
						type = _gl.INT;
909 910 911

					} else if ( array instanceof Int8Array ) {

912
						type = _gl.BYTE;
913 914 915

					} else if ( array instanceof Uint8Array ) {

916
						type = _gl.UNSIGNED_BYTE;
917 918

					}
919

920
					var size = geometryAttribute.itemSize;
G
gero3 已提交
921
					var buffer = objects.getAttributeBuffer( geometryAttribute );
922

B
Ben Adams 已提交
923
					if ( geometryAttribute instanceof THREE.InterleavedBufferAttribute ) {
924

M
Mr.doob 已提交
925 926 927 928 929
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

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

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

M
Mr.doob 已提交
933
							if ( geometry.maxInstancedCount === undefined ) {
934

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

M
Mr.doob 已提交
937
							}
B
Ben Adams 已提交
938

M
Mr.doob 已提交
939
						} else {
B
Ben Adams 已提交
940

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

M
Mr.doob 已提交
943
						}
B
Ben Adams 已提交
944

M
Mr.doob 已提交
945
						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
946
						_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * data.array.BYTES_PER_ELEMENT, ( startIndex * stride + offset ) * data.array.BYTES_PER_ELEMENT );
B
Ben Adams 已提交
947

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

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

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

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

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

M
Mr.doob 已提交
958
							}
B
Ben Adams 已提交
959

M
Mr.doob 已提交
960 961 962 963
						} else {

							state.enableAttribute( programAttribute );

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

M
Mr.doob 已提交
966
						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
967
						_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * geometryAttribute.array.BYTES_PER_ELEMENT );
M
Mr.doob 已提交
968

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

971 972
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
973
					var value = materialDefaultAttributeValues[ name ];
974

975
					if ( value !== undefined ) {
M
Mr.doob 已提交
976

977
						switch ( value.length ) {
M
Mr.doob 已提交
978

979 980 981
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
982

983 984 985
							case 3:
								_gl.vertexAttrib3fv( programAttribute, value );
								break;
M
Mr.doob 已提交
986

987 988 989
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
990

991 992
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
993 994

						}
M
Mr.doob 已提交
995 996 997 998 999 1000 1001 1002

					}

				}

			}

		}
1003

1004
		state.disableUnusedAttributes();
1005

M
Mr.doob 已提交
1006 1007
	}

M
Mr.doob 已提交
1008 1009
	// Sorting

1010
	function absNumericalSort( a, b ) {
1011

1012
		return Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );
1013 1014 1015

	}

M
Mr.doob 已提交
1016 1017
	function painterSortStable ( a, b ) {

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

U
unconed 已提交
1020
			return a.object.renderOrder - b.object.renderOrder;
1021

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

M
Mr.doob 已提交
1024
			return a.material.id - b.material.id;
1025 1026

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

M
Mr.doob 已提交
1028
			return a.z - b.z;
M
Mr.doob 已提交
1029 1030 1031

		} else {

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

		}

1036
	}
M
Mr.doob 已提交
1037

1038 1039
	function reversePainterSortStable ( a, b ) {

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

U
unconed 已提交
1042
			return a.object.renderOrder - b.object.renderOrder;
1043 1044

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

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

		} else {

			return a.id - b.id;

		}

1054
	}
1055

M
Mr.doob 已提交
1056 1057 1058 1059 1060 1061
	// Rendering

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

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

1062
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1063 1064 1065 1066
			return;

		}

M
Mr.doob 已提交
1067
		var fog = scene.fog;
M
Mr.doob 已提交
1068 1069 1070

		// reset caching for this frame

1071
		_currentGeometryProgram = '';
1072
		_currentMaterialId = - 1;
1073
		_currentCamera = null;
M
Mr.doob 已提交
1074 1075 1076

		// update scene graph

1077
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1078 1079 1080

		// update camera matrices and frustum

1081
		if ( camera.parent === null ) camera.updateMatrixWorld();
M
Mr.doob 已提交
1082 1083 1084 1085 1086 1087

		camera.matrixWorldInverse.getInverse( camera.matrixWorld );

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

M
Mr.doob 已提交
1088
		lights.length = 0;
1089

M
Mr.doob 已提交
1090 1091
		opaqueObjectsLastIndex = - 1;
		transparentObjectsLastIndex = - 1;
1092

M
Mr.doob 已提交
1093 1094 1095
		sprites.length = 0;
		lensFlares.length = 0;

T
tschw 已提交
1096 1097 1098
		_localClippingEnabled = this.localClippingEnabled;
		_clippingEnabled = _clipping.init(
				this.clippingPlanes, _localClippingEnabled, camera );
T
tschw 已提交
1099

1100
		projectObject( scene, camera );
M
Mr.doob 已提交
1101

T
tschw 已提交
1102

1103 1104 1105
		opaqueObjects.length = opaqueObjectsLastIndex + 1;
		transparentObjects.length = transparentObjectsLastIndex + 1;

M
Mr.doob 已提交
1106
		if ( _this.sortObjects === true ) {
1107 1108 1109

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

1111 1112
		}

M
Mr.doob 已提交
1113
		//
M
Mr.doob 已提交
1114

T
tschw 已提交
1115
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1116

1117 1118
		setupShadows( lights );

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

1121 1122
		setupLights( lights, camera );

T
tschw 已提交
1123
		if ( _clippingEnabled ) _clipping.endShadows();
T
tschw 已提交
1124

M
Mr.doob 已提交
1125 1126
		//

1127 1128 1129 1130
		_infoRender.calls = 0;
		_infoRender.vertices = 0;
		_infoRender.faces = 0;
		_infoRender.points = 0;
M
Mr.doob 已提交
1131

1132 1133 1134 1135 1136 1137
		if ( renderTarget === undefined ) {

			renderTarget = null;

		}

M
Mr.doob 已提交
1138 1139 1140 1141 1142 1143 1144 1145
		this.setRenderTarget( renderTarget );

		if ( this.autoClear || forceClear ) {

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

		}

1146
		//
M
Mr.doob 已提交
1147 1148 1149

		if ( scene.overrideMaterial ) {

1150
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1151

1152 1153
			renderObjects( opaqueObjects, camera, fog, overrideMaterial );
			renderObjects( transparentObjects, camera, fog, overrideMaterial );
1154

M
Mr.doob 已提交
1155 1156 1157 1158
		} else {

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

M
Mr.doob 已提交
1159
			state.setBlending( THREE.NoBlending );
1160
			renderObjects( opaqueObjects, camera, fog );
M
Mr.doob 已提交
1161 1162 1163

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

1164
			renderObjects( transparentObjects, camera, fog );
M
Mr.doob 已提交
1165 1166 1167 1168 1169

		}

		// custom render plugins (post pass)

M
Mr.doob 已提交
1170
		spritePlugin.render( scene, camera );
1171
		lensFlarePlugin.render( scene, camera, _currentViewport );
M
Mr.doob 已提交
1172 1173 1174

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

M
Mr.doob 已提交
1175 1176
		if ( renderTarget ) {

1177
			textures.updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1178 1179 1180

		}

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

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

		// _gl.finish();

	};
M
Mr.doob 已提交
1190

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

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

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

		if ( material.transparent ) {

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

		} else {

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

		}

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

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

		} else {

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

		}

	}

M
Mr.doob 已提交
1240 1241
	// TODO Duplicated code (Frustum)

T
tschw 已提交
1242 1243 1244 1245 1246 1247 1248
	function isObjectViewable( object ) {

		var geometry = object.geometry;

		if ( geometry.boundingSphere === null )
			geometry.computeBoundingSphere();

M
Mr.doob 已提交
1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266
		_sphere.copy( geometry.boundingSphere ).
			applyMatrix4( object.matrixWorld );

		return isSphereViewable( _sphere );

	}

	function isSpriteViewable( sprite ) {

		_sphere.center.set( 0, 0, 0 );
		_sphere.radius = 0.7071067811865476;
		_sphere.applyMatrix4( sprite.matrixWorld );

		return isSphereViewable( _sphere );

	}

	function isSphereViewable( sphere ) {
T
tschw 已提交
1267 1268

		if ( ! _frustum.intersectsSphere( sphere ) ) return false;
T
tschw 已提交
1269 1270 1271 1272

		var numPlanes = _clipping.numPlanes;

		if ( numPlanes === 0 ) return true;
T
tschw 已提交
1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284

		var planes = _this.clippingPlanes,

			center = sphere.center,
			negRad = - sphere.radius,
			i = 0;

		do {

			// out when deeper than radius in the negative halfspace
			if ( planes[ i ].distanceToPoint( center ) < negRad ) return false;

T
tschw 已提交
1285
		} while ( ++ i !== numPlanes );
T
tschw 已提交
1286 1287 1288 1289 1290

		return true;

	}

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

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

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

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

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

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

M
Mr.doob 已提交
1303
				if ( object.frustumCulled === false || isSpriteViewable( object ) === true ) {
1304 1305 1306 1307

					sprites.push( object );

				}
M
Mr.doob 已提交
1308

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

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

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

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

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

1320
				}
1321

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

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

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

1328
					object.skeleton.update();
1329

1330
				}
1331

T
tschw 已提交
1332
				if ( object.frustumCulled === false || isObjectViewable( object ) === true ) {
1333

1334
					var material = object.material;
1335

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

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

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

						}
M
Mr.doob 已提交
1344

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

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

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

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

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

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

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

								}
M
Mr.doob 已提交
1362

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

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

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

1369
						}
O
OpenShift guest 已提交
1370

1371
					}
M
Mr.doob 已提交
1372

1373
				}
M
Mr.doob 已提交
1374

1375
			}
M
Mr.doob 已提交
1376

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

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

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

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

1385
		}
1386

1387
	}
M
Mr.doob 已提交
1388

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1423
		}
M
Mr.doob 已提交
1424

1425
	}
G
gero3 已提交
1426

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

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

T
tschw 已提交
1431
		var parameters = programCache.getParameters(
T
tschw 已提交
1432
				material, _lights, fog, _clipping.numPlanes, object );
T
tschw 已提交
1433

G
gero3 已提交
1434
		var code = programCache.getProgramCode( material, parameters );
G
gero3 已提交
1435

1436
		var program = materialProperties.program;
T
tschw 已提交
1437
		var programChange = true;
1438

1439
		if ( program === undefined ) {
B
Ben Adams 已提交
1440

M
Mr.doob 已提交
1441 1442
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1443

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

M
Mr.doob 已提交
1446
			// changed glsl or parameters
1447
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1448

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

T
tschw 已提交
1451
			// same glsl and uniform list
T
tschw 已提交
1452 1453
			return;

T
tschw 已提交
1454
		} else {
B
Ben Adams 已提交
1455

T
tschw 已提交
1456 1457
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1458 1459 1460

		}

1461
		if ( programChange ) {
B
Ben Adams 已提交
1462

1463
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1464

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

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

1474
			} else {
B
Ben Adams 已提交
1475

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

1483
			}
G
gero3 已提交
1484

1485
			material.__webglShader = materialProperties.__webglShader;
G
gero3 已提交
1486

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

1489 1490
			materialProperties.program = program;
			material.program = program;
1491 1492 1493

		}

1494
		var attributes = program.getAttributes();
M
Mr.doob 已提交
1495 1496 1497 1498 1499

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

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

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

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

					material.numSupportedMorphNormals ++;

				}

			}

		}

T
tschw 已提交
1528 1529 1530 1531 1532 1533
		var uniforms = materialProperties.__webglShader.uniforms;

		if ( ! ( material instanceof THREE.ShaderMaterial ) &&
				! ( material instanceof THREE.RawShaderMaterial ) ||
				material.clipping === true ) {

T
tschw 已提交
1534 1535
			materialProperties.numClippingPlanes = _clipping.numPlanes;
			uniforms.clippingPlanes = _clipping.uniform;
T
tschw 已提交
1536 1537 1538

		}

M
Mr.doob 已提交
1539
		if ( material.lights ) {
1540

1541 1542
			// store the light setup it was created for

1543 1544
			materialProperties.lightsHash = _lights.hash;

1545 1546 1547 1548 1549
			// wire up the material to this renderer's lighting state

			uniforms.ambientLightColor.value = _lights.ambient;
			uniforms.directionalLights.value = _lights.directional;
			uniforms.spotLights.value = _lights.spot;
M
Mr.doob 已提交
1550
			uniforms.pointLights.value = _lights.point;
1551 1552
			uniforms.hemisphereLights.value = _lights.hemi;

1553 1554 1555 1556 1557 1558
			uniforms.directionalShadowMap.value = _lights.directionalShadowMap;
			uniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;
			uniforms.spotShadowMap.value = _lights.spotShadowMap;
			uniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;
			uniforms.pointShadowMap.value = _lights.pointShadowMap;
			uniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;
1559

1560 1561
		}

T
tschw 已提交
1562 1563 1564
		var progUniforms = materialProperties.program.getUniforms(),
			uniformsList =
					THREE.WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
A
arose 已提交
1565

T
tschw 已提交
1566 1567 1568
		materialProperties.uniformsList = uniformsList;
		materialProperties.dynamicUniforms =
				THREE.WebGLUniforms.splitDynamic( uniformsList, uniforms );
A
arose 已提交
1569

M
Mr.doob 已提交
1570
	}
M
Mr.doob 已提交
1571

1572 1573
	function setMaterial( material ) {

T
tschw 已提交
1574 1575 1576 1577 1578 1579
		if ( material.side !== THREE.DoubleSide )
			state.enable( _gl.CULL_FACE );
		else
			state.disable( _gl.CULL_FACE );

		state.setFlipSided( material.side === THREE.BackSide );
M
Mr.doob 已提交
1580

1581 1582
		if ( material.transparent === true ) {

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

1585 1586 1587 1588
		} else {

			state.setBlending( THREE.NoBlending );

1589 1590
		}

B
Ben Adams 已提交
1591
		state.setDepthFunc( material.depthFunc );
M
Mr.doob 已提交
1592 1593
		state.setDepthTest( material.depthTest );
		state.setDepthWrite( material.depthWrite );
1594
		state.setColorWrite( material.colorWrite );
M
Mr.doob 已提交
1595
		state.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
1596 1597 1598

	}

1599
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1600 1601 1602

		_usedTextureUnits = 0;

1603
		var materialProperties = properties.get( material );
1604

T
tschw 已提交
1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615
		if ( _clippingEnabled ) {

			if ( _localClippingEnabled || camera !== _currentCamera ) {

				var useCache =
						camera === _currentCamera &&
						material.id === _currentMaterialId;

				// we might want to call this function with some ClippingGroup
				// object instead of the material, once it becomes feasible
				// (#8465, #8379)
T
tschw 已提交
1616
				_clipping.setState(
T
tschw 已提交
1617 1618 1619 1620 1621 1622
						material.clippingPlanes, material.clipShadows,
						camera, materialProperties, useCache );

			}

			if ( materialProperties.numClippingPlanes !== undefined &&
T
tschw 已提交
1623
				materialProperties.numClippingPlanes !== _clipping.numPlanes ) {
T
tschw 已提交
1624 1625 1626 1627 1628 1629 1630

				material.needsUpdate = true;

			}

		}

1631 1632 1633 1634 1635 1636
		if ( materialProperties.program === undefined ) {

			material.needsUpdate = true;

		}

1637 1638
		if ( materialProperties.lightsHash !== undefined &&
			materialProperties.lightsHash !== _lights.hash ) {
1639 1640 1641 1642 1643 1644

			material.needsUpdate = true;

		}

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

1646
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1647 1648 1649 1650
			material.needsUpdate = false;

		}

1651
		var refreshProgram = false;
M
Mr.doob 已提交
1652
		var refreshMaterial = false;
1653
		var refreshLights = false;
M
Mr.doob 已提交
1654

1655
		var program = materialProperties.program,
1656
			p_uniforms = program.getUniforms(),
1657
			m_uniforms = materialProperties.__webglShader.uniforms;
M
Mr.doob 已提交
1658

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

1661 1662
			_gl.useProgram( program.program );
			_currentProgram = program.id;
M
Mr.doob 已提交
1663

1664
			refreshProgram = true;
M
Mr.doob 已提交
1665
			refreshMaterial = true;
1666
			refreshLights = true;
M
Mr.doob 已提交
1667 1668 1669 1670 1671 1672

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1673

M
Mr.doob 已提交
1674 1675 1676 1677
			refreshMaterial = true;

		}

1678
		if ( refreshProgram || camera !== _currentCamera ) {
M
Mr.doob 已提交
1679

T
tschw 已提交
1680
			p_uniforms.set( _gl, camera, 'projectionMatrix' );
M
Mr.doob 已提交
1681

G
gero3 已提交
1682
			if ( capabilities.logarithmicDepthBuffer ) {
1683

T
tschw 已提交
1684 1685
				p_uniforms.setValue( _gl, 'logDepthBufFC',
						2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1686 1687 1688 1689

			}


1690 1691 1692 1693 1694 1695 1696 1697 1698
			if ( camera !== _currentCamera ) {

				_currentCamera = camera;

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

				refreshMaterial = true;		// set to true on material change
T
tschw 已提交
1699
				refreshLights = true;		// remains set until update done
1700 1701

			}
M
Mr.doob 已提交
1702

1703 1704 1705 1706 1707
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
1708
				 material instanceof THREE.MeshStandardMaterial ||
1709 1710
				 material.envMap ) {

T
tschw 已提交
1711 1712 1713
				var uCamPos = p_uniforms.map.cameraPosition;

				if ( uCamPos !== undefined ) {
1714

T
tschw 已提交
1715 1716
					uCamPos.setValue( _gl,
							_vector3.setFromMatrixPosition( camera.matrixWorld ) );
1717 1718 1719 1720 1721 1722 1723

				}

			}

			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
1724
				 material instanceof THREE.MeshBasicMaterial ||
1725
				 material instanceof THREE.MeshStandardMaterial ||
1726 1727 1728
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {

T
tschw 已提交
1729
				p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
1730 1731 1732

			}

T
tschw 已提交
1733 1734
			p_uniforms.set( _gl, _this, 'toneMappingExposure' );
			p_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );
M
Mr.doob 已提交
1735

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

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

T
tschw 已提交
1744 1745
			p_uniforms.setOptional( _gl, object, 'bindMatrix' );
			p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
1746

T
tschw 已提交
1747
			var skeleton = object.skeleton;
1748

T
tschw 已提交
1749
			if ( skeleton ) {
1750

T
tschw 已提交
1751
				if ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) {
M
Mr.doob 已提交
1752

T
tschw 已提交
1753 1754 1755
					p_uniforms.set( _gl, skeleton, 'boneTexture' );
					p_uniforms.set( _gl, skeleton, 'boneTextureWidth' );
					p_uniforms.set( _gl, skeleton, 'boneTextureHeight' );
M
Mr.doob 已提交
1756

T
tschw 已提交
1757
				} else {
M
Mr.doob 已提交
1758

T
tschw 已提交
1759
					p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
M
Mr.doob 已提交
1760 1761 1762 1763 1764 1765 1766 1767 1768

				}

			}

		}

		if ( refreshMaterial ) {

M
Mr.doob 已提交
1769
			if ( material.lights ) {
M
Mr.doob 已提交
1770

1771
				// the current material requires lighting info
M
Mr.doob 已提交
1772

T
tschw 已提交
1773 1774 1775 1776 1777 1778
				// note: all lighting uniforms are always set correctly
				// they simply reference the renderer's state for their
				// values
				//
				// use the current material's .needsUpdate flags to set
				// the GL state when required
M
Mr.doob 已提交
1779

T
tschw 已提交
1780
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1781

T
tschw 已提交
1782
			}
G
gero3 已提交
1783

T
tschw 已提交
1784
			// refresh uniforms common to several materials
G
gero3 已提交
1785

T
tschw 已提交
1786
			if ( fog && material.fog ) {
G
gero3 已提交
1787

T
tschw 已提交
1788
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1789 1790 1791 1792 1793

			}

			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
W
WestLangley 已提交
1794
				 material instanceof THREE.MeshPhongMaterial ||
W
WestLangley 已提交
1795 1796
				 material instanceof THREE.MeshStandardMaterial ||
				 material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812

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

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

M
Mr.doob 已提交
1815
				refreshUniformsPoints( m_uniforms, material );
M
Mr.doob 已提交
1816

1817 1818 1819 1820
			} else if ( material instanceof THREE.MeshLambertMaterial ) {

				refreshUniformsLambert( m_uniforms, material );

M
Mr.doob 已提交
1821 1822 1823 1824
			} else if ( material instanceof THREE.MeshPhongMaterial ) {

				refreshUniformsPhong( m_uniforms, material );

W
WestLangley 已提交
1825 1826 1827 1828
			} else if ( material instanceof THREE.MeshPhysicalMaterial ) {

				refreshUniformsPhysical( m_uniforms, material );

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

1831
				refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1832

M
Mr.doob 已提交
1833 1834
			} else if ( material instanceof THREE.MeshDepthMaterial ) {

1835 1836 1837 1838 1839 1840 1841 1842
				if ( material.displacementMap ) {

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

				}

M
Mr.doob 已提交
1843 1844 1845 1846 1847 1848
			} else if ( material instanceof THREE.MeshNormalMaterial ) {

				m_uniforms.opacity.value = material.opacity;

			}

T
tschw 已提交
1849 1850
			THREE.WebGLUniforms.upload(
					_gl, materialProperties.uniformsList, m_uniforms, _this );
A
arose 已提交
1851 1852 1853

		}

M
Mr.doob 已提交
1854

T
tschw 已提交
1855
		// common matrices
M
Mr.doob 已提交
1856

T
tschw 已提交
1857 1858 1859
		p_uniforms.set( _gl, object, 'modelViewMatrix' );
		p_uniforms.set( _gl, object, 'normalMatrix' );
		p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
A
arose 已提交
1860 1861


T
tschw 已提交
1862
		// dynamic uniforms
A
arose 已提交
1863

T
tschw 已提交
1864
		var dynUniforms = materialProperties.dynamicUniforms;
A
arose 已提交
1865

T
tschw 已提交
1866
		if ( dynUniforms !== null ) {
A
arose 已提交
1867

T
tschw 已提交
1868 1869
			THREE.WebGLUniforms.evalDynamic(
					dynUniforms, m_uniforms, object, camera );
A
arose 已提交
1870

T
tschw 已提交
1871
			THREE.WebGLUniforms.upload( _gl, dynUniforms, m_uniforms, _this );
A
arose 已提交
1872 1873 1874

		}

T
tschw 已提交
1875
		return program;
A
arose 已提交
1876 1877 1878

	}

M
Mr.doob 已提交
1879 1880 1881 1882 1883 1884
	// Uniforms (refresh uniforms objects)

	function refreshUniformsCommon ( uniforms, material ) {

		uniforms.opacity.value = material.opacity;

1885
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
1886

1887
		if ( material.emissive ) {
M
Mr.doob 已提交
1888

1889
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
1890 1891 1892

		}

1893 1894 1895
		uniforms.map.value = material.map;
		uniforms.specularMap.value = material.specularMap;
		uniforms.alphaMap.value = material.alphaMap;
M
Mr.doob 已提交
1896

1897
		if ( material.aoMap ) {
1898

1899 1900
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1901 1902 1903

		}

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

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

1922 1923 1924 1925
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
1926 1927 1928 1929 1930 1931 1932 1933
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

1934 1935 1936 1937 1938 1939 1940 1941
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

1942 1943 1944 1945
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

1946 1947 1948 1949
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
1950 1951 1952 1953
		}

		if ( uvScaleMap !== undefined ) {

1954
			// backwards compatibility
M
Mr.doob 已提交
1955 1956 1957 1958 1959 1960
			if ( uvScaleMap instanceof THREE.WebGLRenderTarget ) {

				uvScaleMap = uvScaleMap.texture;

			}

M
Mr.doob 已提交
1961 1962 1963 1964 1965 1966 1967 1968
			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;
1969 1970 1971 1972 1973 1974

		// don't flip CubeTexture envMaps, flip everything else:
		//  WebGLRenderTargetCube will be flipped for backwards compatibility
		//  WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture
		// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future
		uniforms.flipEnvMap.value = ( ! ( material.envMap instanceof THREE.CubeTexture ) ) ? 1 : - 1;
M
Mr.doob 已提交
1975

1976
		uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
1977 1978
		uniforms.refractionRatio.value = material.refractionRatio;

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

	function refreshUniformsLine ( uniforms, material ) {

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

M
Mr.doob 已提交
1986
	}
M
Mr.doob 已提交
1987 1988 1989 1990 1991 1992 1993

	function refreshUniformsDash ( uniforms, material ) {

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

M
Mr.doob 已提交
1994
	}
M
Mr.doob 已提交
1995

M
Mr.doob 已提交
1996
	function refreshUniformsPoints ( uniforms, material ) {
M
Mr.doob 已提交
1997

1998
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
1999
		uniforms.opacity.value = material.opacity;
2000
		uniforms.size.value = material.size * _pixelRatio;
T
tschw 已提交
2001
		uniforms.scale.value = _canvas.clientHeight * 0.5;
M
Mr.doob 已提交
2002 2003 2004

		uniforms.map.value = material.map;

2005 2006 2007 2008 2009 2010 2011 2012 2013
		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 已提交
2014
	}
M
Mr.doob 已提交
2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030

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

2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049
	function refreshUniformsLambert ( uniforms, material ) {

		if ( material.lightMap ) {

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

		}

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

M
Mr.doob 已提交
2050 2051
	function refreshUniformsPhong ( uniforms, material ) {

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

2055 2056 2057 2058
		if ( material.lightMap ) {

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

2060
		}
2061

2062
		if ( material.emissiveMap ) {
2063

2064
			uniforms.emissiveMap.value = material.emissiveMap;
2065

2066
		}
M
Mr.doob 已提交
2067

2068 2069 2070 2071
		if ( material.bumpMap ) {

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

2073
		}
M
Mr.doob 已提交
2074

2075 2076 2077 2078 2079 2080
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2081

2082 2083 2084 2085 2086
		if ( material.displacementMap ) {

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

2088
		}
2089 2090 2091

	}

2092
	function refreshUniformsStandard ( uniforms, material ) {
W
WestLangley 已提交
2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152

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

		if ( material.roughnessMap ) {

			uniforms.roughnessMap.value = material.roughnessMap;

		}

		if ( material.metalnessMap ) {

			uniforms.metalnessMap.value = material.metalnessMap;

		}

		if ( material.lightMap ) {

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

		}

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

		if ( material.bumpMap ) {

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

		}

		if ( material.normalMap ) {

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

		}

		if ( material.displacementMap ) {

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

		}

		if ( material.envMap ) {

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

		}

	}

W
WestLangley 已提交
2153 2154 2155 2156 2157 2158
	function refreshUniformsPhysical ( uniforms, material ) {

		refreshUniformsStandard( uniforms, material );

	}

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

M
Mr.doob 已提交
2161
	function markUniformsLightsNeedsUpdate ( uniforms, value ) {
2162

M
Mr.doob 已提交
2163
		uniforms.ambientLightColor.needsUpdate = value;
2164

B
Ben Houston 已提交
2165 2166 2167 2168
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
		uniforms.hemisphereLights.needsUpdate = value;
2169

M
Mr.doob 已提交
2170
	}
2171

T
tschw 已提交
2172
	// Lighting
M
Mr.doob 已提交
2173

2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193
	function setupShadows ( lights ) {

		var lightShadowsLength = 0;

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

			var light = lights[ i ];

			if ( light.castShadow ) {

				_lights.shadows[ lightShadowsLength ++ ] = light;

			}

		}

		_lights.shadows.length = lightShadowsLength;

	}

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

B
brason 已提交
2196
		var l, ll, light,
M
Mr.doob 已提交
2197
		r = 0, g = 0, b = 0,
B
Ben Houston 已提交
2198
		color,
B
brason 已提交
2199
		intensity,
M
Mr.doob 已提交
2200
		distance,
2201
		shadowMap,
M
Mr.doob 已提交
2202

2203
		viewMatrix = camera.matrixWorldInverse,
M
Mr.doob 已提交
2204

M
Mr.doob 已提交
2205
		directionalLength = 0,
M
Mr.doob 已提交
2206 2207
		pointLength = 0,
		spotLength = 0,
2208
		hemiLength = 0;
M
Mr.doob 已提交
2209 2210 2211 2212 2213 2214 2215 2216 2217

		for ( l = 0, ll = lights.length; l < ll; l ++ ) {

			light = lights[ l ];

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

2218
			shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;
2219

M
Mr.doob 已提交
2220 2221
			if ( light instanceof THREE.AmbientLight ) {

2222 2223 2224
				r += color.r * intensity;
				g += color.g * intensity;
				b += color.b * intensity;
M
Mr.doob 已提交
2225 2226 2227

			} else if ( light instanceof THREE.DirectionalLight ) {

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

2230
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
M
Mr.doob 已提交
2231
				uniforms.direction.setFromMatrixPosition( light.matrixWorld );
2232
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
M
Mr.doob 已提交
2233 2234 2235
				uniforms.direction.sub( _vector3 );
				uniforms.direction.transformDirection( viewMatrix );

2236
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2237

2238
				if ( light.castShadow ) {
M
Mr.doob 已提交
2239

2240 2241 2242
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;
2243

2244 2245
				}

2246
				_lights.directionalShadowMap[ directionalLength ] = shadowMap;
2247
				_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
2248
				_lights.directional[ directionalLength ++ ] = uniforms;
M
Mr.doob 已提交
2249

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

M
Mr.doob 已提交
2252
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2253 2254 2255

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

M
Mr.doob 已提交
2257 2258 2259 2260 2261 2262 2263 2264
				uniforms.color.copy( color ).multiplyScalar( intensity );
				uniforms.distance = distance;

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

2265 2266
				uniforms.coneCos = Math.cos( light.angle );
				uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
M
Mr.doob 已提交
2267
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
M
Mr.doob 已提交
2268

2269
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2270

2271 2272
				if ( light.castShadow ) {

2273 2274 2275
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;
2276

2277 2278
				}

2279
				_lights.spotShadowMap[ spotLength ] = shadowMap;
2280
				_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;
M
Mr.doob 已提交
2281
				_lights.spot[ spotLength ++ ] = uniforms;
2282

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

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

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

M
Mr.doob 已提交
2290 2291
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
				uniforms.distance = light.distance;
M
Mr.doob 已提交
2292 2293
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;

2294
				uniforms.shadow = light.castShadow;
2295

M
Mr.doob 已提交
2296
				if ( light.castShadow ) {
2297

2298 2299 2300 2301 2302
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;

				}
2303

2304
				_lights.pointShadowMap[ pointLength ] = shadowMap;
2305

2306 2307 2308
				if ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {

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

2310 2311
				}

2312 2313 2314 2315 2316
				// for point lights we set the shadow matrix to be a translation-only matrix
				// equal to inverse of the light's position
				_vector3.setFromMatrixPosition( light.matrixWorld ).negate();
				_lights.pointShadowMatrix[ pointLength ].identity().setPosition( _vector3 );

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

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

M
Mr.doob 已提交
2321
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2322 2323 2324 2325

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

M
Mr.doob 已提交
2327 2328
				uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
				uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
M
Mr.doob 已提交
2329

M
Mr.doob 已提交
2330
				_lights.hemi[ hemiLength ++ ] = uniforms;
M
Mr.doob 已提交
2331 2332 2333 2334 2335

			}

		}

M
Mr.doob 已提交
2336 2337 2338
		_lights.ambient[ 0 ] = r;
		_lights.ambient[ 1 ] = g;
		_lights.ambient[ 2 ] = b;
M
Mr.doob 已提交
2339

M
Mr.doob 已提交
2340 2341
		_lights.directional.length = directionalLength;
		_lights.spot.length = spotLength;
2342
		_lights.point.length = pointLength;
M
Mr.doob 已提交
2343
		_lights.hemi.length = hemiLength;
2344

2345
		_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + hemiLength + ',' + _lights.shadows.length;
2346

M
Mr.doob 已提交
2347
	}
M
Mr.doob 已提交
2348 2349 2350 2351 2352

	// GL state setting

	this.setFaceCulling = function ( cullFace, frontFaceDirection ) {

T
tschw 已提交
2353 2354
		state.setCullFace( cullFace );
		state.setFlipSided( frontFaceDirection === THREE.FrontFaceDirectionCW );
M
Mr.doob 已提交
2355 2356 2357 2358 2359

	};

	// Textures

T
tschw 已提交
2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375
	function allocTextureUnit() {

		var textureUnit = _usedTextureUnits;

		if ( textureUnit >= capabilities.maxTextures ) {

			console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );

		}

		_usedTextureUnits += 1;

		return textureUnit;

	}

2376
	this.allocTextureUnit = allocTextureUnit;
T
tschw 已提交
2377

2378
	// this.setTexture2D = setTexture2D;
2379
	this.setTexture2D = ( function() {
T
tschw 已提交
2380

2381
		var warned = false;
T
tschw 已提交
2382

2383 2384
		// backwards compatibility: peel texture.texture
		return function( texture, slot ) {
T
tschw 已提交
2385

2386
			if ( texture instanceof THREE.WebGLRenderTarget ) {
T
tschw 已提交
2387

2388
				if ( ! warned ) {
T
tschw 已提交
2389

2390 2391
					console.warn( "THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead." );
					warned = true;
T
tschw 已提交
2392

2393
				}
T
tschw 已提交
2394

2395
				texture = texture.texture;
T
tschw 已提交
2396

2397
			}
T
tschw 已提交
2398

2399
			textures.setTexture2D( texture, slot );
T
tschw 已提交
2400

2401
		};
T
tschw 已提交
2402

2403
	}() );
T
tschw 已提交
2404

2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417
	this.setTexture = ( function() {

		var warned = false;

		return function( texture, slot ) {

			if ( ! warned ) {

				console.warn( "THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead." );
				warned = true;

			}

2418
			textures.setTexture2D( texture, slot );
2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451

		};

	}() );

	this.setTextureCube = ( function() {

		var warned = false;

		return function( texture, slot ) {

			// backwards compatibility: peel texture.texture
			if ( texture instanceof THREE.WebGLRenderTargetCube ) {

				if ( ! warned ) {

					console.warn( "THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead." );
					warned = true;

				}

				texture = texture.texture;

			}

			// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture
			// TODO: unify these code paths
			if ( texture instanceof THREE.CubeTexture ||
				 ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {

				// CompressedTexture can have Array in image :/

				// this function alone should take care of cube textures
2452
				textures.setTextureCube( texture, slot );
2453 2454 2455 2456 2457

			} else {

				// assumed: texture property of THREE.WebGLRenderTargetCube

2458
				textures.setTextureCubeDynamic( texture, slot );
2459 2460 2461 2462 2463 2464

			}

		};

	}() );
T
tschw 已提交
2465

2466 2467 2468 2469
	this.getCurrentRenderTarget = function() {

		return _currentRenderTarget;

M
Michael Herzog 已提交
2470
	};
2471

2472
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
2473

2474 2475
		_currentRenderTarget = renderTarget;

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

2478
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2479 2480 2481

		}

2482
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
2483
		var framebuffer;
M
Mr.doob 已提交
2484 2485 2486

		if ( renderTarget ) {

2487
			var renderTargetProperties = properties.get( renderTarget );
F
Fordy 已提交
2488

M
Mr.doob 已提交
2489 2490
			if ( isCube ) {

2491
				framebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
2492 2493 2494

			} else {

2495
				framebuffer = renderTargetProperties.__webglFramebuffer;
M
Mr.doob 已提交
2496 2497 2498

			}

2499 2500
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2501

2502
			_currentViewport.copy( renderTarget.viewport );
M
Mr.doob 已提交
2503 2504 2505 2506 2507

		} else {

			framebuffer = null;

2508
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
2509
			_currentScissorTest = _scissorTest;
2510

2511
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
M
Mr.doob 已提交
2512 2513 2514

		}

M
Mr.doob 已提交
2515
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2516 2517 2518 2519 2520 2521

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

		}

2522 2523
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2524

2525
		state.viewport( _currentViewport );
2526

M
Mr.doob 已提交
2527 2528 2529
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
2530
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
2531 2532 2533

		}

M
Mr.doob 已提交
2534 2535
	};

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

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

2540
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2541
			return;
2542

G
gero3 已提交
2543
		}
2544

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

M
Mr.doob 已提交
2547
		if ( framebuffer ) {
2548

G
gero3 已提交
2549
			var restore = false;
2550

M
Mr.doob 已提交
2551
			if ( framebuffer !== _currentFramebuffer ) {
2552

M
Mr.doob 已提交
2553
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2554

G
gero3 已提交
2555
				restore = true;
2556

G
gero3 已提交
2557
			}
2558

M
Mr.doob 已提交
2559
			try {
2560

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

M
Michael Herzog 已提交
2563
				if ( texture.format !== THREE.RGBAFormat && paramThreeToGL( texture.format ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
2564

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

M
Mr.doob 已提交
2568
				}
2569

M
Michael Herzog 已提交
2570 2571 2572 2573
				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' ) ) ) {
2574

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

M
Mr.doob 已提交
2578
				}
2579

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

2582 2583
					// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)

2584
					if ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {
2585 2586 2587 2588

						_gl.readPixels( x, y, width, height, paramThreeToGL( texture.format ), paramThreeToGL( texture.type ), buffer );

					}
2589

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

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

				}
M
Mr.doob 已提交
2595

M
Mr.doob 已提交
2596
			} finally {
M
Mr.doob 已提交
2597

M
Mr.doob 已提交
2598 2599 2600
				if ( restore ) {

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

M
Mr.doob 已提交
2602 2603 2604
				}

			}
M
Mr.doob 已提交
2605 2606 2607

		}

M
Mr.doob 已提交
2608 2609
	};

M
Mr.doob 已提交
2610 2611 2612 2613
	// Map three.js constants to WebGL constants

	function paramThreeToGL ( p ) {

2614 2615
		var extension;

M
Mr.doob 已提交
2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639
		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;

2640 2641 2642 2643 2644 2645 2646 2647
		extension = extensions.get( 'OES_texture_half_float' );

		if ( extension !== null ) {

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

		}

M
Mr.doob 已提交
2648 2649 2650 2651 2652
		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;
2653
		if ( p === THREE.DepthFormat ) return _gl.DEPTH_COMPONENT;
M
Mr.doob 已提交
2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671

		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;

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

2674 2675 2676 2677 2678 2679
		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 已提交
2680 2681 2682

		}

2683 2684 2685
		extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );

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

2687 2688 2689 2690
			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 已提交
2691 2692 2693

		}

2694 2695 2696 2697 2698 2699 2700 2701
		extension = extensions.get( 'WEBGL_compressed_texture_etc1' );

		if ( extension !== null ) {

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

		}

2702 2703 2704
		extension = extensions.get( 'EXT_blend_minmax' );

		if ( extension !== null ) {
2705

2706 2707
			if ( p === THREE.MinEquation ) return extension.MIN_EXT;
			if ( p === THREE.MaxEquation ) return extension.MAX_EXT;
2708 2709 2710

		}

M
Mr.doob 已提交
2711 2712
		return 0;

M
Mr.doob 已提交
2713
	}
M
Mr.doob 已提交
2714 2715

};