WebGLRenderer.js 63.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
	//

M
Mr.doob 已提交
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
	var backgroundCamera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
	var backgroundCamera2 = new THREE.PerspectiveCamera();
	var backgroundPlaneMesh = new THREE.Mesh(
		new THREE.PlaneBufferGeometry( 2, 2 ),
		new THREE.MeshBasicMaterial( { depthTest: false, depthWrite: false } )
	);
	var backgroundBoxShader = THREE.ShaderLib[ 'cube' ];
	var backgroundBoxMesh = new THREE.Mesh(
		new THREE.BoxBufferGeometry( 5, 5, 5 ),
		new THREE.ShaderMaterial( {
			uniforms: backgroundBoxShader.uniforms,
			vertexShader: backgroundBoxShader.vertexShader,
			fragmentShader: backgroundBoxShader.fragmentShader,
			depthTest: false,
			depthWrite: false,
			side: THREE.BackSide
		} )
	);
	objects.update( backgroundPlaneMesh );
	objects.update( backgroundBoxMesh );

	//

287 288
	function getTargetPixelRatio() {

289
		return _currentRenderTarget === null ? _pixelRatio : 1;
290 291 292

	}

293
	function glClearColor( r, g, b, a ) {
294 295 296

		if ( _premultipliedAlpha === true ) {

297
			r *= a; g *= a; b *= a;
298 299 300

		}

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

303
	}
304

305
	function setDefaultGLState() {
M
Mr.doob 已提交
306

M
Mr.doob 已提交
307
		state.init();
M
Mr.doob 已提交
308

309 310
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
M
Mr.doob 已提交
311

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

314
	}
315

316
	function resetGLState() {
317 318 319 320

		_currentProgram = null;
		_currentCamera = null;

321
		_currentGeometryProgram = '';
322 323
		_currentMaterialId = - 1;

M
Mr.doob 已提交
324 325
		state.reset();

326
	}
M
Mr.doob 已提交
327 328 329 330

	setDefaultGLState();

	this.context = _gl;
M
Mr.doob 已提交
331
	this.capabilities = capabilities;
332
	this.extensions = extensions;
333
	this.properties = properties;
M
Mr.doob 已提交
334
	this.state = state;
M
Mr.doob 已提交
335

M
Mr.doob 已提交
336 337
	// shadow map

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

340
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
341

M
Mr.doob 已提交
342

M
Mr.doob 已提交
343 344 345 346 347
	// Plugins

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

M
Mr.doob 已提交
348 349 350 351 352 353 354 355
	// API

	this.getContext = function () {

		return _gl;

	};

356 357 358 359 360 361
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

362 363 364 365 366 367
	this.forceContextLoss = function () {

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

	};

368
	this.getMaxAnisotropy = function () {
369

370
		return capabilities.getMaxAnisotropy();
371

372
	};
M
Mr.doob 已提交
373 374 375

	this.getPrecision = function () {

G
gero3 已提交
376
		return capabilities.precision;
M
Mr.doob 已提交
377 378 379

	};

380 381
	this.getPixelRatio = function () {

382
		return _pixelRatio;
383 384 385 386 387

	};

	this.setPixelRatio = function ( value ) {

388 389 390 391 392
		if ( value === undefined ) return;

		_pixelRatio = value;

		this.setSize( _viewport.z, _viewport.w, false );
393 394 395

	};

396 397 398
	this.getSize = function () {

		return {
399 400
			width: _width,
			height: _height
401 402 403 404
		};

	};

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

407 408 409
		_width = width;
		_height = height;

410 411
		_canvas.width = width * _pixelRatio;
		_canvas.height = height * _pixelRatio;
412

413
		if ( updateStyle !== false ) {
414

G
gero3 已提交
415 416
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
417

G
gero3 已提交
418
		}
M
Mr.doob 已提交
419

420
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
421 422 423 424 425

	};

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

426
		state.viewport( _viewport.set( x, y, width, height ) );
M
Mr.doob 已提交
427 428 429

	};

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

432
		state.scissor( _scissor.set( x, y, width, height ) );
M
Mr.doob 已提交
433 434 435

	};

436 437
	this.setScissorTest = function ( boolean ) {

438
		state.setScissorTest( _scissorTest = boolean );
M
Mr.doob 已提交
439 440 441 442 443

	};

	// Clearing

M
Mr.doob 已提交
444
	this.getClearColor = function () {
M
Mr.doob 已提交
445

M
Mr.doob 已提交
446
		return _clearColor;
M
Mr.doob 已提交
447 448 449

	};

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

M
Mr.doob 已提交
452
		_clearColor.set( color );
453

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

456
		glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
M
Mr.doob 已提交
457 458 459

	};

M
Mr.doob 已提交
460
	this.getClearAlpha = function () {
M
Mr.doob 已提交
461

M
Mr.doob 已提交
462
		return _clearAlpha;
M
Mr.doob 已提交
463 464 465

	};

M
Mr.doob 已提交
466
	this.setClearAlpha = function ( alpha ) {
M
Mr.doob 已提交
467

M
Mr.doob 已提交
468
		_clearAlpha = alpha;
M
Mr.doob 已提交
469

470
		glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
M
Mr.doob 已提交
471 472 473 474 475 476 477 478 479 480 481 482

	};

	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 );
483 484 485 486 487

	};

	this.clearColor = function () {

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

	};

	this.clearDepth = function () {

M
Mr.doob 已提交
494
		this.clear( false, true, false );
495 496 497 498 499

	};

	this.clearStencil = function () {

M
Mr.doob 已提交
500
		this.clear( false, false, true );
M
Mr.doob 已提交
501 502 503 504 505 506 507 508 509 510

	};

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

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

	};

M
Mr.doob 已提交
511 512
	// Reset

513
	this.resetGLState = resetGLState;
M
Mr.doob 已提交
514

D
dubejf 已提交
515 516
	this.dispose = function() {

517 518 519 520 521
		transparentObjects = [];
		transparentObjectsLastIndex = -1;
		opaqueObjects = [];
		opaqueObjectsLastIndex = -1;

D
dubejf 已提交
522 523 524 525
		_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );

	};

M
Mr.doob 已提交
526
	// Events
M
Mr.doob 已提交
527

D
dubejf 已提交
528 529 530 531 532 533 534 535 536
	function onContextLost( event ) {

		event.preventDefault();

		resetGLState();
		setDefaultGLState();

		properties.clear();

M
Mr.doob 已提交
537
	}
D
dubejf 已提交
538

539
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
540 541 542 543 544 545 546

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

547
	}
M
Mr.doob 已提交
548 549 550

	// Buffer deallocation

551
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
552

553 554 555 556
		releaseMaterialProgramReference( material );

		properties.delete( material );

557
	}
558 559


560
	function releaseMaterialProgramReference( material ) {
561

562
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
563 564 565

		material.program = undefined;

566
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
567

568
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
569

M
Mr.doob 已提交
570 571
		}

572
	}
M
Mr.doob 已提交
573 574 575 576 577

	// Buffer rendering

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

578
		state.initAttributes();
579

580
		var buffers = properties.get( object );
581

582 583 584 585
		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 已提交
586

587
		var attributes = program.getAttributes();
588

M
Mr.doob 已提交
589 590
		if ( object.hasPositions ) {

591
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
M
Mr.doob 已提交
592
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
593

594 595
			state.enableAttribute( attributes.position );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
596 597 598 599 600

		}

		if ( object.hasNormals ) {

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

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

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

607
					var array = object.normalArray;
M
Mr.doob 已提交
608

609 610 611
					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 已提交
612

613 614 615
					array[ i + 0 ] = nx;
					array[ i + 1 ] = ny;
					array[ i + 2 ] = nz;
M
Mr.doob 已提交
616

617 618 619
					array[ i + 3 ] = nx;
					array[ i + 4 ] = ny;
					array[ i + 5 ] = nz;
M
Mr.doob 已提交
620

621 622 623
					array[ i + 6 ] = nx;
					array[ i + 7 ] = ny;
					array[ i + 8 ] = nz;
M
Mr.doob 已提交
624 625 626 627 628 629

				}

			}

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

631
			state.enableAttribute( attributes.normal );
632

633
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
634 635 636 637 638

		}

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

639
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
M
Mr.doob 已提交
640
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
641

642
			state.enableAttribute( attributes.uv );
643

644
			_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
645 646 647 648 649

		}

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

650
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
M
Mr.doob 已提交
651
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
652

653
			state.enableAttribute( attributes.color );
654

655
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
656 657 658

		}

659
		state.disableUnusedAttributes();
660

M
Mr.doob 已提交
661 662 663 664 665 666
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

667
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
668

M
Mr.doob 已提交
669 670
		setMaterial( material );

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

M
Mr.doob 已提交
673 674
		var updateBuffers = false;
		var geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;
M
Mr.doob 已提交
675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697

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

			}

698
			activeInfluences.sort( absNumericalSort );
M
Mr.doob 已提交
699 700 701 702 703 704 705

			if ( activeInfluences.length > 8 ) {

				activeInfluences.length = 8;

			}

706 707
			var morphAttributes = geometry.morphAttributes;

M
Mr.doob 已提交
708 709 710 711 712 713 714
			for ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {

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

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

715
					var index = influence[ 1 ];
M
Mr.doob 已提交
716

717 718
					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 已提交
719 720 721

				} else {

722 723
					if ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );
					if ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );
M
Mr.doob 已提交
724 725 726 727 728

				}

			}

T
tschw 已提交
729 730
			program.getUniforms().setValue(
					_gl, 'morphTargetInfluences', morphInfluences );
M
Mr.doob 已提交
731 732 733 734 735

			updateBuffers = true;

		}

736 737
		//

738
		var index = geometry.index;
739 740
		var position = geometry.attributes.position;

741 742
		if ( material.wireframe === true ) {

743
			index = objects.getWireframeAttribute( geometry );
744 745 746

		}

747 748
		var renderer;

749
		if ( index !== null ) {
750

751 752
			renderer = indexedBufferRenderer;
			renderer.setIndex( index );
753

754
		} else {
755

756
			renderer = bufferRenderer;
757

758
		}
M
Mr.doob 已提交
759

760
		if ( updateBuffers ) {
M
Mr.doob 已提交
761

762
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
763

764
			if ( index !== null ) {
765

766
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );
767 768 769

			}

770
		}
771

772 773
		//

M
Mr.doob 已提交
774 775
		var dataStart = 0;
		var dataCount = Infinity;
776

M
Mr.doob 已提交
777
		if ( index !== null ) {
778

M
Mr.doob 已提交
779
			dataCount = index.count;
780

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

M
Mr.doob 已提交
783
			dataCount = position.count;
784

M
Mr.doob 已提交
785
		}
786

M
Mr.doob 已提交
787 788
		var rangeStart = geometry.drawRange.start;
		var rangeCount = geometry.drawRange.count;
789

M
Mr.doob 已提交
790 791
		var groupStart = group !== null ? group.start : 0;
		var groupCount = group !== null ? group.count : Infinity;
792

M
Mr.doob 已提交
793 794 795 796 797 798
		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 );

		//
799

800
		if ( object instanceof THREE.Mesh ) {
801

802
			if ( material.wireframe === true ) {
803

804
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
805
				renderer.setMode( _gl.LINES );
806

807
			} else {
M
Mr.doob 已提交
808 809

				switch ( object.drawMode ) {
810

B
Ben Adams 已提交
811 812 813 814 815 816 817 818 819 820 821 822 823
					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;

				}
824

825
			}
826

827

828
		} else if ( object instanceof THREE.Line ) {
829

830
			var lineWidth = material.linewidth;
831

832
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
833

834
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
835

836
			if ( object instanceof THREE.LineSegments ) {
837

838
				renderer.setMode( _gl.LINES );
839

840
			} else {
841

842
				renderer.setMode( _gl.LINE_STRIP );
843 844

			}
M
Mr.doob 已提交
845

846
		} else if ( object instanceof THREE.Points ) {
847 848

			renderer.setMode( _gl.POINTS );
849 850

		}
851

J
jfranc 已提交
852
		if ( geometry instanceof THREE.InstancedBufferGeometry ) {
M
Mr.doob 已提交
853 854 855

			if ( geometry.maxInstancedCount > 0 ) {

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

J
jfranc 已提交
858
			}
859 860 861

		} else {

M
Mr.doob 已提交
862
			renderer.render( drawStart, drawCount );
863

M
Mr.doob 已提交
864 865 866 867
		}

	};

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

M
Mr.doob 已提交
870
		var extension;
B
Ben Adams 已提交
871

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

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

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

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

M
Mr.doob 已提交
881 882 883
			}

		}
B
Ben Adams 已提交
884

885 886
		if ( startIndex === undefined ) startIndex = 0;

887 888
		state.initAttributes();

889
		var geometryAttributes = geometry.attributes;
890

891
		var programAttributes = program.getAttributes();
892

893
		var materialDefaultAttributeValues = material.defaultAttributeValues;
894

895
		for ( var name in programAttributes ) {
896

897
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
898

M
Mr.doob 已提交
899
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
900

901
				var geometryAttribute = geometryAttributes[ name ];
902

M
Mr.doob 已提交
903
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
904

905
					var type = _gl.FLOAT;
906
					var array = geometryAttribute.array;
907 908
					var normalized = geometryAttribute.normalized;

909 910
					if ( array instanceof Float32Array ) {

911
						type = _gl.FLOAT;
912 913 914 915 916 917 918

					} else if ( array instanceof Float64Array ) {

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

					} else if ( array instanceof Uint16Array ) {

919 920
						type = _gl.UNSIGNED_SHORT;

921 922
					} else if ( array instanceof Int16Array ) {

923
						type = _gl.SHORT;
924 925 926

					} else if ( array instanceof Uint32Array ) {

927
						type = _gl.UNSIGNED_INT;
928 929 930

					} else if ( array instanceof Int32Array ) {

931
						type = _gl.INT;
932 933 934

					} else if ( array instanceof Int8Array ) {

935
						type = _gl.BYTE;
936 937 938

					} else if ( array instanceof Uint8Array ) {

939
						type = _gl.UNSIGNED_BYTE;
940 941

					}
942

943
					var size = geometryAttribute.itemSize;
G
gero3 已提交
944
					var buffer = objects.getAttributeBuffer( geometryAttribute );
945

B
Ben Adams 已提交
946
					if ( geometryAttribute instanceof THREE.InterleavedBufferAttribute ) {
947

M
Mr.doob 已提交
948 949 950 951 952
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

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

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

M
Mr.doob 已提交
956
							if ( geometry.maxInstancedCount === undefined ) {
957

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

M
Mr.doob 已提交
960
							}
B
Ben Adams 已提交
961

M
Mr.doob 已提交
962
						} else {
B
Ben Adams 已提交
963

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

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

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

M
Mr.doob 已提交
971
					} else {
B
Ben Adams 已提交
972

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

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

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

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

M
Mr.doob 已提交
981
							}
B
Ben Adams 已提交
982

M
Mr.doob 已提交
983 984 985 986
						} else {

							state.enableAttribute( programAttribute );

M
Mr.doob 已提交
987
						}
B
Ben Adams 已提交
988

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

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

994 995
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
996
					var value = materialDefaultAttributeValues[ name ];
997

998
					if ( value !== undefined ) {
M
Mr.doob 已提交
999

1000
						switch ( value.length ) {
M
Mr.doob 已提交
1001

1002 1003 1004
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
1005

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

1010 1011 1012
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
1013

1014 1015
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
1016 1017

						}
M
Mr.doob 已提交
1018 1019 1020 1021 1022 1023 1024 1025

					}

				}

			}

		}
1026

1027
		state.disableUnusedAttributes();
1028

M
Mr.doob 已提交
1029 1030
	}

M
Mr.doob 已提交
1031 1032
	// Sorting

1033
	function absNumericalSort( a, b ) {
1034

1035
		return Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );
1036 1037 1038

	}

M
Mr.doob 已提交
1039 1040
	function painterSortStable ( a, b ) {

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

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

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

M
Mr.doob 已提交
1047
			return a.material.id - b.material.id;
1048 1049

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

M
Mr.doob 已提交
1051
			return a.z - b.z;
M
Mr.doob 已提交
1052 1053 1054

		} else {

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

		}

1059
	}
M
Mr.doob 已提交
1060

1061 1062
	function reversePainterSortStable ( a, b ) {

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

U
unconed 已提交
1065
			return a.object.renderOrder - b.object.renderOrder;
1066 1067

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

M
Mr.doob 已提交
1069
			return b.z - a.z;
1070 1071 1072 1073 1074 1075 1076

		} else {

			return a.id - b.id;

		}

1077
	}
1078

M
Mr.doob 已提交
1079 1080 1081 1082 1083 1084
	// Rendering

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

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

1085
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1086 1087 1088 1089
			return;

		}

M
Mr.doob 已提交
1090
		var fog = scene.fog;
M
Mr.doob 已提交
1091 1092 1093

		// reset caching for this frame

1094
		_currentGeometryProgram = '';
1095
		_currentMaterialId = - 1;
1096
		_currentCamera = null;
M
Mr.doob 已提交
1097 1098 1099

		// update scene graph

1100
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1101 1102 1103

		// update camera matrices and frustum

1104
		if ( camera.parent === null ) camera.updateMatrixWorld();
M
Mr.doob 已提交
1105 1106 1107 1108 1109 1110

		camera.matrixWorldInverse.getInverse( camera.matrixWorld );

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

M
Mr.doob 已提交
1111
		lights.length = 0;
1112

M
Mr.doob 已提交
1113 1114
		opaqueObjectsLastIndex = - 1;
		transparentObjectsLastIndex = - 1;
1115

M
Mr.doob 已提交
1116 1117 1118
		sprites.length = 0;
		lensFlares.length = 0;

T
tschw 已提交
1119
		_localClippingEnabled = this.localClippingEnabled;
M
Mr.doob 已提交
1120
		_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
T
tschw 已提交
1121

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

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

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

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

1132 1133
		}

M
Mr.doob 已提交
1134
		//
M
Mr.doob 已提交
1135

T
tschw 已提交
1136
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1137

1138 1139
		setupShadows( lights );

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

1142 1143
		setupLights( lights, camera );

T
tschw 已提交
1144
		if ( _clippingEnabled ) _clipping.endShadows();
T
tschw 已提交
1145

M
Mr.doob 已提交
1146 1147
		//

1148 1149 1150 1151
		_infoRender.calls = 0;
		_infoRender.vertices = 0;
		_infoRender.faces = 0;
		_infoRender.points = 0;
M
Mr.doob 已提交
1152

1153 1154 1155 1156 1157 1158
		if ( renderTarget === undefined ) {

			renderTarget = null;

		}

M
Mr.doob 已提交
1159 1160
		this.setRenderTarget( renderTarget );

M
Mr.doob 已提交
1161 1162 1163 1164 1165 1166 1167 1168
		//

		var background = scene.background;

		if ( background === null ) {

			glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );

1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181
		} else if ( background instanceof THREE.Color ) {

			glClearColor( background.r, background.g, background.b, 1 );

		}

		if ( this.autoClear || forceClear ) {

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

		}

		if ( background instanceof THREE.CubeTexture ) {
M
Mr.doob 已提交
1182

1183
			backgroundCamera2.projectionMatrix.copy( camera.projectionMatrix );
M
Mr.doob 已提交
1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198

			backgroundCamera2.matrixWorld.extractRotation( camera.matrixWorld );
			backgroundCamera2.matrixWorldInverse.getInverse( backgroundCamera2.matrixWorld );

			backgroundBoxMesh.material.uniforms[ "tCube" ].value = background;
			backgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundCamera2.matrixWorldInverse, backgroundBoxMesh.matrixWorld );

			_this.renderBufferDirect( backgroundCamera2, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );

		} else if ( background instanceof THREE.Texture ) {

			backgroundPlaneMesh.material.map = background;

			_this.renderBufferDirect( backgroundCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );

M
Mr.doob 已提交
1199 1200
		}

1201
		//
M
Mr.doob 已提交
1202 1203 1204

		if ( scene.overrideMaterial ) {

1205
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1206

1207 1208
			renderObjects( opaqueObjects, camera, fog, overrideMaterial );
			renderObjects( transparentObjects, camera, fog, overrideMaterial );
1209

M
Mr.doob 已提交
1210 1211 1212 1213
		} else {

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

M
Mr.doob 已提交
1214
			state.setBlending( THREE.NoBlending );
1215
			renderObjects( opaqueObjects, camera, fog );
M
Mr.doob 已提交
1216 1217 1218

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

1219
			renderObjects( transparentObjects, camera, fog );
M
Mr.doob 已提交
1220 1221 1222 1223 1224

		}

		// custom render plugins (post pass)

M
Mr.doob 已提交
1225
		spritePlugin.render( scene, camera );
1226
		lensFlarePlugin.render( scene, camera, _currentViewport );
M
Mr.doob 已提交
1227 1228 1229

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

M
Mr.doob 已提交
1230 1231
		if ( renderTarget ) {

1232
			textures.updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1233 1234 1235

		}

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

M
Mr.doob 已提交
1238 1239
		state.setDepthTest( true );
		state.setDepthWrite( true );
1240
		state.setColorWrite( true );
M
Mr.doob 已提交
1241 1242 1243 1244

		// _gl.finish();

	};
M
Mr.doob 已提交
1245

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

1248
		var array, index;
M
Mr.doob 已提交
1249

1250
		// allocate the next position in the appropriate array
M
Mr.doob 已提交
1251 1252 1253

		if ( material.transparent ) {

1254 1255
			array = transparentObjects;
			index = ++ transparentObjectsLastIndex;
M
Mr.doob 已提交
1256 1257 1258

		} else {

1259 1260 1261 1262 1263
			array = opaqueObjects;
			index = ++ opaqueObjectsLastIndex;

		}

1264 1265
		// recycle existing render item or grow the array

1266 1267 1268 1269 1270 1271 1272 1273 1274 1275
		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 已提交
1276 1277 1278

		} else {

1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289
			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 已提交
1290 1291 1292 1293 1294

		}

	}

M
Mr.doob 已提交
1295 1296
	// TODO Duplicated code (Frustum)

T
tschw 已提交
1297 1298 1299 1300 1301 1302 1303
	function isObjectViewable( object ) {

		var geometry = object.geometry;

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

M
Mr.doob 已提交
1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321
		_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 已提交
1322 1323

		if ( ! _frustum.intersectsSphere( sphere ) ) return false;
T
tschw 已提交
1324 1325 1326 1327

		var numPlanes = _clipping.numPlanes;

		if ( numPlanes === 0 ) return true;
T
tschw 已提交
1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339

		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 已提交
1340
		} while ( ++ i !== numPlanes );
T
tschw 已提交
1341 1342 1343 1344 1345

		return true;

	}

1346
	function projectObject( object, camera ) {
M
Mr.doob 已提交
1347

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

1350
		if ( object.layers.test( camera.layers ) ) {
M
Mr.doob 已提交
1351

1352
			if ( object instanceof THREE.Light ) {
M
Mr.doob 已提交
1353

1354
				lights.push( object );
M
Mr.doob 已提交
1355

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

M
Mr.doob 已提交
1358
				if ( object.frustumCulled === false || isSpriteViewable( object ) === true ) {
1359 1360 1361 1362

					sprites.push( object );

				}
M
Mr.doob 已提交
1363

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

1366
				lensFlares.push( object );
M
Mr.doob 已提交
1367

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

1370
				if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1371

1372 1373
					_vector3.setFromMatrixPosition( object.matrixWorld );
					_vector3.applyProjection( _projScreenMatrix );
M
Mr.doob 已提交
1374

1375
				}
1376

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

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

1381
				if ( object instanceof THREE.SkinnedMesh ) {
M
Mr.doob 已提交
1382

1383
					object.skeleton.update();
1384

1385
				}
1386

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

1389
					var material = object.material;
1390

1391
					if ( material.visible === true ) {
M
Mr.doob 已提交
1392

1393
						if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1394

1395 1396 1397 1398
							_vector3.setFromMatrixPosition( object.matrixWorld );
							_vector3.applyProjection( _projScreenMatrix );

						}
M
Mr.doob 已提交
1399

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

S
SUNAG 已提交
1402
						if ( material instanceof THREE.MultiMaterial ) {
1403

1404 1405
							var groups = geometry.groups;
							var materials = material.materials;
1406

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

1409 1410
								var group = groups[ i ];
								var groupMaterial = materials[ group.materialIndex ];
1411

1412
								if ( groupMaterial.visible === true ) {
1413

1414 1415 1416
									pushRenderItem( object, geometry, groupMaterial, _vector3.z, group );

								}
M
Mr.doob 已提交
1417

M
Mr.doob 已提交
1418
							}
M
Mr.doob 已提交
1419

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

1422
							pushRenderItem( object, geometry, material, _vector3.z, null );
1423

1424
						}
O
OpenShift guest 已提交
1425

1426
					}
M
Mr.doob 已提交
1427

1428
				}
M
Mr.doob 已提交
1429

1430
			}
M
Mr.doob 已提交
1431

M
Mr.doob 已提交
1432
		}
M
Mr.doob 已提交
1433

M
Mr.doob 已提交
1434
		var children = object.children;
M
Mr.doob 已提交
1435

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

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

1440
		}
1441

1442
	}
M
Mr.doob 已提交
1443

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

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

1448
			var renderItem = renderList[ i ];
M
Mr.doob 已提交
1449

1450
			var object = renderItem.object;
M
Mr.doob 已提交
1451 1452 1453
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
M
Mr.doob 已提交
1454

1455 1456
			object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
			object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
M
Mr.doob 已提交
1457

M
Mr.doob 已提交
1458
			if ( object instanceof THREE.ImmediateRenderObject ) {
M
Mr.doob 已提交
1459

M
Mr.doob 已提交
1460
				setMaterial( material );
M
Mr.doob 已提交
1461

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

M
Mr.doob 已提交
1464
				_currentGeometryProgram = '';
M
Mr.doob 已提交
1465

M
Mr.doob 已提交
1466
				object.render( function ( object ) {
M
Mr.doob 已提交
1467

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

M
Mr.doob 已提交
1470
				} );
1471

M
Mr.doob 已提交
1472
			} else {
M
Mr.doob 已提交
1473

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

M
Mr.doob 已提交
1476
			}
M
Mr.doob 已提交
1477

1478
		}
M
Mr.doob 已提交
1479

1480
	}
G
gero3 已提交
1481

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

1484
		var materialProperties = properties.get( material );
G
gero3 已提交
1485

T
tschw 已提交
1486
		var parameters = programCache.getParameters(
T
tschw 已提交
1487
				material, _lights, fog, _clipping.numPlanes, object );
T
tschw 已提交
1488

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

1491
		var program = materialProperties.program;
T
tschw 已提交
1492
		var programChange = true;
1493

1494
		if ( program === undefined ) {
B
Ben Adams 已提交
1495

M
Mr.doob 已提交
1496 1497
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1498

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

M
Mr.doob 已提交
1501
			// changed glsl or parameters
1502
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1503

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

T
tschw 已提交
1506
			// same glsl and uniform list
T
tschw 已提交
1507 1508
			return;

T
tschw 已提交
1509
		} else {
B
Ben Adams 已提交
1510

T
tschw 已提交
1511 1512
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1513 1514 1515

		}

1516
		if ( programChange ) {
B
Ben Adams 已提交
1517

1518
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1519

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

1522 1523 1524 1525 1526 1527
				materialProperties.__webglShader = {
					name: material.type,
					uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
					vertexShader: shader.vertexShader,
					fragmentShader: shader.fragmentShader
				};
B
Ben Adams 已提交
1528

1529
			} else {
B
Ben Adams 已提交
1530

1531 1532 1533 1534 1535 1536
				materialProperties.__webglShader = {
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
					fragmentShader: material.fragmentShader
				};
G
gero3 已提交
1537

1538
			}
G
gero3 已提交
1539

1540
			material.__webglShader = materialProperties.__webglShader;
G
gero3 已提交
1541

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

1544 1545
			materialProperties.program = program;
			material.program = program;
1546 1547 1548

		}

1549
		var attributes = program.getAttributes();
M
Mr.doob 已提交
1550 1551 1552 1553 1554

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

M
Mr.doob 已提交
1557
				if ( attributes[ 'morphTarget' + i ] >= 0 ) {
M
Mr.doob 已提交
1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

M
Mr.doob 已提交
1573
				if ( attributes[ 'morphNormal' + i ] >= 0 ) {
M
Mr.doob 已提交
1574 1575 1576 1577 1578 1579 1580 1581 1582

					material.numSupportedMorphNormals ++;

				}

			}

		}

T
tschw 已提交
1583 1584 1585 1586 1587 1588
		var uniforms = materialProperties.__webglShader.uniforms;

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

T
tschw 已提交
1589 1590
			materialProperties.numClippingPlanes = _clipping.numPlanes;
			uniforms.clippingPlanes = _clipping.uniform;
T
tschw 已提交
1591 1592 1593

		}

M
Mr.doob 已提交
1594
		if ( material.lights ) {
1595

1596 1597
			// store the light setup it was created for

1598 1599
			materialProperties.lightsHash = _lights.hash;

1600 1601 1602 1603 1604
			// 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 已提交
1605
			uniforms.pointLights.value = _lights.point;
1606 1607
			uniforms.hemisphereLights.value = _lights.hemi;

1608 1609 1610 1611 1612 1613
			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;
1614

1615 1616
		}

T
tschw 已提交
1617 1618 1619
		var progUniforms = materialProperties.program.getUniforms(),
			uniformsList =
					THREE.WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
A
arose 已提交
1620

T
tschw 已提交
1621 1622 1623
		materialProperties.uniformsList = uniformsList;
		materialProperties.dynamicUniforms =
				THREE.WebGLUniforms.splitDynamic( uniformsList, uniforms );
A
arose 已提交
1624

M
Mr.doob 已提交
1625
	}
M
Mr.doob 已提交
1626

1627 1628
	function setMaterial( material ) {

T
tschw 已提交
1629 1630 1631 1632 1633 1634
		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 已提交
1635

1636 1637
		if ( material.transparent === true ) {

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

1640 1641 1642 1643
		} else {

			state.setBlending( THREE.NoBlending );

1644 1645
		}

B
Ben Adams 已提交
1646
		state.setDepthFunc( material.depthFunc );
M
Mr.doob 已提交
1647 1648
		state.setDepthTest( material.depthTest );
		state.setDepthWrite( material.depthWrite );
1649
		state.setColorWrite( material.colorWrite );
M
Mr.doob 已提交
1650
		state.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
1651 1652 1653

	}

1654
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1655 1656 1657

		_usedTextureUnits = 0;

1658
		var materialProperties = properties.get( material );
1659

T
tschw 已提交
1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670
		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 已提交
1671
				_clipping.setState(
T
tschw 已提交
1672 1673 1674 1675 1676 1677
						material.clippingPlanes, material.clipShadows,
						camera, materialProperties, useCache );

			}

			if ( materialProperties.numClippingPlanes !== undefined &&
T
tschw 已提交
1678
				materialProperties.numClippingPlanes !== _clipping.numPlanes ) {
T
tschw 已提交
1679 1680 1681 1682 1683 1684 1685

				material.needsUpdate = true;

			}

		}

1686 1687 1688 1689 1690 1691
		if ( materialProperties.program === undefined ) {

			material.needsUpdate = true;

		}

1692 1693
		if ( materialProperties.lightsHash !== undefined &&
			materialProperties.lightsHash !== _lights.hash ) {
1694 1695 1696 1697 1698 1699

			material.needsUpdate = true;

		}

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

1701
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1702 1703 1704 1705
			material.needsUpdate = false;

		}

1706
		var refreshProgram = false;
M
Mr.doob 已提交
1707
		var refreshMaterial = false;
1708
		var refreshLights = false;
M
Mr.doob 已提交
1709

1710
		var program = materialProperties.program,
1711
			p_uniforms = program.getUniforms(),
1712
			m_uniforms = materialProperties.__webglShader.uniforms;
M
Mr.doob 已提交
1713

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

1716 1717
			_gl.useProgram( program.program );
			_currentProgram = program.id;
M
Mr.doob 已提交
1718

1719
			refreshProgram = true;
M
Mr.doob 已提交
1720
			refreshMaterial = true;
1721
			refreshLights = true;
M
Mr.doob 已提交
1722 1723 1724 1725 1726 1727

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1728

M
Mr.doob 已提交
1729 1730 1731 1732
			refreshMaterial = true;

		}

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

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

G
gero3 已提交
1737
			if ( capabilities.logarithmicDepthBuffer ) {
1738

T
tschw 已提交
1739 1740
				p_uniforms.setValue( _gl, 'logDepthBufFC',
						2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1741 1742 1743 1744

			}


1745 1746 1747 1748 1749 1750 1751 1752 1753
			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 已提交
1754
				refreshLights = true;		// remains set until update done
1755 1756

			}
M
Mr.doob 已提交
1757

1758 1759 1760 1761 1762
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
1763
				 material instanceof THREE.MeshStandardMaterial ||
1764 1765
				 material.envMap ) {

T
tschw 已提交
1766 1767 1768
				var uCamPos = p_uniforms.map.cameraPosition;

				if ( uCamPos !== undefined ) {
1769

T
tschw 已提交
1770 1771
					uCamPos.setValue( _gl,
							_vector3.setFromMatrixPosition( camera.matrixWorld ) );
1772 1773 1774 1775 1776 1777 1778

				}

			}

			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
1779
				 material instanceof THREE.MeshBasicMaterial ||
1780
				 material instanceof THREE.MeshStandardMaterial ||
1781 1782 1783
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {

T
tschw 已提交
1784
				p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
1785 1786 1787

			}

T
tschw 已提交
1788 1789
			p_uniforms.set( _gl, _this, 'toneMappingExposure' );
			p_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );
M
Mr.doob 已提交
1790

M
Mr.doob 已提交
1791 1792 1793 1794 1795 1796 1797 1798
		}

		// 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 已提交
1799 1800
			p_uniforms.setOptional( _gl, object, 'bindMatrix' );
			p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
1801

T
tschw 已提交
1802
			var skeleton = object.skeleton;
1803

T
tschw 已提交
1804
			if ( skeleton ) {
1805

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

T
tschw 已提交
1808 1809 1810
					p_uniforms.set( _gl, skeleton, 'boneTexture' );
					p_uniforms.set( _gl, skeleton, 'boneTextureWidth' );
					p_uniforms.set( _gl, skeleton, 'boneTextureHeight' );
M
Mr.doob 已提交
1811

T
tschw 已提交
1812
				} else {
M
Mr.doob 已提交
1813

T
tschw 已提交
1814
					p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
M
Mr.doob 已提交
1815 1816 1817 1818 1819 1820 1821 1822 1823

				}

			}

		}

		if ( refreshMaterial ) {

M
Mr.doob 已提交
1824
			if ( material.lights ) {
M
Mr.doob 已提交
1825

1826
				// the current material requires lighting info
M
Mr.doob 已提交
1827

T
tschw 已提交
1828 1829 1830 1831 1832 1833
				// 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 已提交
1834

T
tschw 已提交
1835
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1836

T
tschw 已提交
1837
			}
G
gero3 已提交
1838

T
tschw 已提交
1839
			// refresh uniforms common to several materials
G
gero3 已提交
1840

T
tschw 已提交
1841
			if ( fog && material.fog ) {
G
gero3 已提交
1842

T
tschw 已提交
1843
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1844 1845 1846 1847 1848

			}

			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
W
WestLangley 已提交
1849
				 material instanceof THREE.MeshPhongMaterial ||
W
WestLangley 已提交
1850 1851
				 material instanceof THREE.MeshStandardMaterial ||
				 material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867

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

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

M
Mr.doob 已提交
1870
				refreshUniformsPoints( m_uniforms, material );
M
Mr.doob 已提交
1871

1872 1873 1874 1875
			} else if ( material instanceof THREE.MeshLambertMaterial ) {

				refreshUniformsLambert( m_uniforms, material );

M
Mr.doob 已提交
1876 1877 1878 1879
			} else if ( material instanceof THREE.MeshPhongMaterial ) {

				refreshUniformsPhong( m_uniforms, material );

W
WestLangley 已提交
1880 1881 1882 1883
			} else if ( material instanceof THREE.MeshPhysicalMaterial ) {

				refreshUniformsPhysical( m_uniforms, material );

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

1886
				refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1887

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

1890 1891 1892 1893 1894 1895 1896 1897
				if ( material.displacementMap ) {

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

				}

M
Mr.doob 已提交
1898 1899 1900 1901 1902 1903
			} else if ( material instanceof THREE.MeshNormalMaterial ) {

				m_uniforms.opacity.value = material.opacity;

			}

T
tschw 已提交
1904 1905
			THREE.WebGLUniforms.upload(
					_gl, materialProperties.uniformsList, m_uniforms, _this );
A
arose 已提交
1906 1907 1908

		}

M
Mr.doob 已提交
1909

T
tschw 已提交
1910
		// common matrices
M
Mr.doob 已提交
1911

T
tschw 已提交
1912 1913 1914
		p_uniforms.set( _gl, object, 'modelViewMatrix' );
		p_uniforms.set( _gl, object, 'normalMatrix' );
		p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
A
arose 已提交
1915 1916


T
tschw 已提交
1917
		// dynamic uniforms
A
arose 已提交
1918

T
tschw 已提交
1919
		var dynUniforms = materialProperties.dynamicUniforms;
A
arose 已提交
1920

T
tschw 已提交
1921
		if ( dynUniforms !== null ) {
A
arose 已提交
1922

T
tschw 已提交
1923 1924
			THREE.WebGLUniforms.evalDynamic(
					dynUniforms, m_uniforms, object, camera );
A
arose 已提交
1925

T
tschw 已提交
1926
			THREE.WebGLUniforms.upload( _gl, dynUniforms, m_uniforms, _this );
A
arose 已提交
1927 1928 1929

		}

T
tschw 已提交
1930
		return program;
A
arose 已提交
1931 1932 1933

	}

M
Mr.doob 已提交
1934 1935 1936 1937 1938 1939
	// Uniforms (refresh uniforms objects)

	function refreshUniformsCommon ( uniforms, material ) {

		uniforms.opacity.value = material.opacity;

1940
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
1941

1942
		if ( material.emissive ) {
M
Mr.doob 已提交
1943

1944
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
1945 1946 1947

		}

1948 1949 1950
		uniforms.map.value = material.map;
		uniforms.specularMap.value = material.specularMap;
		uniforms.alphaMap.value = material.alphaMap;
M
Mr.doob 已提交
1951

1952
		if ( material.aoMap ) {
1953

1954 1955
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1956 1957 1958

		}

M
Mr.doob 已提交
1959
		// uv repeat and offset setting priorities
M
Mr.doob 已提交
1960 1961 1962 1963 1964
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
1965
		// 6. emissive map
M
Mr.doob 已提交
1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

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

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
1981 1982 1983 1984 1985 1986 1987 1988
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

1989 1990 1991 1992 1993 1994 1995 1996
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

1997 1998 1999 2000
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

2001 2002 2003 2004
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
2005 2006 2007 2008
		}

		if ( uvScaleMap !== undefined ) {

2009
			// backwards compatibility
M
Mr.doob 已提交
2010 2011 2012 2013 2014 2015
			if ( uvScaleMap instanceof THREE.WebGLRenderTarget ) {

				uvScaleMap = uvScaleMap.texture;

			}

M
Mr.doob 已提交
2016 2017 2018 2019 2020 2021 2022 2023
			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;
2024 2025 2026 2027 2028 2029

		// 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 已提交
2030

2031
		uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
2032 2033
		uniforms.refractionRatio.value = material.refractionRatio;

M
Mr.doob 已提交
2034
	}
M
Mr.doob 已提交
2035 2036 2037 2038 2039 2040

	function refreshUniformsLine ( uniforms, material ) {

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

M
Mr.doob 已提交
2041
	}
M
Mr.doob 已提交
2042 2043 2044 2045 2046 2047 2048

	function refreshUniformsDash ( uniforms, material ) {

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

M
Mr.doob 已提交
2049
	}
M
Mr.doob 已提交
2050

M
Mr.doob 已提交
2051
	function refreshUniformsPoints ( uniforms, material ) {
M
Mr.doob 已提交
2052

2053
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
2054
		uniforms.opacity.value = material.opacity;
2055
		uniforms.size.value = material.size * _pixelRatio;
T
tschw 已提交
2056
		uniforms.scale.value = _canvas.clientHeight * 0.5;
M
Mr.doob 已提交
2057 2058 2059

		uniforms.map.value = material.map;

2060 2061 2062 2063 2064 2065 2066 2067 2068
		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 已提交
2069
	}
M
Mr.doob 已提交
2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085

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

2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104
	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 已提交
2105 2106
	function refreshUniformsPhong ( uniforms, material ) {

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

2110 2111 2112 2113
		if ( material.lightMap ) {

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

2115
		}
2116

2117
		if ( material.emissiveMap ) {
2118

2119
			uniforms.emissiveMap.value = material.emissiveMap;
2120

2121
		}
M
Mr.doob 已提交
2122

2123 2124 2125 2126
		if ( material.bumpMap ) {

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

2128
		}
M
Mr.doob 已提交
2129

2130 2131 2132 2133 2134 2135
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2136

2137 2138 2139 2140 2141
		if ( material.displacementMap ) {

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

2143
		}
2144 2145 2146

	}

2147
	function refreshUniformsStandard ( uniforms, material ) {
W
WestLangley 已提交
2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207

		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 已提交
2208 2209
	function refreshUniformsPhysical ( uniforms, material ) {

2210 2211 2212
		uniforms.clearCoat.value = material.clearCoat;
		uniforms.clearCoatRoughness.value = material.clearCoatRoughness;

W
WestLangley 已提交
2213 2214 2215 2216
		refreshUniformsStandard( uniforms, material );

	}

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

M
Mr.doob 已提交
2219
	function markUniformsLightsNeedsUpdate ( uniforms, value ) {
2220

M
Mr.doob 已提交
2221
		uniforms.ambientLightColor.needsUpdate = value;
2222

B
Ben Houston 已提交
2223 2224 2225 2226
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
		uniforms.hemisphereLights.needsUpdate = value;
2227

M
Mr.doob 已提交
2228
	}
2229

T
tschw 已提交
2230
	// Lighting
M
Mr.doob 已提交
2231

2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251
	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 已提交
2252
	function setupLights ( lights, camera ) {
M
Mr.doob 已提交
2253

B
brason 已提交
2254
		var l, ll, light,
M
Mr.doob 已提交
2255
		r = 0, g = 0, b = 0,
B
Ben Houston 已提交
2256
		color,
B
brason 已提交
2257
		intensity,
M
Mr.doob 已提交
2258
		distance,
2259
		shadowMap,
M
Mr.doob 已提交
2260

2261
		viewMatrix = camera.matrixWorldInverse,
M
Mr.doob 已提交
2262

M
Mr.doob 已提交
2263
		directionalLength = 0,
M
Mr.doob 已提交
2264 2265
		pointLength = 0,
		spotLength = 0,
2266
		hemiLength = 0;
M
Mr.doob 已提交
2267 2268 2269 2270 2271 2272 2273 2274 2275

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

			light = lights[ l ];

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

2276
			shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;
2277

M
Mr.doob 已提交
2278 2279
			if ( light instanceof THREE.AmbientLight ) {

2280 2281 2282
				r += color.r * intensity;
				g += color.g * intensity;
				b += color.b * intensity;
M
Mr.doob 已提交
2283 2284 2285

			} else if ( light instanceof THREE.DirectionalLight ) {

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

2288
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
M
Mr.doob 已提交
2289
				uniforms.direction.setFromMatrixPosition( light.matrixWorld );
2290
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
M
Mr.doob 已提交
2291 2292 2293
				uniforms.direction.sub( _vector3 );
				uniforms.direction.transformDirection( viewMatrix );

2294
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2295

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

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

2302 2303
				}

2304
				_lights.directionalShadowMap[ directionalLength ] = shadowMap;
2305
				_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
2306
				_lights.directional[ directionalLength ++ ] = uniforms;
M
Mr.doob 已提交
2307

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

M
Mr.doob 已提交
2310
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2311 2312 2313

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

M
Mr.doob 已提交
2315 2316 2317 2318 2319 2320 2321 2322
				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 );

2323 2324
				uniforms.coneCos = Math.cos( light.angle );
				uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
M
Mr.doob 已提交
2325
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
M
Mr.doob 已提交
2326

2327
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2328

2329 2330
				if ( light.castShadow ) {

2331 2332 2333
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;
2334

2335 2336
				}

2337
				_lights.spotShadowMap[ spotLength ] = shadowMap;
2338
				_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;
M
Mr.doob 已提交
2339
				_lights.spot[ spotLength ++ ] = uniforms;
2340

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

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

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

M
Mr.doob 已提交
2348 2349
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
				uniforms.distance = light.distance;
M
Mr.doob 已提交
2350 2351
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;

2352
				uniforms.shadow = light.castShadow;
2353

M
Mr.doob 已提交
2354
				if ( light.castShadow ) {
2355

2356 2357 2358 2359 2360
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;

				}
2361

2362
				_lights.pointShadowMap[ pointLength ] = shadowMap;
2363

2364 2365 2366
				if ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {

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

2368 2369
				}

2370 2371 2372 2373 2374
				// 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 已提交
2375
				_lights.point[ pointLength ++ ] = uniforms;
2376

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

M
Mr.doob 已提交
2379
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2380 2381 2382 2383

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

M
Mr.doob 已提交
2385 2386
				uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
				uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
M
Mr.doob 已提交
2387

M
Mr.doob 已提交
2388
				_lights.hemi[ hemiLength ++ ] = uniforms;
M
Mr.doob 已提交
2389 2390 2391 2392 2393

			}

		}

M
Mr.doob 已提交
2394 2395 2396
		_lights.ambient[ 0 ] = r;
		_lights.ambient[ 1 ] = g;
		_lights.ambient[ 2 ] = b;
M
Mr.doob 已提交
2397

M
Mr.doob 已提交
2398 2399
		_lights.directional.length = directionalLength;
		_lights.spot.length = spotLength;
2400
		_lights.point.length = pointLength;
M
Mr.doob 已提交
2401
		_lights.hemi.length = hemiLength;
2402

2403
		_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + hemiLength + ',' + _lights.shadows.length;
2404

M
Mr.doob 已提交
2405
	}
M
Mr.doob 已提交
2406 2407 2408 2409 2410

	// GL state setting

	this.setFaceCulling = function ( cullFace, frontFaceDirection ) {

T
tschw 已提交
2411 2412
		state.setCullFace( cullFace );
		state.setFlipSided( frontFaceDirection === THREE.FrontFaceDirectionCW );
M
Mr.doob 已提交
2413 2414 2415 2416 2417

	};

	// Textures

T
tschw 已提交
2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433
	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;

	}

2434
	this.allocTextureUnit = allocTextureUnit;
T
tschw 已提交
2435

2436
	// this.setTexture2D = setTexture2D;
2437
	this.setTexture2D = ( function() {
T
tschw 已提交
2438

2439
		var warned = false;
T
tschw 已提交
2440

2441
		// backwards compatibility: peel texture.texture
W
WestLangley 已提交
2442
		return function setTexture2D( texture, slot ) {
T
tschw 已提交
2443

2444
			if ( texture instanceof THREE.WebGLRenderTarget ) {
T
tschw 已提交
2445

2446
				if ( ! warned ) {
T
tschw 已提交
2447

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

2451
				}
T
tschw 已提交
2452

2453
				texture = texture.texture;
T
tschw 已提交
2454

2455
			}
T
tschw 已提交
2456

2457
			textures.setTexture2D( texture, slot );
T
tschw 已提交
2458

2459
		};
T
tschw 已提交
2460

2461
	}() );
T
tschw 已提交
2462

2463 2464 2465 2466
	this.setTexture = ( function() {

		var warned = false;

W
WestLangley 已提交
2467
		return function setTexture( texture, slot ) {
2468 2469 2470 2471 2472 2473 2474 2475

			if ( ! warned ) {

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

			}

2476
			textures.setTexture2D( texture, slot );
2477 2478 2479 2480 2481 2482 2483 2484 2485

		};

	}() );

	this.setTextureCube = ( function() {

		var warned = false;

W
WestLangley 已提交
2486
		return function setTextureCube( texture, slot ) {
2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509

			// 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
2510
				textures.setTextureCube( texture, slot );
2511 2512 2513 2514 2515

			} else {

				// assumed: texture property of THREE.WebGLRenderTargetCube

2516
				textures.setTextureCubeDynamic( texture, slot );
2517 2518 2519 2520 2521 2522

			}

		};

	}() );
T
tschw 已提交
2523

2524 2525 2526 2527
	this.getCurrentRenderTarget = function() {

		return _currentRenderTarget;

M
Michael Herzog 已提交
2528
	};
2529

2530
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
2531

2532 2533
		_currentRenderTarget = renderTarget;

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

2536
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2537 2538 2539

		}

2540
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
2541
		var framebuffer;
M
Mr.doob 已提交
2542 2543 2544

		if ( renderTarget ) {

2545
			var renderTargetProperties = properties.get( renderTarget );
F
Fordy 已提交
2546

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

2549
				framebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
2550 2551 2552

			} else {

2553
				framebuffer = renderTargetProperties.__webglFramebuffer;
M
Mr.doob 已提交
2554 2555 2556

			}

2557 2558
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2559

2560
			_currentViewport.copy( renderTarget.viewport );
M
Mr.doob 已提交
2561 2562 2563 2564 2565

		} else {

			framebuffer = null;

2566
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
2567
			_currentScissorTest = _scissorTest;
2568

2569
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
M
Mr.doob 已提交
2570 2571 2572

		}

M
Mr.doob 已提交
2573
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2574 2575 2576 2577 2578 2579

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

		}

2580 2581
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2582

2583
		state.viewport( _currentViewport );
2584

M
Mr.doob 已提交
2585 2586 2587
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
2588
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
2589 2590 2591

		}

M
Mr.doob 已提交
2592 2593
	};

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

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

2598
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2599
			return;
2600

G
gero3 已提交
2601
		}
2602

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

M
Mr.doob 已提交
2605
		if ( framebuffer ) {
2606

G
gero3 已提交
2607
			var restore = false;
2608

M
Mr.doob 已提交
2609
			if ( framebuffer !== _currentFramebuffer ) {
2610

M
Mr.doob 已提交
2611
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2612

G
gero3 已提交
2613
				restore = true;
2614

G
gero3 已提交
2615
			}
2616

M
Mr.doob 已提交
2617
			try {
2618

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

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

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

M
Mr.doob 已提交
2626
				}
2627

M
Michael Herzog 已提交
2628 2629 2630 2631
				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' ) ) ) {
2632

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

M
Mr.doob 已提交
2636
				}
2637

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

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

2642
					if ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {
2643 2644 2645 2646

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

					}
2647

M
Mr.doob 已提交
2648
				} else {
M
Mr.doob 已提交
2649

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

				}
M
Mr.doob 已提交
2653

M
Mr.doob 已提交
2654
			} finally {
M
Mr.doob 已提交
2655

M
Mr.doob 已提交
2656 2657 2658
				if ( restore ) {

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

M
Mr.doob 已提交
2660 2661 2662
				}

			}
M
Mr.doob 已提交
2663 2664 2665

		}

M
Mr.doob 已提交
2666 2667
	};

M
Mr.doob 已提交
2668 2669 2670 2671
	// Map three.js constants to WebGL constants

	function paramThreeToGL ( p ) {

2672 2673
		var extension;

M
Mr.doob 已提交
2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697
		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;

2698 2699 2700 2701 2702 2703 2704 2705
		extension = extensions.get( 'OES_texture_half_float' );

		if ( extension !== null ) {

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

		}

M
Mr.doob 已提交
2706 2707 2708 2709 2710
		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;
2711
		if ( p === THREE.DepthFormat ) return _gl.DEPTH_COMPONENT;
M
Mr.doob 已提交
2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729

		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;

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

2732 2733 2734 2735 2736 2737
		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 已提交
2738 2739 2740

		}

2741 2742 2743
		extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );

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

2745 2746 2747 2748
			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 已提交
2749 2750 2751

		}

2752 2753 2754 2755 2756 2757 2758 2759
		extension = extensions.get( 'WEBGL_compressed_texture_etc1' );

		if ( extension !== null ) {

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

		}

2760 2761 2762
		extension = extensions.get( 'EXT_blend_minmax' );

		if ( extension !== null ) {
2763

2764 2765
			if ( p === THREE.MinEquation ) return extension.MIN_EXT;
			if ( p === THREE.MaxEquation ) return extension.MAX_EXT;
2766 2767 2768

		}

M
Mr.doob 已提交
2769 2770
		return 0;

M
Mr.doob 已提交
2771
	}
M
Mr.doob 已提交
2772 2773

};