WebGLRenderer.js 89.0 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 15

	parameters = parameters || {};

	var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElement( '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 86 87 88 89
	// morphs

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

	// flags

	this.autoScaleCubemaps = true;

	// internal properties

	var _this = this,

	// internal state cache

	_currentProgram = null,
90
	_currentRenderTarget = null,
M
Mr.doob 已提交
91
	_currentFramebuffer = null,
92
	_currentMaterialId = - 1,
93
	_currentGeometryProgram = '',
M
Mr.doob 已提交
94 95
	_currentCamera = null,

96 97 98 99 100
	_currentScissor = new THREE.Vector4(),
	_currentScissorTest = null,

	_currentViewport = new THREE.Vector4(),

101 102
	//

M
Mr.doob 已提交
103 104
	_usedTextureUnits = 0,

M
Mr.doob 已提交
105 106 107 108 109 110 111 112 113 114 115
	//

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

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

	_pixelRatio = 1,

	_scissor = new THREE.Vector4( 0, 0, _width, _height ),
116 117
	_scissorTest = false,

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

M
Mr.doob 已提交
120 121 122 123
	// frustum

	_frustum = new THREE.Frustum(),

T
tschw 已提交
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
	// clipping

	_clippingEnabled = false,
	_localClippingEnabled = false,
	_clipRenderingShadows = false,

	_numClippingPlanes = 0,
	_clippingPlanesUniform = {
			type: '4fv', value: null, needsUpdate: false },

	_globalClippingState = null,
	_numGlobalClippingPlanes = 0,

	_matrix3 = new THREE.Matrix3(),
	_sphere = new THREE.Sphere(),
	_plane = new THREE.Plane(),


M
Mr.doob 已提交
142
	// camera matrices cache
M
Mr.doob 已提交
143 144 145 146 147 148 149 150 151

	_projScreenMatrix = new THREE.Matrix4(),

	_vector3 = new THREE.Vector3(),

	// light arrays cache

	_lights = {

152 153
		hash: '',

M
Mr.doob 已提交
154
		ambient: [ 0, 0, 0 ],
M
Mr.doob 已提交
155
		directional: [],
156 157
		directionalShadowMap: [],
		directionalShadowMatrix: [],
M
Mr.doob 已提交
158
		spot: [],
159 160
		spotShadowMap: [],
		spotShadowMatrix: [],
M
Mr.doob 已提交
161
		point: [],
162 163
		pointShadowMap: [],
		pointShadowMatrix: [],
164 165
		hemi: [],

166
		shadows: []
M
Mr.doob 已提交
167

168 169
	},

M
Mr.doob 已提交
170 171
	// info

172
	_infoMemory = {
173 174

		geometries: 0,
T
tschw 已提交
175
		textures: 0
176 177 178

	},

179
	_infoRender = {
180 181 182 183 184 185

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

M
Mr.doob 已提交
186 187
	};

M
Mr.doob 已提交
188
	this.info = {
189

M
Mr.doob 已提交
190 191
		render: _infoRender,
		memory: _infoMemory,
192
		programs: null
M
Mr.doob 已提交
193 194

	};
195

196

M
Mr.doob 已提交
197 198 199 200
	// initialize

	var _gl;

M
Mr.doob 已提交
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
	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 已提交
216
			if ( _canvas.getContext( 'webgl' ) !== null ) {
217 218 219 220 221 222 223 224

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

			} else {

				throw 'Error creating WebGL context.';

			}
M
Mr.doob 已提交
225 226 227

		}

228 229 230 231 232 233 234 235 236 237 238 239
		// Some experimental-webgl implementations do not have getShaderPrecisionFormat

		if ( _gl.getShaderPrecisionFormat === undefined ) {

			_gl.getShaderPrecisionFormat = function () {

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

			};

		}

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

M
Mr.doob 已提交
242 243
	} catch ( error ) {

244
		console.error( 'THREE.WebGLRenderer: ' + error );
M
Mr.doob 已提交
245 246 247

	}

248 249
	var extensions = new THREE.WebGLExtensions( _gl );

250 251
	extensions.get( 'OES_texture_float' );
	extensions.get( 'OES_texture_float_linear' );
252 253
	extensions.get( 'OES_texture_half_float' );
	extensions.get( 'OES_texture_half_float_linear' );
254
	extensions.get( 'OES_standard_derivatives' );
B
Ben Adams 已提交
255
	extensions.get( 'ANGLE_instanced_arrays' );
256

257 258
	if ( extensions.get( 'OES_element_index_uint' ) ) {

259
		THREE.BufferGeometry.MaxIndex = 4294967296;
260 261 262

	}

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

265 266 267
	var state = new THREE.WebGLState( _gl, extensions, paramThreeToGL );
	var properties = new THREE.WebGLProperties();
	var objects = new THREE.WebGLObjects( _gl, properties, this.info );
G
gero3 已提交
268
	var programCache = new THREE.WebGLPrograms( this, capabilities );
M
Mr.doob 已提交
269
	var lightCache = new THREE.WebGLLights();
270

271 272
	this.info.programs = programCache.programs;

273 274
	var bufferRenderer = new THREE.WebGLBufferRenderer( _gl, extensions, _infoRender );
	var indexedBufferRenderer = new THREE.WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
275

M
Mr.doob 已提交
276 277
	//

278 279
	function getTargetPixelRatio() {

280
		return _currentRenderTarget === null ? _pixelRatio : 1;
281 282 283

	}

284
	function glClearColor( r, g, b, a ) {
285 286 287

		if ( _premultipliedAlpha === true ) {

288
			r *= a; g *= a; b *= a;
289 290 291

		}

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

294
	}
295

296
	function setDefaultGLState() {
M
Mr.doob 已提交
297

M
Mr.doob 已提交
298
		state.init();
M
Mr.doob 已提交
299

300 301
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
M
Mr.doob 已提交
302

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

305
	}
306

307
	function resetGLState() {
308 309 310 311

		_currentProgram = null;
		_currentCamera = null;

312
		_currentGeometryProgram = '';
313 314
		_currentMaterialId = - 1;

M
Mr.doob 已提交
315 316
		state.reset();

317
	}
M
Mr.doob 已提交
318 319 320 321

	setDefaultGLState();

	this.context = _gl;
M
Mr.doob 已提交
322
	this.capabilities = capabilities;
323
	this.extensions = extensions;
324
	this.properties = properties;
M
Mr.doob 已提交
325
	this.state = state;
M
Mr.doob 已提交
326

M
Mr.doob 已提交
327 328
	// shadow map

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

331
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
332

M
Mr.doob 已提交
333

M
Mr.doob 已提交
334 335 336 337 338
	// Plugins

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

M
Mr.doob 已提交
339 340 341 342 343 344 345 346
	// API

	this.getContext = function () {

		return _gl;

	};

347 348 349 350 351 352
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

353 354 355 356 357 358
	this.forceContextLoss = function () {

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

	};

359
	this.getMaxAnisotropy = ( function () {
M
Mr.doob 已提交
360

361
		var value;
M
Mr.doob 已提交
362

363
		return function getMaxAnisotropy() {
364

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

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

M
Mr.doob 已提交
369
			if ( extension !== null ) {
370

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

M
Mr.doob 已提交
373 374 375 376 377
			} else {

				value = 0;

			}
378 379 380

			return value;

M
Mr.doob 已提交
381
		};
382 383

	} )();
M
Mr.doob 已提交
384 385 386

	this.getPrecision = function () {

G
gero3 已提交
387
		return capabilities.precision;
M
Mr.doob 已提交
388 389 390

	};

391 392
	this.getPixelRatio = function () {

393
		return _pixelRatio;
394 395 396 397 398

	};

	this.setPixelRatio = function ( value ) {

399 400 401 402 403
		if ( value === undefined ) return;

		_pixelRatio = value;

		this.setSize( _viewport.z, _viewport.w, false );
404 405 406

	};

407 408 409
	this.getSize = function () {

		return {
410 411
			width: _width,
			height: _height
412 413 414 415
		};

	};

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

418 419 420
		_width = width;
		_height = height;

421 422
		_canvas.width = width * _pixelRatio;
		_canvas.height = height * _pixelRatio;
423

424
		if ( updateStyle !== false ) {
425

G
gero3 已提交
426 427
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
428

G
gero3 已提交
429
		}
M
Mr.doob 已提交
430

431
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
432 433 434 435 436

	};

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

437
		state.viewport( _viewport.set( x, y, width, height ) );
M
Mr.doob 已提交
438 439 440

	};

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

443
		state.scissor( _scissor.set( x, y, width, height ) );
M
Mr.doob 已提交
444 445 446

	};

447 448
	this.setScissorTest = function ( boolean ) {

449
		state.setScissorTest( _scissorTest = boolean );
M
Mr.doob 已提交
450 451 452 453 454

	};

	// Clearing

M
Mr.doob 已提交
455
	this.getClearColor = function () {
M
Mr.doob 已提交
456

M
Mr.doob 已提交
457
		return _clearColor;
M
Mr.doob 已提交
458 459 460

	};

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

M
Mr.doob 已提交
463
		_clearColor.set( color );
464

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

467
		glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
M
Mr.doob 已提交
468 469 470

	};

M
Mr.doob 已提交
471
	this.getClearAlpha = function () {
M
Mr.doob 已提交
472

M
Mr.doob 已提交
473
		return _clearAlpha;
M
Mr.doob 已提交
474 475 476

	};

M
Mr.doob 已提交
477
	this.setClearAlpha = function ( alpha ) {
M
Mr.doob 已提交
478

M
Mr.doob 已提交
479
		_clearAlpha = alpha;
M
Mr.doob 已提交
480

481
		glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
M
Mr.doob 已提交
482 483 484 485 486 487 488 489 490 491 492 493

	};

	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 );
494 495 496 497 498

	};

	this.clearColor = function () {

M
Mr.doob 已提交
499
		this.clear( true, false, false );
500 501 502 503 504

	};

	this.clearDepth = function () {

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

	};

	this.clearStencil = function () {

M
Mr.doob 已提交
511
		this.clear( false, false, true );
M
Mr.doob 已提交
512 513 514 515 516 517 518 519 520 521

	};

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

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

	};

M
Mr.doob 已提交
522 523
	// Reset

524
	this.resetGLState = resetGLState;
M
Mr.doob 已提交
525

D
dubejf 已提交
526 527 528 529 530 531
	this.dispose = function() {

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

	};

M
Mr.doob 已提交
532
	// Events
M
Mr.doob 已提交
533

D
dubejf 已提交
534 535 536 537 538 539 540 541 542
	function onContextLost( event ) {

		event.preventDefault();

		resetGLState();
		setDefaultGLState();

		properties.clear();

M
Mr.doob 已提交
543
	}
D
dubejf 已提交
544

545
	function onTextureDispose( event ) {
M
Mr.doob 已提交
546 547 548 549 550 551 552

		var texture = event.target;

		texture.removeEventListener( 'dispose', onTextureDispose );

		deallocateTexture( texture );

553
		_infoMemory.textures --;
M
Mr.doob 已提交
554 555


556
	}
M
Mr.doob 已提交
557

558
	function onRenderTargetDispose( event ) {
M
Mr.doob 已提交
559 560 561 562 563 564 565

		var renderTarget = event.target;

		renderTarget.removeEventListener( 'dispose', onRenderTargetDispose );

		deallocateRenderTarget( renderTarget );

566
		_infoMemory.textures --;
M
Mr.doob 已提交
567

568
	}
M
Mr.doob 已提交
569

570
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
571 572 573 574 575 576 577

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

578
	}
M
Mr.doob 已提交
579 580 581

	// Buffer deallocation

582
	function deallocateTexture( texture ) {
M
Mr.doob 已提交
583

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

586
		if ( texture.image && textureProperties.__image__webglTextureCube ) {
M
Mr.doob 已提交
587 588 589

			// cube texture

590
			_gl.deleteTexture( textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
591

592 593 594 595
		} else {

			// 2D texture

596
			if ( textureProperties.__webglInit === undefined ) return;
597

598
			_gl.deleteTexture( textureProperties.__webglTexture );
599

M
Mr.doob 已提交
600 601
		}

602
		// remove all webgl properties
603
		properties.delete( texture );
604

605
	}
M
Mr.doob 已提交
606

607
	function deallocateRenderTarget( renderTarget ) {
M
Mr.doob 已提交
608

609
		var renderTargetProperties = properties.get( renderTarget );
M
Mr.doob 已提交
610
		var textureProperties = properties.get( renderTarget.texture );
M
Mr.doob 已提交
611

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

M
Mr.doob 已提交
614
		_gl.deleteTexture( textureProperties.__webglTexture );
M
Mr.doob 已提交
615

M
Mr.doob 已提交
616 617 618 619
		if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {

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

620
				_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );
621
				_gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );
M
Mr.doob 已提交
622 623 624 625 626

			}

		} else {

627
			_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );
628
			_gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );
M
Mr.doob 已提交
629 630 631

		}

M
Mr.doob 已提交
632
		properties.delete( renderTarget.texture );
D
Daosheng Mu 已提交
633
		properties.delete( renderTarget );
M
Mr.doob 已提交
634

635
	}
M
Mr.doob 已提交
636

637
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
638

639 640 641 642
		releaseMaterialProgramReference( material );

		properties.delete( material );

643
	}
644 645


646
	function releaseMaterialProgramReference( material ) {
647

648
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
649 650 651

		material.program = undefined;

652
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
653

654
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
655

M
Mr.doob 已提交
656 657
		}

658
	}
M
Mr.doob 已提交
659 660 661 662 663

	// Buffer rendering

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

664
		state.initAttributes();
665

666
		var buffers = properties.get( object );
667

668 669 670 671
		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 已提交
672

673
		var attributes = program.getAttributes();
674

M
Mr.doob 已提交
675 676
		if ( object.hasPositions ) {

677
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
M
Mr.doob 已提交
678
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
679

680 681
			state.enableAttribute( attributes.position );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
682 683 684 685 686

		}

		if ( object.hasNormals ) {

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

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

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

693
					var array = object.normalArray;
M
Mr.doob 已提交
694

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

699 700 701
					array[ i + 0 ] = nx;
					array[ i + 1 ] = ny;
					array[ i + 2 ] = nz;
M
Mr.doob 已提交
702

703 704 705
					array[ i + 3 ] = nx;
					array[ i + 4 ] = ny;
					array[ i + 5 ] = nz;
M
Mr.doob 已提交
706

707 708 709
					array[ i + 6 ] = nx;
					array[ i + 7 ] = ny;
					array[ i + 8 ] = nz;
M
Mr.doob 已提交
710 711 712 713 714 715

				}

			}

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

717
			state.enableAttribute( attributes.normal );
718

719
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
720 721 722 723 724

		}

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

725
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
M
Mr.doob 已提交
726
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
727

728
			state.enableAttribute( attributes.uv );
729

730
			_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
731 732 733 734 735

		}

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

736
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
M
Mr.doob 已提交
737
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
738

739
			state.enableAttribute( attributes.color );
740

741
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
742 743 744

		}

745
		state.disableUnusedAttributes();
746

M
Mr.doob 已提交
747 748 749 750 751 752
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

753
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
754

M
Mr.doob 已提交
755 756
		setMaterial( material );

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

M
Mr.doob 已提交
759 760
		var updateBuffers = false;
		var geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;
M
Mr.doob 已提交
761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783

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

			}

784
			activeInfluences.sort( absNumericalSort );
M
Mr.doob 已提交
785 786 787 788 789 790 791

			if ( activeInfluences.length > 8 ) {

				activeInfluences.length = 8;

			}

792 793
			var morphAttributes = geometry.morphAttributes;

M
Mr.doob 已提交
794 795 796 797 798 799 800
			for ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {

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

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

801
					var index = influence[ 1 ];
M
Mr.doob 已提交
802

803 804
					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 已提交
805 806 807

				} else {

808 809
					if ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );
					if ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );
M
Mr.doob 已提交
810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826

				}

			}

			var uniforms = program.getUniforms();

			if ( uniforms.morphTargetInfluences !== null ) {

				_gl.uniform1fv( uniforms.morphTargetInfluences, morphInfluences );

			}

			updateBuffers = true;

		}

M
Mr.doob 已提交
827 828
		//

829
		var index = geometry.index;
830 831
		var position = geometry.attributes.position;

832 833
		if ( material.wireframe === true ) {

834
			index = objects.getWireframeAttribute( geometry );
835 836 837

		}

838 839
		var renderer;

840
		if ( index !== null ) {
841

842 843
			renderer = indexedBufferRenderer;
			renderer.setIndex( index );
844

845
		} else {
846

847
			renderer = bufferRenderer;
848

849
		}
M
Mr.doob 已提交
850

851
		if ( updateBuffers ) {
M
Mr.doob 已提交
852

853
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
854

855
			if ( index !== null ) {
856

857
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );
858 859 860

			}

861
		}
862

M
Mr.doob 已提交
863
		//
864

M
Mr.doob 已提交
865 866
		var dataStart = 0;
		var dataCount = Infinity;
867

M
Mr.doob 已提交
868
		if ( index !== null ) {
869

M
Mr.doob 已提交
870
			dataCount = index.count;
871

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

M
Mr.doob 已提交
874
			dataCount = position.count;
875

M
Mr.doob 已提交
876
		}
877

M
Mr.doob 已提交
878 879
		var rangeStart = geometry.drawRange.start;
		var rangeCount = geometry.drawRange.count;
880

M
Mr.doob 已提交
881 882
		var groupStart = group !== null ? group.start : 0;
		var groupCount = group !== null ? group.count : Infinity;
883

M
Mr.doob 已提交
884 885 886 887 888 889
		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 );

		//
890

891
		if ( object instanceof THREE.Mesh ) {
892

893
			if ( material.wireframe === true ) {
894

895
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
896
				renderer.setMode( _gl.LINES );
897

898
			} else {
M
Mr.doob 已提交
899 900

				switch ( object.drawMode ) {
901

B
Ben Adams 已提交
902 903 904 905 906 907 908 909 910 911 912 913 914
					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;

				}
915

916
			}
917

918

919
		} else if ( object instanceof THREE.Line ) {
920

921
			var lineWidth = material.linewidth;
922

923
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
924

925
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
926

927
			if ( object instanceof THREE.LineSegments ) {
928

929
				renderer.setMode( _gl.LINES );
930

931
			} else {
932

933
				renderer.setMode( _gl.LINE_STRIP );
934 935

			}
M
Mr.doob 已提交
936

937
		} else if ( object instanceof THREE.Points ) {
938 939

			renderer.setMode( _gl.POINTS );
940 941

		}
942

J
jfranc 已提交
943
		if ( geometry instanceof THREE.InstancedBufferGeometry ) {
M
Mr.doob 已提交
944 945 946

			if ( geometry.maxInstancedCount > 0 ) {

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

J
jfranc 已提交
949
			}
950 951 952

		} else {

M
Mr.doob 已提交
953
			renderer.render( drawStart, drawCount );
954

M
Mr.doob 已提交
955 956 957 958
		}

	};

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

M
Mr.doob 已提交
961
		var extension;
B
Ben Adams 已提交
962

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

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

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

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

M
Mr.doob 已提交
972 973 974
			}

		}
B
Ben Adams 已提交
975

976 977
		if ( startIndex === undefined ) startIndex = 0;

978 979
		state.initAttributes();

980
		var geometryAttributes = geometry.attributes;
981

982
		var programAttributes = program.getAttributes();
983

984
		var materialDefaultAttributeValues = material.defaultAttributeValues;
985

986
		for ( var name in programAttributes ) {
987

988
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
989

M
Mr.doob 已提交
990
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
991

992
				var geometryAttribute = geometryAttributes[ name ];
993

M
Mr.doob 已提交
994
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
995

996
					var size = geometryAttribute.itemSize;
G
gero3 已提交
997
					var buffer = objects.getAttributeBuffer( geometryAttribute );
998

B
Ben Adams 已提交
999
					if ( geometryAttribute instanceof THREE.InterleavedBufferAttribute ) {
1000

M
Mr.doob 已提交
1001 1002 1003 1004 1005
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

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

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

M
Mr.doob 已提交
1009
							if ( geometry.maxInstancedCount === undefined ) {
1010

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

M
Mr.doob 已提交
1013
							}
B
Ben Adams 已提交
1014

M
Mr.doob 已提交
1015
						} else {
B
Ben Adams 已提交
1016

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

M
Mr.doob 已提交
1019
						}
B
Ben Adams 已提交
1020

M
Mr.doob 已提交
1021 1022
						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
						_gl.vertexAttribPointer( programAttribute, size, _gl.FLOAT, false, stride * data.array.BYTES_PER_ELEMENT, ( startIndex * stride + offset ) * data.array.BYTES_PER_ELEMENT );
B
Ben Adams 已提交
1023

M
Mr.doob 已提交
1024
					} else {
B
Ben Adams 已提交
1025

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

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

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

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

M
Mr.doob 已提交
1034
							}
B
Ben Adams 已提交
1035

M
Mr.doob 已提交
1036 1037 1038 1039
						} else {

							state.enableAttribute( programAttribute );

M
Mr.doob 已提交
1040
						}
B
Ben Adams 已提交
1041

1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052
						var type = _gl.FLOAT;
						var normalized = false;
						var array = geometryAttribute.array;

						if ( array instanceof Uint8Array ) {

							type = _gl.UNSIGNED_BYTE;
							normalized = true;

						}

M
Mr.doob 已提交
1053
						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
1054
						_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * array.BYTES_PER_ELEMENT );
M
Mr.doob 已提交
1055

B
Ben Adams 已提交
1056
					}
M
Mr.doob 已提交
1057

1058 1059
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
1060
					var value = materialDefaultAttributeValues[ name ];
1061

1062
					if ( value !== undefined ) {
M
Mr.doob 已提交
1063

1064
						switch ( value.length ) {
M
Mr.doob 已提交
1065

1066 1067 1068
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
1069

1070 1071 1072
							case 3:
								_gl.vertexAttrib3fv( programAttribute, value );
								break;
M
Mr.doob 已提交
1073

1074 1075 1076
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
1077

1078 1079
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
1080 1081

						}
M
Mr.doob 已提交
1082 1083 1084 1085 1086 1087 1088 1089

					}

				}

			}

		}
1090

1091
		state.disableUnusedAttributes();
1092

M
Mr.doob 已提交
1093 1094
	}

M
Mr.doob 已提交
1095 1096
	// Sorting

1097
	function absNumericalSort( a, b ) {
1098

1099
		return Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );
1100 1101 1102

	}

M
Mr.doob 已提交
1103 1104
	function painterSortStable ( a, b ) {

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

U
unconed 已提交
1107
			return a.object.renderOrder - b.object.renderOrder;
1108

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

M
Mr.doob 已提交
1111
			return a.material.id - b.material.id;
1112 1113

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

M
Mr.doob 已提交
1115
			return a.z - b.z;
M
Mr.doob 已提交
1116 1117 1118

		} else {

1119
			return a.id - b.id;
M
Mr.doob 已提交
1120 1121 1122

		}

1123
	}
M
Mr.doob 已提交
1124

1125 1126
	function reversePainterSortStable ( a, b ) {

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

U
unconed 已提交
1129
			return a.object.renderOrder - b.object.renderOrder;
1130 1131

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

M
Mr.doob 已提交
1133
			return b.z - a.z;
1134 1135 1136 1137 1138 1139 1140

		} else {

			return a.id - b.id;

		}

1141
	}
1142

M
Mr.doob 已提交
1143 1144 1145 1146 1147 1148
	// Rendering

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

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

1149
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1150 1151 1152 1153
			return;

		}

M
Mr.doob 已提交
1154
		var fog = scene.fog;
M
Mr.doob 已提交
1155 1156 1157

		// reset caching for this frame

1158
		_currentGeometryProgram = '';
1159
		_currentMaterialId = - 1;
1160
		_currentCamera = null;
M
Mr.doob 已提交
1161 1162 1163

		// update scene graph

1164
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1165 1166 1167

		// update camera matrices and frustum

1168
		if ( camera.parent === null ) camera.updateMatrixWorld();
M
Mr.doob 已提交
1169 1170 1171 1172 1173 1174

		camera.matrixWorldInverse.getInverse( camera.matrixWorld );

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

M
Mr.doob 已提交
1175
		lights.length = 0;
1176

M
Mr.doob 已提交
1177 1178
		opaqueObjectsLastIndex = - 1;
		transparentObjectsLastIndex = - 1;
1179

M
Mr.doob 已提交
1180 1181 1182
		sprites.length = 0;
		lensFlares.length = 0;

T
tschw 已提交
1183 1184
		setupGlobalClippingPlanes( this.clippingPlanes, camera );

1185
		projectObject( scene, camera );
M
Mr.doob 已提交
1186

T
tschw 已提交
1187

1188 1189 1190
		opaqueObjects.length = opaqueObjectsLastIndex + 1;
		transparentObjects.length = transparentObjectsLastIndex + 1;

M
Mr.doob 已提交
1191
		if ( _this.sortObjects === true ) {
1192 1193 1194

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

1196 1197
		}

M
Mr.doob 已提交
1198
		//
M
Mr.doob 已提交
1199

T
tschw 已提交
1200 1201 1202 1203 1204 1205 1206
		if ( _clippingEnabled ) {

			_clipRenderingShadows = true;
			setupClippingPlanes( null );

		}

1207 1208
		setupShadows( lights );

M
Mr.doob 已提交
1209
		shadowMap.render( scene, camera );
M
Mr.doob 已提交
1210

1211 1212
		setupLights( lights, camera );

T
tschw 已提交
1213 1214 1215 1216 1217 1218 1219
		if ( _clippingEnabled ) {

			_clipRenderingShadows = false;
			resetGlobalClippingState();

		}

M
Mr.doob 已提交
1220 1221
		//

1222 1223 1224 1225
		_infoRender.calls = 0;
		_infoRender.vertices = 0;
		_infoRender.faces = 0;
		_infoRender.points = 0;
M
Mr.doob 已提交
1226

1227 1228 1229 1230 1231 1232
		if ( renderTarget === undefined ) {

			renderTarget = null;

		}

M
Mr.doob 已提交
1233 1234 1235 1236 1237 1238 1239 1240
		this.setRenderTarget( renderTarget );

		if ( this.autoClear || forceClear ) {

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

		}

1241
		//
M
Mr.doob 已提交
1242 1243 1244

		if ( scene.overrideMaterial ) {

1245
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1246

1247 1248
			renderObjects( opaqueObjects, camera, fog, overrideMaterial );
			renderObjects( transparentObjects, camera, fog, overrideMaterial );
1249

M
Mr.doob 已提交
1250 1251 1252 1253
		} else {

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

M
Mr.doob 已提交
1254
			state.setBlending( THREE.NoBlending );
1255
			renderObjects( opaqueObjects, camera, fog );
M
Mr.doob 已提交
1256 1257 1258

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

1259
			renderObjects( transparentObjects, camera, fog );
M
Mr.doob 已提交
1260 1261 1262 1263 1264

		}

		// custom render plugins (post pass)

M
Mr.doob 已提交
1265
		spritePlugin.render( scene, camera );
1266
		lensFlarePlugin.render( scene, camera, _currentViewport );
M
Mr.doob 已提交
1267 1268 1269

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

M
Mr.doob 已提交
1270 1271 1272
		if ( renderTarget ) {

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

M
Mr.doob 已提交
1274 1275 1276 1277 1278
			if ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&
					texture.minFilter !== THREE.NearestFilter &&
					texture.minFilter !== THREE.LinearFilter ) {

				updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1279 1280

			}
M
Mr.doob 已提交
1281 1282 1283

		}

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

M
Mr.doob 已提交
1286 1287
		state.setDepthTest( true );
		state.setDepthWrite( true );
1288
		state.setColorWrite( true );
M
Mr.doob 已提交
1289 1290 1291 1292

		// _gl.finish();

	};
M
Mr.doob 已提交
1293

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

1296
		var array, index;
M
Mr.doob 已提交
1297

1298
		// allocate the next position in the appropriate array
M
Mr.doob 已提交
1299 1300 1301

		if ( material.transparent ) {

1302 1303
			array = transparentObjects;
			index = ++ transparentObjectsLastIndex;
M
Mr.doob 已提交
1304 1305 1306

		} else {

1307 1308 1309 1310 1311
			array = opaqueObjects;
			index = ++ opaqueObjectsLastIndex;

		}

1312 1313
		// recycle existing render item or grow the array

1314 1315 1316 1317 1318 1319 1320 1321 1322 1323
		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 已提交
1324 1325 1326

		} else {

1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337
			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 已提交
1338 1339 1340 1341 1342

		}

	}

T
tschw 已提交
1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373
	function isObjectViewable( object ) {

		var geometry = object.geometry;

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

		var sphere = _sphere.
				copy( geometry.boundingSphere ).
				applyMatrix4( object.matrixWorld );

		if ( ! _frustum.intersectsSphere( sphere ) ) return false;
		if ( _numClippingPlanes === 0 ) return true;

		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;

		} while ( ++ i !== _numClippingPlanes );

		return true;

	}

1374
	function projectObject( object, camera ) {
M
Mr.doob 已提交
1375

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

1378
		if ( object.layers.test( camera.layers ) ) {
M
Mr.doob 已提交
1379

1380
			if ( object instanceof THREE.Light ) {
M
Mr.doob 已提交
1381

1382
				lights.push( object );
M
Mr.doob 已提交
1383

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

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

					sprites.push( object );

				}
M
Mr.doob 已提交
1391

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

1394
				lensFlares.push( object );
M
Mr.doob 已提交
1395

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

1398
				if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1399

1400 1401
					_vector3.setFromMatrixPosition( object.matrixWorld );
					_vector3.applyProjection( _projScreenMatrix );
M
Mr.doob 已提交
1402

1403
				}
1404

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

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

1409
				if ( object instanceof THREE.SkinnedMesh ) {
M
Mr.doob 已提交
1410

1411
					object.skeleton.update();
1412

1413
				}
1414

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

1417
					var material = object.material;
1418

1419
					if ( material.visible === true ) {
M
Mr.doob 已提交
1420

1421
						if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1422

1423 1424 1425 1426
							_vector3.setFromMatrixPosition( object.matrixWorld );
							_vector3.applyProjection( _projScreenMatrix );

						}
M
Mr.doob 已提交
1427

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

S
SUNAG 已提交
1430
						if ( material instanceof THREE.MultiMaterial ) {
1431

1432 1433
							var groups = geometry.groups;
							var materials = material.materials;
1434

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

1437 1438
								var group = groups[ i ];
								var groupMaterial = materials[ group.materialIndex ];
1439

1440
								if ( groupMaterial.visible === true ) {
1441

1442 1443 1444
									pushRenderItem( object, geometry, groupMaterial, _vector3.z, group );

								}
M
Mr.doob 已提交
1445

M
Mr.doob 已提交
1446
							}
M
Mr.doob 已提交
1447

1448
						} else {
M
Mr.doob 已提交
1449

1450
							pushRenderItem( object, geometry, material, _vector3.z, null );
1451

1452
						}
O
OpenShift guest 已提交
1453

1454
					}
M
Mr.doob 已提交
1455

1456
				}
M
Mr.doob 已提交
1457

1458
			}
M
Mr.doob 已提交
1459

M
Mr.doob 已提交
1460
		}
M
Mr.doob 已提交
1461

M
Mr.doob 已提交
1462
		var children = object.children;
M
Mr.doob 已提交
1463

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

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

1468
		}
1469

1470
	}
M
Mr.doob 已提交
1471

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

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

1476
			var renderItem = renderList[ i ];
M
Mr.doob 已提交
1477

1478
			var object = renderItem.object;
M
Mr.doob 已提交
1479 1480 1481
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
M
Mr.doob 已提交
1482

1483 1484
			object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
			object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
M
Mr.doob 已提交
1485

M
Mr.doob 已提交
1486
			if ( object instanceof THREE.ImmediateRenderObject ) {
M
Mr.doob 已提交
1487

M
Mr.doob 已提交
1488
				setMaterial( material );
M
Mr.doob 已提交
1489

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

M
Mr.doob 已提交
1492
				_currentGeometryProgram = '';
M
Mr.doob 已提交
1493

M
Mr.doob 已提交
1494
				object.render( function ( object ) {
M
Mr.doob 已提交
1495

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

M
Mr.doob 已提交
1498
				} );
1499

M
Mr.doob 已提交
1500
			} else {
M
Mr.doob 已提交
1501

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

M
Mr.doob 已提交
1504
			}
M
Mr.doob 已提交
1505

1506
		}
M
Mr.doob 已提交
1507

1508
	}
G
gero3 已提交
1509

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

1512
		var materialProperties = properties.get( material );
G
gero3 已提交
1513

T
tschw 已提交
1514 1515 1516
		var parameters = programCache.getParameters(
				material, _lights, fog, _numClippingPlanes, object );

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

1519
		var program = materialProperties.program;
T
tschw 已提交
1520
		var programChange = true;
1521

1522
		if ( program === undefined ) {
B
Ben Adams 已提交
1523

M
Mr.doob 已提交
1524 1525
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1526

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

M
Mr.doob 已提交
1529
			// changed glsl or parameters
1530
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1531

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

T
tschw 已提交
1534
			// same glsl and uniform list
T
tschw 已提交
1535 1536
			return;

T
tschw 已提交
1537
		} else {
B
Ben Adams 已提交
1538

T
tschw 已提交
1539 1540
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1541 1542 1543

		}

1544
		if ( programChange ) {
B
Ben Adams 已提交
1545

1546
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1547

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

1550 1551 1552 1553 1554 1555
				materialProperties.__webglShader = {
					name: material.type,
					uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
					vertexShader: shader.vertexShader,
					fragmentShader: shader.fragmentShader
				};
B
Ben Adams 已提交
1556

1557
			} else {
B
Ben Adams 已提交
1558

1559 1560 1561 1562 1563 1564
				materialProperties.__webglShader = {
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
					fragmentShader: material.fragmentShader
				};
G
gero3 已提交
1565

1566
			}
G
gero3 已提交
1567

1568
			material.__webglShader = materialProperties.__webglShader;
G
gero3 已提交
1569

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

1572 1573
			materialProperties.program = program;
			material.program = program;
1574 1575 1576

		}

1577
		var attributes = program.getAttributes();
M
Mr.doob 已提交
1578 1579 1580 1581 1582

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

M
Mr.doob 已提交
1585
				if ( attributes[ 'morphTarget' + i ] >= 0 ) {
M
Mr.doob 已提交
1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

M
Mr.doob 已提交
1601
				if ( attributes[ 'morphNormal' + i ] >= 0 ) {
M
Mr.doob 已提交
1602 1603 1604 1605 1606 1607 1608 1609 1610

					material.numSupportedMorphNormals ++;

				}

			}

		}

T
tschw 已提交
1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622
		var uniforms = materialProperties.__webglShader.uniforms;

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

			materialProperties.numClippingPlanes = _numClippingPlanes;
			uniforms.clippingPlanes = _clippingPlanesUniform;

		}

		var uniformLocations = materialProperties.program.getUniforms();
M
Mr.doob 已提交
1623

T
tschw 已提交
1624
		materialProperties.uniformsList = [];
M
Mr.doob 已提交
1625

1626
		for ( var u in uniforms ) {
M
Mr.doob 已提交
1627

1628
			var location = uniformLocations[ u ];
1629 1630

			if ( location ) {
G
gero3 已提交
1631

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

1634
			}
M
Mr.doob 已提交
1635 1636 1637

		}

1638 1639
		if ( material instanceof THREE.MeshPhongMaterial ||
				material instanceof THREE.MeshLambertMaterial ||
1640
				material instanceof THREE.MeshStandardMaterial ||
1641 1642
				material.lights ) {

1643 1644
			// store the light setup it was created for

1645 1646
			materialProperties.lightsHash = _lights.hash;

1647 1648 1649 1650 1651
			// 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 已提交
1652
			uniforms.pointLights.value = _lights.point;
1653 1654
			uniforms.hemisphereLights.value = _lights.hemi;

1655 1656 1657 1658 1659 1660
			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;
1661

1662 1663
		}

A
arose 已提交
1664 1665 1666 1667 1668 1669 1670 1671
		// detect dynamic uniforms

		materialProperties.hasDynamicUniforms = false;

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

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

1672
			if ( uniform.dynamic === true ) {
A
arose 已提交
1673 1674 1675 1676 1677 1678 1679 1680

				materialProperties.hasDynamicUniforms = true;
				break;

			}

		}

M
Mr.doob 已提交
1681
	}
M
Mr.doob 已提交
1682

1683 1684
	function setMaterial( material ) {

M
Mr.doob 已提交
1685 1686
		setMaterialFaces( material );

1687 1688
		if ( material.transparent === true ) {

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

1691 1692 1693 1694
		} else {

			state.setBlending( THREE.NoBlending );

1695 1696
		}

B
Ben Adams 已提交
1697
		state.setDepthFunc( material.depthFunc );
M
Mr.doob 已提交
1698 1699
		state.setDepthTest( material.depthTest );
		state.setDepthWrite( material.depthWrite );
1700
		state.setColorWrite( material.colorWrite );
M
Mr.doob 已提交
1701
		state.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
1702 1703 1704

	}

M
Mr.doob 已提交
1705 1706
	function setMaterialFaces( material ) {

1707
		material.side !== THREE.DoubleSide ? state.enable( _gl.CULL_FACE ) : state.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
1708 1709 1710 1711
		state.setFlipSided( material.side === THREE.BackSide );

	}

1712
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1713 1714 1715

		_usedTextureUnits = 0;

1716
		var materialProperties = properties.get( material );
1717

T
tschw 已提交
1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743
		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)
				setClippingState(
						material.clippingPlanes, material.clipShadows,
						camera, materialProperties, useCache );

			}

			if ( materialProperties.numClippingPlanes !== undefined &&
				materialProperties.numClippingPlanes !== _numClippingPlanes ) {

				material.needsUpdate = true;

			}

		}

1744 1745 1746 1747 1748 1749
		if ( materialProperties.program === undefined ) {

			material.needsUpdate = true;

		}

1750 1751
		if ( materialProperties.lightsHash !== undefined &&
			materialProperties.lightsHash !== _lights.hash ) {
1752 1753 1754 1755 1756 1757

			material.needsUpdate = true;

		}

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

1759
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1760 1761 1762 1763
			material.needsUpdate = false;

		}

1764
		var refreshProgram = false;
M
Mr.doob 已提交
1765
		var refreshMaterial = false;
1766
		var refreshLights = false;
M
Mr.doob 已提交
1767

1768
		var program = materialProperties.program,
1769
			p_uniforms = program.getUniforms(),
1770
			m_uniforms = materialProperties.__webglShader.uniforms;
M
Mr.doob 已提交
1771

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

1774 1775
			_gl.useProgram( program.program );
			_currentProgram = program.id;
M
Mr.doob 已提交
1776

1777
			refreshProgram = true;
M
Mr.doob 已提交
1778
			refreshMaterial = true;
1779
			refreshLights = true;
M
Mr.doob 已提交
1780 1781 1782 1783 1784 1785

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1786

M
Mr.doob 已提交
1787 1788 1789 1790
			refreshMaterial = true;

		}

1791
		if ( refreshProgram || camera !== _currentCamera ) {
M
Mr.doob 已提交
1792 1793 1794

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

G
gero3 已提交
1795
			if ( capabilities.logarithmicDepthBuffer ) {
1796

1797
				_gl.uniform1f( p_uniforms.logDepthBufFC, 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1798 1799 1800 1801

			}


1802 1803 1804 1805 1806 1807 1808 1809 1810
			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 已提交
1811
				refreshLights = true;		// remains set until update done
1812 1813

			}
M
Mr.doob 已提交
1814

1815 1816 1817 1818 1819
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
1820
				 material instanceof THREE.MeshStandardMaterial ||
1821 1822
				 material.envMap ) {

1823
				if ( p_uniforms.cameraPosition !== undefined ) {
1824 1825 1826 1827 1828 1829 1830 1831 1832 1833

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

				}

			}

			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
1834
				 material instanceof THREE.MeshBasicMaterial ||
1835
				 material instanceof THREE.MeshStandardMaterial ||
1836 1837 1838
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {

1839
				if ( p_uniforms.viewMatrix !== undefined ) {
1840 1841

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

1843 1844 1845 1846
				}

			}

B
Ben Houston 已提交
1847 1848 1849 1850

			if ( p_uniforms.toneMappingExposure !== undefined ) {

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

B
Ben Houston 已提交
1852 1853 1854 1855 1856 1857 1858
			}

			if ( p_uniforms.toneMappingWhitePoint !== undefined ) {

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

			}
M
Mr.doob 已提交
1859

M
Mr.doob 已提交
1860 1861 1862 1863 1864 1865 1866 1867
		}

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

1868
			if ( object.bindMatrix && p_uniforms.bindMatrix !== undefined ) {
1869 1870 1871 1872 1873

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

			}

1874
			if ( object.bindMatrixInverse && p_uniforms.bindMatrixInverse !== undefined ) {
1875 1876 1877 1878 1879

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

			}

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

1882
				if ( p_uniforms.boneTexture !== undefined ) {
M
Mr.doob 已提交
1883 1884 1885 1886

					var textureUnit = getTextureUnit();

					_gl.uniform1i( p_uniforms.boneTexture, textureUnit );
1887
					_this.setTexture( object.skeleton.boneTexture, textureUnit );
M
Mr.doob 已提交
1888 1889 1890

				}

1891
				if ( p_uniforms.boneTextureWidth !== undefined ) {
1892

1893
					_gl.uniform1i( p_uniforms.boneTextureWidth, object.skeleton.boneTextureWidth );
1894 1895 1896

				}

1897
				if ( p_uniforms.boneTextureHeight !== undefined ) {
1898

1899
					_gl.uniform1i( p_uniforms.boneTextureHeight, object.skeleton.boneTextureHeight );
1900 1901 1902

				}

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

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

1907
					_gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.skeleton.boneMatrices );
M
Mr.doob 已提交
1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918

				}

			}

		}

		if ( refreshMaterial ) {

			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
1919
				 material instanceof THREE.MeshStandardMaterial ||
M
Mr.doob 已提交
1920 1921
				 material.lights ) {

1922
				// the current material requires lighting info
M
Mr.doob 已提交
1923

T
tschw 已提交
1924 1925 1926 1927 1928 1929
				// 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 已提交
1930

T
tschw 已提交
1931
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1932

T
tschw 已提交
1933
			}
G
gero3 已提交
1934

T
tschw 已提交
1935
			// refresh uniforms common to several materials
G
gero3 已提交
1936

T
tschw 已提交
1937
			if ( fog && material.fog ) {
G
gero3 已提交
1938

T
tschw 已提交
1939
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1940 1941 1942 1943 1944

			}

			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
W
WestLangley 已提交
1945
				 material instanceof THREE.MeshPhongMaterial ||
1946
				 material instanceof THREE.MeshStandardMaterial ) {
M
Mr.doob 已提交
1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962

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

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

M
Mr.doob 已提交
1965
				refreshUniformsPoints( m_uniforms, material );
M
Mr.doob 已提交
1966

1967 1968 1969 1970
			} else if ( material instanceof THREE.MeshLambertMaterial ) {

				refreshUniformsLambert( m_uniforms, material );

M
Mr.doob 已提交
1971 1972 1973 1974
			} else if ( material instanceof THREE.MeshPhongMaterial ) {

				refreshUniformsPhong( m_uniforms, material );

W
WestLangley 已提交
1975 1976 1977 1978
			} else if ( material instanceof THREE.MeshPhysicalMaterial ) {

				refreshUniformsPhysical( m_uniforms, material );

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

1981
				refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1982

M
Mr.doob 已提交
1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996
			} else if ( material instanceof THREE.MeshDepthMaterial ) {

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

			} else if ( material instanceof THREE.MeshNormalMaterial ) {

				m_uniforms.opacity.value = material.opacity;

			}

			// load common uniforms

1997
			loadUniformsGeneric( materialProperties.uniformsList );
M
Mr.doob 已提交
1998 1999 2000 2001 2002

		}

		loadUniformsMatrices( p_uniforms, object );

2003
		if ( p_uniforms.modelMatrix !== undefined ) {
M
Mr.doob 已提交
2004 2005

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

M
Mr.doob 已提交
2007 2008
		}

2009
		if ( materialProperties.hasDynamicUniforms === true ) {
A
arose 已提交
2010

2011
			updateDynamicUniforms( materialProperties.uniformsList, object, camera );
A
arose 已提交
2012 2013 2014

		}

M
Mr.doob 已提交
2015 2016
		return program;

M
Mr.doob 已提交
2017
	}
M
Mr.doob 已提交
2018

2019
	function updateDynamicUniforms ( uniforms, object, camera ) {
A
arose 已提交
2020 2021 2022 2023 2024 2025

		var dynamicUniforms = [];

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

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

2028
			if ( onUpdateCallback !== undefined ) {
A
arose 已提交
2029

2030
				onUpdateCallback.bind( uniform )( object, camera );
A
arose 已提交
2031 2032 2033 2034 2035 2036 2037 2038 2039 2040
				dynamicUniforms.push( uniforms[ j ] );

			}

		}

		loadUniformsGeneric( dynamicUniforms );

	}

M
Mr.doob 已提交
2041 2042 2043 2044 2045 2046
	// Uniforms (refresh uniforms objects)

	function refreshUniformsCommon ( uniforms, material ) {

		uniforms.opacity.value = material.opacity;

2047
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
2048

2049
		if ( material.emissive ) {
M
Mr.doob 已提交
2050

2051
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
2052 2053 2054

		}

2055 2056 2057
		uniforms.map.value = material.map;
		uniforms.specularMap.value = material.specularMap;
		uniforms.alphaMap.value = material.alphaMap;
M
Mr.doob 已提交
2058

2059
		if ( material.aoMap ) {
2060

2061 2062
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
2063 2064 2065

		}

M
Mr.doob 已提交
2066
		// uv repeat and offset setting priorities
M
Mr.doob 已提交
2067 2068 2069 2070 2071
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
2072
		// 6. emissive map
M
Mr.doob 已提交
2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

2084 2085 2086 2087
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
2088 2089 2090 2091 2092 2093 2094 2095
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

2096 2097 2098 2099 2100 2101 2102 2103
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

2104 2105 2106 2107
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

2108 2109 2110 2111
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
2112 2113 2114 2115
		}

		if ( uvScaleMap !== undefined ) {

M
Mr.doob 已提交
2116 2117 2118 2119 2120 2121
			if ( uvScaleMap instanceof THREE.WebGLRenderTarget ) {

				uvScaleMap = uvScaleMap.texture;

			}

M
Mr.doob 已提交
2122 2123 2124 2125 2126 2127 2128 2129
			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;
2130
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : - 1;
M
Mr.doob 已提交
2131

2132
		uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
2133 2134
		uniforms.refractionRatio.value = material.refractionRatio;

M
Mr.doob 已提交
2135
	}
M
Mr.doob 已提交
2136 2137 2138 2139 2140 2141

	function refreshUniformsLine ( uniforms, material ) {

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

M
Mr.doob 已提交
2142
	}
M
Mr.doob 已提交
2143 2144 2145 2146 2147 2148 2149

	function refreshUniformsDash ( uniforms, material ) {

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

M
Mr.doob 已提交
2150
	}
M
Mr.doob 已提交
2151

M
Mr.doob 已提交
2152
	function refreshUniformsPoints ( uniforms, material ) {
M
Mr.doob 已提交
2153

2154
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
2155
		uniforms.opacity.value = material.opacity;
2156
		uniforms.size.value = material.size * _pixelRatio;
T
tschw 已提交
2157
		uniforms.scale.value = _canvas.clientHeight * 0.5;
M
Mr.doob 已提交
2158 2159 2160

		uniforms.map.value = material.map;

2161 2162 2163 2164 2165 2166 2167 2168 2169
		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 已提交
2170
	}
M
Mr.doob 已提交
2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186

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

2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205
	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 已提交
2206 2207
	function refreshUniformsPhong ( uniforms, material ) {

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

2211 2212 2213 2214
		if ( material.lightMap ) {

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

2216
		}
2217

2218
		if ( material.emissiveMap ) {
2219

2220
			uniforms.emissiveMap.value = material.emissiveMap;
2221

2222
		}
M
Mr.doob 已提交
2223

2224 2225 2226 2227
		if ( material.bumpMap ) {

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

2229
		}
M
Mr.doob 已提交
2230

2231 2232 2233 2234 2235 2236
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2237

2238 2239 2240 2241 2242
		if ( material.displacementMap ) {

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

2244
		}
2245 2246 2247

	}

2248
	function refreshUniformsStandard ( uniforms, material ) {
W
WestLangley 已提交
2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308

		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 已提交
2309 2310 2311 2312 2313 2314
	function refreshUniformsPhysical ( uniforms, material ) {

		refreshUniformsStandard( uniforms, material );

	}

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

M
Mr.doob 已提交
2317
	function markUniformsLightsNeedsUpdate ( uniforms, value ) {
2318

M
Mr.doob 已提交
2319
		uniforms.ambientLightColor.needsUpdate = value;
2320

B
Ben Houston 已提交
2321 2322 2323 2324
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
		uniforms.hemisphereLights.needsUpdate = value;
2325

M
Mr.doob 已提交
2326
	}
2327

M
Mr.doob 已提交
2328 2329 2330 2331
	// Uniforms (load to GPU)

	function loadUniformsMatrices ( uniforms, object ) {

2332
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object.modelViewMatrix.elements );
M
Mr.doob 已提交
2333 2334 2335

		if ( uniforms.normalMatrix ) {

2336
			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object.normalMatrix.elements );
M
Mr.doob 已提交
2337 2338 2339

		}

M
Mr.doob 已提交
2340
	}
M
Mr.doob 已提交
2341 2342 2343 2344 2345

	function getTextureUnit() {

		var textureUnit = _usedTextureUnits;

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

G
gero3 已提交
2348
			console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
M
Mr.doob 已提交
2349 2350 2351 2352 2353 2354 2355

		}

		_usedTextureUnits += 1;

		return textureUnit;

M
Mr.doob 已提交
2356
	}
M
Mr.doob 已提交
2357

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

M
Mr.doob 已提交
2360
		var texture, textureUnit;
M
Mr.doob 已提交
2361

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

2364
			_gl.uniform1i( location, value );
M
Mr.doob 已提交
2365

2366
		} else if ( type === '1f' ) {
2367

2368 2369 2370
			_gl.uniform1f( location, value );

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

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

2374
		} else if ( type === '3f' ) {
2375

2376
			_gl.uniform3f( location, value[ 0 ], value[ 1 ], value[ 2 ] );
2377

2378
		} else if ( type === '4f' ) {
2379

2380
			_gl.uniform4f( location, value[ 0 ], value[ 1 ], value[ 2 ], value[ 3 ] );
2381

2382
		} else if ( type === '1iv' ) {
2383

2384
			_gl.uniform1iv( location, value );
2385

2386
		} else if ( type === '3iv' ) {
2387

2388
			_gl.uniform3iv( location, value );
2389

2390
		} else if ( type === '1fv' ) {
2391

2392
			_gl.uniform1fv( location, value );
2393

2394
		} else if ( type === '2fv' ) {
2395

2396
			_gl.uniform2fv( location, value );
2397

2398
		} else if ( type === '3fv' ) {
2399

2400
			_gl.uniform3fv( location, value );
2401

2402
		} else if ( type === '4fv' ) {
2403

2404
			_gl.uniform4fv( location, value );
M
Mr.doob 已提交
2405

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

2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418
			_gl.uniformMatrix2fv( location, false, value );

		} else if ( type === 'Matrix3fv' ) {

			_gl.uniformMatrix3fv( location, false, value );

		} else if ( type === 'Matrix4fv' ) {

			_gl.uniformMatrix4fv( location, false, value );

		//
M
Mr.doob 已提交
2419

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

2422
			// console.warn( 'THREE.WebGLRenderer: Uniform "i" is now "1i".' );
2423
			_gl.uniform1i( location, value );
M
Mr.doob 已提交
2424

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

2427
			// console.warn( 'THREE.WebGLRenderer: Uniform "f" is now "1f".' );
2428
			_gl.uniform1f( location, value );
M
Mr.doob 已提交
2429

2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449
		} else if ( type === 'iv1' ) {

			// console.warn( 'THREE.WebGLRenderer: Uniform "iv1" is now "1iv".' );
			_gl.uniform1iv( location, value );

		} else if ( type === 'iv' ) {

			// console.warn( 'THREE.WebGLRenderer: Uniform "iv" is now "3iv".' );
			_gl.uniform3iv( location, value );

		} else if ( type === 'fv1' ) {

			// console.warn( 'THREE.WebGLRenderer: Uniform "fv1" is now "1fv".' );
			_gl.uniform1fv( location, value );

		} else if ( type === 'fv' ) {

			// console.warn( 'THREE.WebGLRenderer: Uniform "fv" is now "3fv".' );
			_gl.uniform3fv( location, value );

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

2452 2453
			// single THREE.Vector2
			_gl.uniform2f( location, value.x, value.y );
M
Mr.doob 已提交
2454

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

2457 2458
			// single THREE.Vector3
			_gl.uniform3f( location, value.x, value.y, value.z );
M
Mr.doob 已提交
2459

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

2462 2463
			// single THREE.Vector4
			_gl.uniform4f( location, value.x, value.y, value.z, value.w );
M
Mr.doob 已提交
2464

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

2467 2468
			// single THREE.Color
			_gl.uniform3f( location, value.r, value.g, value.b );
M
Mr.doob 已提交
2469

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

2472
			// TODO: Optimize this
M
Mr.doob 已提交
2473

2474
			var properties = uniform.properties;
2475

2476
			for ( var name in properties ) {
2477

2478 2479 2480
				var property = properties[ name ];
				var locationProperty = location[ name ];
				var valueProperty = value[ name ];
2481

2482
				loadUniform( property, property.type, locationProperty, valueProperty );
2483 2484

			}
2485

2486 2487 2488 2489
		} else if ( type === 'sa' ) {

			// TODO: Optimize this

M
Mr.doob 已提交
2490
			var properties = uniform.properties;
2491

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

M
Mr.doob 已提交
2494
				for ( var name in properties ) {
2495

M
Mr.doob 已提交
2496 2497 2498
					var property = properties[ name ];
					var locationProperty =  location[ i ][ name ];
					var valueProperty = value[ i ][ name ];
2499

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

2502 2503
				}

2504
			}
2505

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

2508
			// array of THREE.Vector2
M
Mr.doob 已提交
2509

2510
			if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2511

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

2514
			}
M
Mr.doob 已提交
2515

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

2518 2519
				uniform._array[ i2 + 0 ] = value[ i ].x;
				uniform._array[ i2 + 1 ] = value[ i ].y;
M
Mr.doob 已提交
2520

2521
			}
2522

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

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

2527
			// array of THREE.Vector3
2528

2529
			if ( uniform._array === undefined ) {
2530

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

2533
			}
M
Mr.doob 已提交
2534

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

2537 2538 2539
				uniform._array[ i3 + 0 ] = value[ i ].x;
				uniform._array[ i3 + 1 ] = value[ i ].y;
				uniform._array[ i3 + 2 ] = value[ i ].z;
M
Mr.doob 已提交
2540

2541
			}
M
Mr.doob 已提交
2542

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

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

2547
			// array of THREE.Vector4
M
Mr.doob 已提交
2548

2549
			if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2550

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

2553
			}
R
Ryan Tsao 已提交
2554

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

2557 2558 2559 2560
				uniform._array[ i4 + 0 ] = value[ i ].x;
				uniform._array[ i4 + 1 ] = value[ i ].y;
				uniform._array[ i4 + 2 ] = value[ i ].z;
				uniform._array[ i4 + 3 ] = value[ i ].w;
R
Ryan Tsao 已提交
2561

2562
			}
R
Ryan Tsao 已提交
2563

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

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

2568 2569
			// single THREE.Matrix2
			_gl.uniformMatrix2fv( location, false, value.elements );
R
Ryan Tsao 已提交
2570

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

2573 2574
			// single THREE.Matrix3
			_gl.uniformMatrix3fv( location, false, value.elements );
M
Mr.doob 已提交
2575

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

2578
			// array of THREE.Matrix3
M
Mr.doob 已提交
2579

2580
			if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2581

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

2584
			}
M
Mr.doob 已提交
2585

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

2588
				value[ i ].flattenToArrayOffset( uniform._array, i * 9 );
2589

2590
			}
2591

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

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

2596 2597
			// single THREE.Matrix4
			_gl.uniformMatrix4fv( location, false, value.elements );
M
Mr.doob 已提交
2598

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

2601
			// array of THREE.Matrix4
M
Mr.doob 已提交
2602

2603
			if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2604

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

2607
			}
M
Mr.doob 已提交
2608

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

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

2613
			}
M
Mr.doob 已提交
2614

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

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

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

2621 2622
			texture = value;
			textureUnit = getTextureUnit();
M
Mr.doob 已提交
2623

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

2626
			if ( ! texture ) return;
M
Mr.doob 已提交
2627

2628 2629
			if ( texture instanceof THREE.CubeTexture ||
				 ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
M
Mr.doob 已提交
2630

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

2633
				setCubeTexture( texture, textureUnit );
2634

2635
			} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
2636

2637
				setCubeTextureDynamic( texture.texture, textureUnit );
2638

2639
			} else if ( texture instanceof THREE.WebGLRenderTarget ) {
2640

2641
				_this.setTexture( texture.texture, textureUnit );
2642

2643
			} else {
M
Mr.doob 已提交
2644

2645
				_this.setTexture( texture, textureUnit );
M
Mr.doob 已提交
2646

2647
			}
M
Mr.doob 已提交
2648

2649
		} else if ( type === 'tv' ) {
2650

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

2653
			if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2654

2655
				uniform._array = [];
G
gero3 已提交
2656

2657
			}
M
Mr.doob 已提交
2658

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

2661
				uniform._array[ i ] = getTextureUnit();
2662

2663
			}
M
Mr.doob 已提交
2664

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

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

2669 2670
				texture = uniform.value[ i ];
				textureUnit = uniform._array[ i ];
2671

2672
				if ( ! texture ) continue;
2673

2674
				if ( texture instanceof THREE.CubeTexture ||
2675
					 ( texture.image instanceof Array && texture.image.length === 6 ) ) {
2676

2677
					// CompressedTexture can have Array in image :/
2678

2679
					setCubeTexture( texture, textureUnit );
2680

2681
				} else if ( texture instanceof THREE.WebGLRenderTarget ) {
2682

2683
					_this.setTexture( texture.texture, textureUnit );
2684

2685
				} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
2686

2687
					setCubeTextureDynamic( texture.texture, textureUnit );
M
Mr.doob 已提交
2688

2689
				} else {
M
Mr.doob 已提交
2690

2691
					_this.setTexture( texture, textureUnit );
M
Mr.doob 已提交
2692

2693
				}
M
Mr.doob 已提交
2694

2695
			}
2696

2697
		} else {
2698

2699
			console.warn( 'THREE.WebGLRenderer: Unknown uniform type: ' + type );
2700

2701
		}
2702

2703
	}
2704

2705
	function loadUniformsGeneric( uniforms ) {
2706

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

2709
			var uniform = uniforms[ i ][ 0 ];
2710

2711 2712
			// needsUpdate property is not added to all uniforms.
			if ( uniform.needsUpdate === false ) continue;
2713

2714 2715 2716
			var type = uniform.type;
			var location = uniforms[ i ][ 1 ];
			var value = uniform.value;
2717

2718
			loadUniform( uniform, type, location, value );
M
Mr.doob 已提交
2719 2720 2721

		}

M
Mr.doob 已提交
2722
	}
M
Mr.doob 已提交
2723

2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743
	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 已提交
2744
	function setupLights ( lights, camera ) {
M
Mr.doob 已提交
2745

B
brason 已提交
2746
		var l, ll, light,
M
Mr.doob 已提交
2747
		r = 0, g = 0, b = 0,
B
Ben Houston 已提交
2748
		color,
B
brason 已提交
2749
		intensity,
M
Mr.doob 已提交
2750 2751
		distance,

2752
		viewMatrix = camera.matrixWorldInverse,
M
Mr.doob 已提交
2753

M
Mr.doob 已提交
2754
		directionalLength = 0,
M
Mr.doob 已提交
2755 2756
		pointLength = 0,
		spotLength = 0,
2757
		hemiLength = 0;
M
Mr.doob 已提交
2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768

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

			light = lights[ l ];

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

			if ( light instanceof THREE.AmbientLight ) {

2769 2770 2771
				r += color.r * intensity;
				g += color.g * intensity;
				b += color.b * intensity;
M
Mr.doob 已提交
2772 2773 2774

			} else if ( light instanceof THREE.DirectionalLight ) {

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

2777
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
M
Mr.doob 已提交
2778
				uniforms.direction.setFromMatrixPosition( light.matrixWorld );
2779
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
M
Mr.doob 已提交
2780 2781 2782
				uniforms.direction.sub( _vector3 );
				uniforms.direction.transformDirection( viewMatrix );

2783
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2784

2785
				if ( light.castShadow ) {
M
Mr.doob 已提交
2786

2787 2788 2789
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;
2790

2791 2792
				}

2793 2794
				_lights.directionalShadowMap[ directionalLength ] = light.shadow.map;
				_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
2795
				_lights.directional[ directionalLength ++ ] = uniforms;
M
Mr.doob 已提交
2796

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

M
Mr.doob 已提交
2799
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2800 2801 2802

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

M
Mr.doob 已提交
2804 2805 2806 2807 2808 2809 2810 2811
				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 );

2812 2813
				uniforms.coneCos = Math.cos( light.angle );
				uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
M
Mr.doob 已提交
2814
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
M
Mr.doob 已提交
2815

2816
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2817

2818 2819
				if ( light.castShadow ) {

2820 2821 2822
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;
2823

2824 2825
				}

2826 2827
				_lights.spotShadowMap[ spotLength ] = light.shadow.map;
				_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;
M
Mr.doob 已提交
2828
				_lights.spot[ spotLength ++ ] = uniforms;
2829

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

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

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

M
Mr.doob 已提交
2837 2838
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
				uniforms.distance = light.distance;
M
Mr.doob 已提交
2839 2840
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;

2841
				uniforms.shadow = light.castShadow;
2842

M
Mr.doob 已提交
2843
				if ( light.castShadow ) {
2844

2845 2846 2847 2848 2849
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;

				}
2850

2851
				_lights.pointShadowMap[ pointLength ] = light.shadow.map;
2852

2853 2854 2855
				if ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {

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

2857 2858
				}

2859 2860 2861 2862 2863
				// 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 已提交
2864
				_lights.point[ pointLength ++ ] = uniforms;
2865

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

M
Mr.doob 已提交
2868
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2869 2870 2871 2872

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

M
Mr.doob 已提交
2874 2875
				uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
				uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
M
Mr.doob 已提交
2876

M
Mr.doob 已提交
2877
				_lights.hemi[ hemiLength ++ ] = uniforms;
M
Mr.doob 已提交
2878 2879 2880 2881 2882

			}

		}

M
Mr.doob 已提交
2883 2884 2885
		_lights.ambient[ 0 ] = r;
		_lights.ambient[ 1 ] = g;
		_lights.ambient[ 2 ] = b;
M
Mr.doob 已提交
2886

M
Mr.doob 已提交
2887 2888
		_lights.directional.length = directionalLength;
		_lights.spot.length = spotLength;
2889
		_lights.point.length = pointLength;
M
Mr.doob 已提交
2890
		_lights.hemi.length = hemiLength;
2891

2892
		_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + hemiLength + ',' + _lights.shadows.length;
2893

M
Mr.doob 已提交
2894
	}
M
Mr.doob 已提交
2895

T
tschw 已提交
2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012

	function setupGlobalClippingPlanes( planes, camera ) {

		_clippingEnabled =
				_this.clippingPlanes.length !== 0 ||
				_this.localClippingEnabled ||
				// enable state of previous frame - the clipping code has to
				// run another frame in order to reset the state:
				_numGlobalClippingPlanes !== 0 ||
				_localClippingEnabled;

		_localClippingEnabled = _this.localClippingEnabled;

		_globalClippingState = setupClippingPlanes( planes, camera, 0 );
		_numGlobalClippingPlanes = planes !== null ? planes.length : 0;

	}

	function setupClippingPlanes( planes, camera, dstOffset, skipTransform ) {

		var nPlanes = planes !== null ? planes.length : 0,
			dstArray = null;

		if ( nPlanes !== 0 ) {

			dstArray = _clippingPlanesUniform.value;

			if ( skipTransform !== true || dstArray === null ) {

				var flatSize = dstOffset + nPlanes * 4,
					viewMatrix = camera.matrixWorldInverse,
					viewNormalMatrix = _matrix3.getNormalMatrix( viewMatrix );

				if ( dstArray === null || dstArray.length < flatSize ) {

					dstArray = new Float32Array( flatSize );

				}

				for ( var i = 0, i4 = dstOffset; i !== nPlanes; ++ i, i4 += 4 ) {

					var plane = _plane.copy( planes[ i ] ).
							applyMatrix4( viewMatrix, viewNormalMatrix );

					plane.normal.toArray( dstArray, i4 );
					dstArray[ i4 + 3 ] = plane.constant;

				}

			}

			_clippingPlanesUniform.value = dstArray;
			_clippingPlanesUniform.needsUpdate = true;

		}

		_numClippingPlanes = nPlanes;
		return dstArray;

	}

	function resetGlobalClippingState() {

		if ( _clippingPlanesUniform.value !== _globalClippingState ) {

			_clippingPlanesUniform.value = _globalClippingState;
			_clippingPlanesUniform.needsUpdate = _numGlobalClippingPlanes > 0;

		}

		_numClippingPlanes = _numGlobalClippingPlanes;

	}

	function setClippingState( planes, clipShadows, camera, cache, fromCache ) {

		if ( ! _localClippingEnabled ||
				planes === null || planes.length === 0 ||
				_clipRenderingShadows && ! clipShadows ) {
			// there's no local clipping

			if ( _clipRenderingShadows ) {
				// there's no global clipping

				setupClippingPlanes( null );

			} else {

				resetGlobalClippingState();
			}

		} else {

			var nGlobal = _clipRenderingShadows ? 0 : _numGlobalClippingPlanes,
				lGlobal = nGlobal * 4,

				dstArray = cache.clippingState || null;

			_clippingPlanesUniform.value = dstArray; // ensure unique state

			dstArray = setupClippingPlanes(
					planes, camera, lGlobal, fromCache );

			for ( var i = 0; i !== lGlobal; ++ i ) {

				dstArray[ i ] = _globalClippingState[ i ];

			}

			cache.clippingState = dstArray;
			_numClippingPlanes += nGlobal;

		}

	}


M
Mr.doob 已提交
3013 3014 3015 3016 3017 3018
	// GL state setting

	this.setFaceCulling = function ( cullFace, frontFaceDirection ) {

		if ( cullFace === THREE.CullFaceNone ) {

3019
			state.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046

		} else {

			if ( frontFaceDirection === THREE.FrontFaceDirectionCW ) {

				_gl.frontFace( _gl.CW );

			} else {

				_gl.frontFace( _gl.CCW );

			}

			if ( cullFace === THREE.CullFaceBack ) {

				_gl.cullFace( _gl.BACK );

			} else if ( cullFace === THREE.CullFaceFront ) {

				_gl.cullFace( _gl.FRONT );

			} else {

				_gl.cullFace( _gl.FRONT_AND_BACK );

			}

3047
			state.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
3048 3049 3050 3051 3052 3053 3054

		}

	};

	// Textures

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

3057 3058
		var extension;

M
Mr.doob 已提交
3059
		if ( isPowerOfTwoImage ) {
M
Mr.doob 已提交
3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070

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

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

		} else {

			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
M
Mr.doob 已提交
3071 3072 3073

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

M
Mr.doob 已提交
3074
				console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );
M
Mr.doob 已提交
3075

3076
			}
M
Mr.doob 已提交
3077 3078 3079 3080

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

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

M
Mr.doob 已提交
3083
				console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );
M
Mr.doob 已提交
3084

3085
			}
M
Mr.doob 已提交
3086

M
Mr.doob 已提交
3087 3088
		}

3089 3090
		extension = extensions.get( 'EXT_texture_filter_anisotropic' );

3091
		if ( extension ) {
M
Mr.doob 已提交
3092

3093 3094
			if ( texture.type === THREE.FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;
			if ( texture.type === THREE.HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;
M
Mr.doob 已提交
3095

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

3098
				_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _this.getMaxAnisotropy() ) );
3099
				properties.get( texture ).__currentAnisotropy = texture.anisotropy;
M
Mr.doob 已提交
3100 3101 3102 3103 3104

			}

		}

M
Mr.doob 已提交
3105
	}
M
Mr.doob 已提交
3106

3107
	function uploadTexture( textureProperties, texture, slot ) {
3108

3109
		if ( textureProperties.__webglInit === undefined ) {
3110

3111
			textureProperties.__webglInit = true;
3112 3113 3114

			texture.addEventListener( 'dispose', onTextureDispose );

3115
			textureProperties.__webglTexture = _gl.createTexture();
3116

3117
			_infoMemory.textures ++;
3118 3119

		}
M
Mr.doob 已提交
3120

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

H
Henri Astre 已提交
3124 3125 3126 3127
		_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
		_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
		_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );

3128
		var image = clampToMaxSize( texture.image, capabilities.maxTextureSize );
3129

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

3132
			image = makePowerOfTwo( image );
M
Mr.doob 已提交
3133 3134 3135

		}

M
Mr.doob 已提交
3136
		var isPowerOfTwoImage = isPowerOfTwo( image ),
H
Henri Astre 已提交
3137 3138
		glFormat = paramThreeToGL( texture.format ),
		glType = paramThreeToGL( texture.type );
M
Mr.doob 已提交
3139

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

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

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

H
Henri Astre 已提交
3146 3147 3148
			// use manually created mipmaps if available
			// if there are no manual mipmaps
			// set 0 level mipmap and then use GL to generate other mipmap levels
M
Mr.doob 已提交
3149

M
Mr.doob 已提交
3150
			if ( mipmaps.length > 0 && isPowerOfTwoImage ) {
H
Henri Astre 已提交
3151 3152

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

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

H
Henri Astre 已提交
3157
				}
M
Mr.doob 已提交
3158

H
Henri Astre 已提交
3159
				texture.generateMipmaps = false;
M
Mr.doob 已提交
3160

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

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

H
Henri Astre 已提交
3165
			}
M
Mr.doob 已提交
3166

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

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

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

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

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

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

3179
					} else {
M
Mr.doob 已提交
3180

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

3183
					}
M
Mr.doob 已提交
3184

H
Henri Astre 已提交
3185
				} else {
M
Mr.doob 已提交
3186

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

M
Mr.doob 已提交
3189 3190
				}

H
Henri Astre 已提交
3191 3192
			}

G
gero3 已提交
3193 3194 3195
		} else {

			// regular Texture (image, video, canvas)
H
Henri Astre 已提交
3196 3197 3198 3199 3200

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

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

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

					mipmap = mipmaps[ i ];
3206
					state.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );
M
Mr.doob 已提交
3207 3208 3209

				}

H
Henri Astre 已提交
3210
				texture.generateMipmaps = false;
M
Mr.doob 已提交
3211

H
Henri Astre 已提交
3212
			} else {
M
Mr.doob 已提交
3213

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

H
Henri Astre 已提交
3216
			}
M
Mr.doob 已提交
3217

H
Henri Astre 已提交
3218
		}
M
Mr.doob 已提交
3219

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

3222
		textureProperties.__version = texture.version;
M
Mr.doob 已提交
3223

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

3226
	}
M
Mr.doob 已提交
3227

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

3230 3231 3232
		var textureProperties = properties.get( texture );

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

3234
			var image = texture.image;
M
Mr.doob 已提交
3235

3236 3237
			if ( image === undefined ) {

3238
				console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );
3239 3240 3241 3242
				return;

			}

3243
			if ( image.complete === false ) {
M
Mr.doob 已提交
3244

3245
				console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );
3246 3247 3248 3249
				return;

			}

3250
			uploadTexture( textureProperties, texture, slot );
3251

3252
			return;
M
Mr.doob 已提交
3253 3254 3255

		}

B
Ben Adams 已提交
3256
		state.activeTexture( _gl.TEXTURE0 + slot );
3257
		state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
3258

M
Mr.doob 已提交
3259 3260 3261 3262
	};

	function clampToMaxSize ( image, maxSize ) {

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

3265 3266
			// Warning: Scaling through the canvas will only work with images that use
			// premultiplied alpha.
M
Mr.doob 已提交
3267

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

3270 3271 3272
			var canvas = document.createElement( 'canvas' );
			canvas.width = Math.floor( image.width * scale );
			canvas.height = Math.floor( image.height * scale );
M
Mr.doob 已提交
3273

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

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

3279 3280 3281
			return canvas;

		}
M
Mr.doob 已提交
3282

3283
		return image;
M
Mr.doob 已提交
3284 3285 3286

	}

M
Mr.doob 已提交
3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322
	function isPowerOfTwo( image ) {

		return THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height );

	}

	function textureNeedsPowerOfTwo( texture ) {

		if ( texture.wrapS !== THREE.ClampToEdgeWrapping || texture.wrapT !== THREE.ClampToEdgeWrapping ) return true;
		if ( texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) return true;

		return false;

	}

	function makePowerOfTwo( image ) {

		if ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {

			var canvas = document.createElement( 'canvas' );
			canvas.width = THREE.Math.nearestPowerOfTwo( image.width );
			canvas.height = THREE.Math.nearestPowerOfTwo( image.height );

			var context = canvas.getContext( '2d' );
			context.drawImage( image, 0, 0, canvas.width, canvas.height );

			console.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );

			return canvas;

		}

		return image;

	}

M
Mr.doob 已提交
3323 3324
	function setCubeTexture ( texture, slot ) {

3325
		var textureProperties = properties.get( texture );
3326

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

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

3331
				if ( ! textureProperties.__image__webglTextureCube ) {
M
Mr.doob 已提交
3332

3333 3334
					texture.addEventListener( 'dispose', onTextureDispose );

3335
					textureProperties.__image__webglTextureCube = _gl.createTexture();
M
Mr.doob 已提交
3336

3337
					_infoMemory.textures ++;
M
Mr.doob 已提交
3338 3339 3340

				}

B
Ben Adams 已提交
3341
				state.activeTexture( _gl.TEXTURE0 + slot );
3342
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
3343 3344 3345

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

M
Mr.doob 已提交
3346 3347
				var isCompressed = texture instanceof THREE.CompressedTexture;
				var isDataTexture = texture.image[ 0 ] instanceof THREE.DataTexture;
M
Mr.doob 已提交
3348 3349 3350 3351 3352

				var cubeImage = [];

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

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

G
gero3 已提交
3355
						cubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );
M
Mr.doob 已提交
3356 3357 3358

					} else {

3359
						cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];
M
Mr.doob 已提交
3360 3361 3362 3363 3364 3365

					}

				}

				var image = cubeImage[ 0 ],
M
Mr.doob 已提交
3366
				isPowerOfTwoImage = isPowerOfTwo( image ),
M
Mr.doob 已提交
3367 3368 3369
				glFormat = paramThreeToGL( texture.format ),
				glType = paramThreeToGL( texture.type );

M
Mr.doob 已提交
3370
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );
M
Mr.doob 已提交
3371 3372 3373

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

3374
					if ( ! isCompressed ) {
M
Mr.doob 已提交
3375

M
Mr.doob 已提交
3376
						if ( isDataTexture ) {
3377

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

M
Mr.doob 已提交
3380
						} else {
3381

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

M
Mr.doob 已提交
3384 3385
						}

3386
					} else {
3387

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

3390
						for ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {
M
Mr.doob 已提交
3391 3392

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

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

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

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

3400
								} else {
M
Mr.doob 已提交
3401

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

3404
								}
M
Mr.doob 已提交
3405

3406
							} else {
M
Mr.doob 已提交
3407

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

3410
							}
M
Mr.doob 已提交
3411

3412
						}
M
Mr.doob 已提交
3413

M
Mr.doob 已提交
3414
					}
M
Mr.doob 已提交
3415

M
Mr.doob 已提交
3416 3417
				}

M
Mr.doob 已提交
3418
				if ( texture.generateMipmaps && isPowerOfTwoImage ) {
M
Mr.doob 已提交
3419 3420 3421 3422 3423

					_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

				}

3424
				textureProperties.__version = texture.version;
M
Mr.doob 已提交
3425

B
Ben Adams 已提交
3426
				if ( texture.onUpdate ) texture.onUpdate( texture );
M
Mr.doob 已提交
3427 3428 3429

			} else {

B
Ben Adams 已提交
3430
				state.activeTexture( _gl.TEXTURE0 + slot );
3431
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
3432 3433 3434 3435 3436

			}

		}

M
Mr.doob 已提交
3437
	}
M
Mr.doob 已提交
3438 3439 3440

	function setCubeTextureDynamic ( texture, slot ) {

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

M
Mr.doob 已提交
3444
	}
M
Mr.doob 已提交
3445 3446 3447

	// Render targets

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

3451 3452 3453
		var glFormat = paramThreeToGL( renderTarget.texture.format );
		var glType = paramThreeToGL( renderTarget.texture.type );
		state.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
M
Mr.doob 已提交
3454
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
3455 3456
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
M
Mr.doob 已提交
3457

M
Mr.doob 已提交
3458
	}
M
Mr.doob 已提交
3459

3460 3461
	// Setup storage for internal depth/stencil buffers and bind to correct framebuffer
	function setupRenderBufferStorage ( renderbuffer, renderTarget ) {
M
Mr.doob 已提交
3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476

		_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );

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

			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );

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

			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );

		} else {

3477
			// FIXME: We don't support !depth !stencil
M
Mr.doob 已提交
3478 3479 3480 3481
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );

		}

3482
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
M
Mr.doob 已提交
3483

M
Mr.doob 已提交
3484
	}
M
Mr.doob 已提交
3485

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

3489
		var renderTargetProperties = properties.get( renderTarget );
M
Mr.doob 已提交
3490 3491

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

3493
		if ( isCube ) {
M
Mr.doob 已提交
3494

3495
			renderTargetProperties.__webglDepthbuffer = [];
M
Mr.doob 已提交
3496

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

M
Marius Kintel 已提交
3499
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );
3500 3501
				renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();
				setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );
M
Mr.doob 已提交
3502 3503

			}
B
Ben Adams 已提交
3504

M
Mr.doob 已提交
3505
		} else {
M
Mr.doob 已提交
3506

M
Marius Kintel 已提交
3507
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );
3508 3509
			renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
			setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );
M
Mr.doob 已提交
3510

3511
		}
M
Mr.doob 已提交
3512

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

M
Mr.doob 已提交
3515
	}
M
Mr.doob 已提交
3516

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

3520 3521
		var renderTargetProperties = properties.get( renderTarget );
		var textureProperties = properties.get( renderTarget.texture );
M
Mr.doob 已提交
3522

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

3525
		textureProperties.__webglTexture = _gl.createTexture();
M
Mr.doob 已提交
3526

3527
		_infoMemory.textures ++;
M
Mr.doob 已提交
3528

3529 3530
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
		var isTargetPowerOfTwo = THREE.Math.isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height );
M
Mr.doob 已提交
3531

3532
		// Setup framebuffer
M
Mr.doob 已提交
3533

3534
		if ( isCube ) {
M
Mr.doob 已提交
3535

3536
			renderTargetProperties.__webglFramebuffer = [];
M
Mr.doob 已提交
3537

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

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

3542
			}
M
Mr.doob 已提交
3543

3544
		} else {
M
Mr.doob 已提交
3545

3546
			renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
M
Mr.doob 已提交
3547

3548
		}
M
Mr.doob 已提交
3549

3550
		// Setup color buffer
M
Mr.doob 已提交
3551

3552
		if ( isCube ) {
M
Mr.doob 已提交
3553

3554 3555
			state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
			setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );
M
Mr.doob 已提交
3556

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

3559
				setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
M
Mr.doob 已提交
3560 3561 3562

			}

3563 3564
			if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
			state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
M
Mr.doob 已提交
3565

3566
		} else {
M
Mr.doob 已提交
3567

3568 3569 3570
			state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
			setTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );
			setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );
M
Mr.doob 已提交
3571

3572 3573
			if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
			state.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
3574

3575
		}
M
Mr.doob 已提交
3576

3577
		// Setup depth and stencil buffers
3578

3579
		if ( renderTarget.depthBuffer ) {
M
Mr.doob 已提交
3580

M
Marius Kintel 已提交
3581
			setupDepthRenderbuffer( renderTarget );
M
Mr.doob 已提交
3582

3583
		}
M
Mr.doob 已提交
3584

3585
	}
M
Mr.doob 已提交
3586

3587 3588 3589 3590 3591 3592
	this.getCurrentRenderTarget = function() {

		return _currentRenderTarget;

	}

3593
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
3594

3595 3596
		_currentRenderTarget = renderTarget;

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

M
Marius Kintel 已提交
3599
			setupRenderTarget( renderTarget );
M
Mr.doob 已提交
3600 3601 3602

		}

3603
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
3604
		var framebuffer;
M
Mr.doob 已提交
3605 3606 3607

		if ( renderTarget ) {

3608
			var renderTargetProperties = properties.get( renderTarget );
F
Fordy 已提交
3609

M
Mr.doob 已提交
3610 3611
			if ( isCube ) {

3612
				framebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
3613 3614 3615

			} else {

3616
				framebuffer = renderTargetProperties.__webglFramebuffer;
M
Mr.doob 已提交
3617 3618 3619

			}

3620 3621
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
3622

3623
			_currentViewport.copy( renderTarget.viewport );
M
Mr.doob 已提交
3624 3625 3626 3627 3628

		} else {

			framebuffer = null;

3629
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
3630
			_currentScissorTest = _scissorTest;
3631

3632
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
M
Mr.doob 已提交
3633 3634 3635

		}

M
Mr.doob 已提交
3636
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
3637 3638 3639 3640 3641 3642

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

		}

3643 3644
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
3645

3646
		state.viewport( _currentViewport );
3647

M
Mr.doob 已提交
3648 3649 3650
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
3651
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
3652 3653 3654

		}

M
Mr.doob 已提交
3655 3656
	};

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

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

3661
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
3662
			return;
3663

G
gero3 已提交
3664
		}
3665

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

M
Mr.doob 已提交
3668
		if ( framebuffer ) {
3669

G
gero3 已提交
3670
			var restore = false;
3671

M
Mr.doob 已提交
3672
			if ( framebuffer !== _currentFramebuffer ) {
3673

M
Mr.doob 已提交
3674
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
3675

G
gero3 已提交
3676
				restore = true;
3677

G
gero3 已提交
3678
			}
3679

M
Mr.doob 已提交
3680
			try {
3681

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

M
Mr.doob 已提交
3684 3685
				if ( texture.format !== THREE.RGBAFormat
					&& paramThreeToGL( texture.format ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
3686

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

M
Mr.doob 已提交
3690
				}
3691

M
Mr.doob 已提交
3692 3693 3694 3695
				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' ) ) ) {
3696

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

M
Mr.doob 已提交
3700
				}
3701

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

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

M
Mr.doob 已提交
3706
				} else {
M
Mr.doob 已提交
3707

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

				}
M
Mr.doob 已提交
3711

M
Mr.doob 已提交
3712
			} finally {
M
Mr.doob 已提交
3713

M
Mr.doob 已提交
3714 3715 3716
				if ( restore ) {

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

M
Mr.doob 已提交
3718 3719 3720
				}

			}
M
Mr.doob 已提交
3721 3722 3723

		}

M
Mr.doob 已提交
3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734
	};

	function updateRenderTargetMipmap( renderTarget ) {

		var target = renderTarget instanceof THREE.WebGLRenderTargetCube ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;
		var texture = properties.get( renderTarget.texture ).__webglTexture;

		state.bindTexture( target, texture );
		_gl.generateMipmap( target );
		state.bindTexture( target, null );

M
Mr.doob 已提交
3735
	}
M
Mr.doob 已提交
3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748

	// Fallback filters for non-power-of-2 textures

	function filterFallback ( f ) {

		if ( f === THREE.NearestFilter || f === THREE.NearestMipMapNearestFilter || f === THREE.NearestMipMapLinearFilter ) {

			return _gl.NEAREST;

		}

		return _gl.LINEAR;

M
Mr.doob 已提交
3749
	}
M
Mr.doob 已提交
3750 3751 3752 3753 3754

	// Map three.js constants to WebGL constants

	function paramThreeToGL ( p ) {

3755 3756
		var extension;

M
Mr.doob 已提交
3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780
		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;

3781 3782 3783 3784 3785 3786 3787 3788
		extension = extensions.get( 'OES_texture_half_float' );

		if ( extension !== null ) {

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

		}

M
Mr.doob 已提交
3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811
		if ( p === THREE.AlphaFormat ) return _gl.ALPHA;
		if ( p === THREE.RGBFormat ) return _gl.RGB;
		if ( p === THREE.RGBAFormat ) return _gl.RGBA;
		if ( p === THREE.LuminanceFormat ) return _gl.LUMINANCE;
		if ( p === THREE.LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;

		if ( p === THREE.AddEquation ) return _gl.FUNC_ADD;
		if ( p === THREE.SubtractEquation ) return _gl.FUNC_SUBTRACT;
		if ( p === THREE.ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;

		if ( p === THREE.ZeroFactor ) return _gl.ZERO;
		if ( p === THREE.OneFactor ) return _gl.ONE;
		if ( p === THREE.SrcColorFactor ) return _gl.SRC_COLOR;
		if ( p === THREE.OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;
		if ( p === THREE.SrcAlphaFactor ) return _gl.SRC_ALPHA;
		if ( p === THREE.OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;
		if ( p === THREE.DstAlphaFactor ) return _gl.DST_ALPHA;
		if ( p === THREE.OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;

		if ( p === THREE.DstColorFactor ) return _gl.DST_COLOR;
		if ( p === THREE.OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;
		if ( p === THREE.SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;

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

3814 3815 3816 3817 3818 3819
		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 已提交
3820 3821 3822

		}

3823 3824 3825
		extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );

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

3827 3828 3829 3830
			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 已提交
3831 3832 3833

		}

3834 3835 3836 3837 3838 3839 3840 3841
		extension = extensions.get( 'WEBGL_compressed_texture_etc1' );

		if ( extension !== null ) {

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

		}

3842 3843 3844
		extension = extensions.get( 'EXT_blend_minmax' );

		if ( extension !== null ) {
3845

3846 3847
			if ( p === THREE.MinEquation ) return extension.MIN_EXT;
			if ( p === THREE.MaxEquation ) return extension.MAX_EXT;
3848 3849 3850

		}

M
Mr.doob 已提交
3851 3852
		return 0;

M
Mr.doob 已提交
3853
	}
M
Mr.doob 已提交
3854 3855

};