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

THREE.WebGLRenderer = function ( parameters ) {

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

	parameters = parameters || {};

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

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

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

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

31 32
	var morphInfluences = new Float32Array( 8 );

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

M
Mr.doob 已提交
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
	// public properties

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

	// clearing

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

	// scene graph

	this.sortObjects = true;

	// physically based shading

54
	this.gammaFactor = 2.0;	// for backwards compatibility
M
Mr.doob 已提交
55 56 57
	this.gammaInput = false;
	this.gammaOutput = false;

58 59 60 61
	// physical lights

	this.physicalLights = false;
	
B
Ben Houston 已提交
62 63 64 65 66 67
	// tone mapping

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

M
Mr.doob 已提交
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
	// morphs

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

	// flags

	this.autoScaleCubemaps = true;

	// internal properties

	var _this = this,

	// internal state cache

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

90 91 92 93 94
	_currentScissor = new THREE.Vector4(),
	_currentScissorTest = null,

	_currentViewport = new THREE.Vector4(),

95 96
	//

M
Mr.doob 已提交
97 98
	_usedTextureUnits = 0,

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

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

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

	_pixelRatio = 1,

	_scissor = new THREE.Vector4( 0, 0, _width, _height ),
110 111
	_scissorTest = false,

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

M
Mr.doob 已提交
114 115 116 117
	// frustum

	_frustum = new THREE.Frustum(),

M
Mr.doob 已提交
118
	// camera matrices cache
M
Mr.doob 已提交
119 120 121 122 123 124 125 126 127

	_projScreenMatrix = new THREE.Matrix4(),

	_vector3 = new THREE.Vector3(),

	// light arrays cache

	_lights = {

128 129
		hash: '',

M
Mr.doob 已提交
130
		ambient: [ 0, 0, 0 ],
M
Mr.doob 已提交
131
		directional: [],
132 133
		directionalShadowMap: [],
		directionalShadowMatrix: [],
M
Mr.doob 已提交
134
		spot: [],
135 136
		spotShadowMap: [],
		spotShadowMatrix: [],
M
Mr.doob 已提交
137
		point: [],
138 139
		pointShadowMap: [],
		pointShadowMatrix: [],
140 141
		hemi: [],

142
		shadows: [],
143
		shadowsPointLight: 0
M
Mr.doob 已提交
144

145 146
	},

M
Mr.doob 已提交
147 148
	// info

149
	_infoMemory = {
150 151

		geometries: 0,
T
tschw 已提交
152
		textures: 0
153 154 155

	},

156
	_infoRender = {
157 158 159 160 161 162

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

M
Mr.doob 已提交
163 164
	};

M
Mr.doob 已提交
165
	this.info = {
166

M
Mr.doob 已提交
167 168
		render: _infoRender,
		memory: _infoMemory,
169
		programs: null
M
Mr.doob 已提交
170 171

	};
172

173

M
Mr.doob 已提交
174 175 176 177
	// initialize

	var _gl;

M
Mr.doob 已提交
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
	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 已提交
193
			if ( _canvas.getContext( 'webgl' ) !== null ) {
194 195 196 197 198 199 200 201

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

			} else {

				throw 'Error creating WebGL context.';

			}
M
Mr.doob 已提交
202 203 204

		}

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

M
Mr.doob 已提交
207 208
	} catch ( error ) {

209
		console.error( 'THREE.WebGLRenderer: ' + error );
M
Mr.doob 已提交
210 211 212

	}

213 214
	var extensions = new THREE.WebGLExtensions( _gl );

215 216
	extensions.get( 'OES_texture_float' );
	extensions.get( 'OES_texture_float_linear' );
217 218
	extensions.get( 'OES_texture_half_float' );
	extensions.get( 'OES_texture_half_float_linear' );
219
	extensions.get( 'OES_standard_derivatives' );
B
Ben Adams 已提交
220
	extensions.get( 'ANGLE_instanced_arrays' );
221

222 223
	if ( extensions.get( 'OES_element_index_uint' ) ) {

224
		THREE.BufferGeometry.MaxIndex = 4294967296;
225 226 227

	}

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

230 231 232
	var state = new THREE.WebGLState( _gl, extensions, paramThreeToGL );
	var properties = new THREE.WebGLProperties();
	var objects = new THREE.WebGLObjects( _gl, properties, this.info );
G
gero3 已提交
233
	var programCache = new THREE.WebGLPrograms( this, capabilities );
M
Mr.doob 已提交
234
	var lightCache = new THREE.WebGLLights();
235

236 237
	this.info.programs = programCache.programs;

238 239
	var bufferRenderer = new THREE.WebGLBufferRenderer( _gl, extensions, _infoRender );
	var indexedBufferRenderer = new THREE.WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
240

M
Mr.doob 已提交
241 242
	//

243 244
	function getTargetPixelRatio() {

245
		return _currentRenderTarget === null ? _pixelRatio : 1;
246 247 248

	}

249
	function glClearColor( r, g, b, a ) {
250 251 252

		if ( _premultipliedAlpha === true ) {

253
			r *= a; g *= a; b *= a;
254 255 256

		}

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

259
	}
260

261
	function setDefaultGLState() {
M
Mr.doob 已提交
262

M
Mr.doob 已提交
263
		state.init();
M
Mr.doob 已提交
264

265 266
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
M
Mr.doob 已提交
267

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

270
	}
271

272
	function resetGLState() {
273 274 275 276

		_currentProgram = null;
		_currentCamera = null;

277
		_currentGeometryProgram = '';
278 279
		_currentMaterialId = - 1;

M
Mr.doob 已提交
280 281
		state.reset();

282
	}
M
Mr.doob 已提交
283 284 285 286

	setDefaultGLState();

	this.context = _gl;
M
Mr.doob 已提交
287
	this.capabilities = capabilities;
288
	this.extensions = extensions;
289
	this.properties = properties;
M
Mr.doob 已提交
290
	this.state = state;
M
Mr.doob 已提交
291

M
Mr.doob 已提交
292 293
	// shadow map

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

296
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
297

M
Mr.doob 已提交
298

M
Mr.doob 已提交
299 300 301 302 303
	// Plugins

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

M
Mr.doob 已提交
304 305 306 307 308 309 310 311
	// API

	this.getContext = function () {

		return _gl;

	};

312 313 314 315 316 317
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

318 319 320 321 322 323
	this.forceContextLoss = function () {

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

	};

324
	this.getMaxAnisotropy = ( function () {
M
Mr.doob 已提交
325

326
		var value;
M
Mr.doob 已提交
327

328
		return function getMaxAnisotropy() {
329

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

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

M
Mr.doob 已提交
334
			if ( extension !== null ) {
335

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

M
Mr.doob 已提交
338 339 340 341 342
			} else {

				value = 0;

			}
343 344 345

			return value;

M
Mr.doob 已提交
346
		};
347 348

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

	this.getPrecision = function () {

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

	};

356 357
	this.getPixelRatio = function () {

358
		return _pixelRatio;
359 360 361 362 363

	};

	this.setPixelRatio = function ( value ) {

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

		_pixelRatio = value;

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

	};

372 373 374
	this.getSize = function () {

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

	};

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

383 384 385
		_width = width;
		_height = height;

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

389
		if ( updateStyle !== false ) {
390

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

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

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

	};

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

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

	};

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

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

	};

412 413
	this.setScissorTest = function ( boolean ) {

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

	};

	// Clearing

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

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

	};

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

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

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

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

	};

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

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

	};

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

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

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

	};

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

	};

	this.clearColor = function () {

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

	};

	this.clearDepth = function () {

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

	};

	this.clearStencil = function () {

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

	};

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

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

	};

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

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

D
dubejf 已提交
491 492 493 494 495 496
	this.dispose = function() {

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

	};

M
Mr.doob 已提交
497
	// Events
M
Mr.doob 已提交
498

D
dubejf 已提交
499 500 501 502 503 504 505 506 507
	function onContextLost( event ) {

		event.preventDefault();

		resetGLState();
		setDefaultGLState();

		properties.clear();

M
Mr.doob 已提交
508
	}
D
dubejf 已提交
509

510
	function onTextureDispose( event ) {
M
Mr.doob 已提交
511 512 513 514 515 516 517

		var texture = event.target;

		texture.removeEventListener( 'dispose', onTextureDispose );

		deallocateTexture( texture );

518
		_infoMemory.textures --;
M
Mr.doob 已提交
519 520


521
	}
M
Mr.doob 已提交
522

523
	function onRenderTargetDispose( event ) {
M
Mr.doob 已提交
524 525 526 527 528 529 530

		var renderTarget = event.target;

		renderTarget.removeEventListener( 'dispose', onRenderTargetDispose );

		deallocateRenderTarget( renderTarget );

531
		_infoMemory.textures --;
M
Mr.doob 已提交
532

533
	}
M
Mr.doob 已提交
534

535
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
536 537 538 539 540 541 542

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

543
	}
M
Mr.doob 已提交
544 545 546

	// Buffer deallocation

547
	function deallocateTexture( texture ) {
M
Mr.doob 已提交
548

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

551
		if ( texture.image && textureProperties.__image__webglTextureCube ) {
M
Mr.doob 已提交
552 553 554

			// cube texture

555
			_gl.deleteTexture( textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
556

557 558 559 560
		} else {

			// 2D texture

561
			if ( textureProperties.__webglInit === undefined ) return;
562

563
			_gl.deleteTexture( textureProperties.__webglTexture );
564

M
Mr.doob 已提交
565 566
		}

567
		// remove all webgl properties
568
		properties.delete( texture );
569

570
	}
M
Mr.doob 已提交
571

572
	function deallocateRenderTarget( renderTarget ) {
M
Mr.doob 已提交
573

574
		var renderTargetProperties = properties.get( renderTarget );
M
Mr.doob 已提交
575
		var textureProperties = properties.get( renderTarget.texture );
M
Mr.doob 已提交
576

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

M
Mr.doob 已提交
579
		_gl.deleteTexture( textureProperties.__webglTexture );
M
Mr.doob 已提交
580

M
Mr.doob 已提交
581 582 583 584
		if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {

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

585
				_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );
586
				_gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );
M
Mr.doob 已提交
587 588 589 590 591

			}

		} else {

592
			_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );
593
			_gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );
M
Mr.doob 已提交
594 595 596

		}

M
Mr.doob 已提交
597
		properties.delete( renderTarget.texture );
D
Daosheng Mu 已提交
598
		properties.delete( renderTarget );
M
Mr.doob 已提交
599

600
	}
M
Mr.doob 已提交
601

602
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
603

604 605 606 607
		releaseMaterialProgramReference( material );

		properties.delete( material );

608
	}
609 610


611
	function releaseMaterialProgramReference( material ) {
612

613
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
614 615 616

		material.program = undefined;

617
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
618

619
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
620

M
Mr.doob 已提交
621 622
		}

623
	}
M
Mr.doob 已提交
624 625 626 627 628

	// Buffer rendering

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

629
		state.initAttributes();
630

631
		var buffers = properties.get( object );
632

633 634 635 636
		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 已提交
637

638
		var attributes = program.getAttributes();
639

M
Mr.doob 已提交
640 641
		if ( object.hasPositions ) {

642
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
M
Mr.doob 已提交
643
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
644

645 646
			state.enableAttribute( attributes.position );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
647 648 649 650 651

		}

		if ( object.hasNormals ) {

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

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

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

658
					var array = object.normalArray;
M
Mr.doob 已提交
659

660 661 662
					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 已提交
663

664 665 666
					array[ i + 0 ] = nx;
					array[ i + 1 ] = ny;
					array[ i + 2 ] = nz;
M
Mr.doob 已提交
667

668 669 670
					array[ i + 3 ] = nx;
					array[ i + 4 ] = ny;
					array[ i + 5 ] = nz;
M
Mr.doob 已提交
671

672 673 674
					array[ i + 6 ] = nx;
					array[ i + 7 ] = ny;
					array[ i + 8 ] = nz;
M
Mr.doob 已提交
675 676 677 678 679 680

				}

			}

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

682
			state.enableAttribute( attributes.normal );
683

684
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
685 686 687 688 689

		}

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

690
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
M
Mr.doob 已提交
691
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
692

693
			state.enableAttribute( attributes.uv );
694

695
			_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
696 697 698 699 700

		}

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

701
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
M
Mr.doob 已提交
702
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
703

704
			state.enableAttribute( attributes.color );
705

706
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
707 708 709

		}

710
		state.disableUnusedAttributes();
711

M
Mr.doob 已提交
712 713 714 715 716 717
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

718
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
719

M
Mr.doob 已提交
720 721
		setMaterial( material );

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

M
Mr.doob 已提交
724 725
		var updateBuffers = false;
		var geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;
M
Mr.doob 已提交
726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748

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

			}

749
			activeInfluences.sort( absNumericalSort );
M
Mr.doob 已提交
750 751 752 753 754 755 756

			if ( activeInfluences.length > 8 ) {

				activeInfluences.length = 8;

			}

757 758
			var morphAttributes = geometry.morphAttributes;

M
Mr.doob 已提交
759 760 761 762 763 764 765
			for ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {

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

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

766
					var index = influence[ 1 ];
M
Mr.doob 已提交
767

768 769
					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 已提交
770 771 772

				} else {

773 774
					if ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );
					if ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );
M
Mr.doob 已提交
775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791

				}

			}

			var uniforms = program.getUniforms();

			if ( uniforms.morphTargetInfluences !== null ) {

				_gl.uniform1fv( uniforms.morphTargetInfluences, morphInfluences );

			}

			updateBuffers = true;

		}

M
Mr.doob 已提交
792 793
		//

794
		var index = geometry.index;
795 796
		var position = geometry.attributes.position;

797 798
		if ( material.wireframe === true ) {

799
			index = objects.getWireframeAttribute( geometry );
800 801 802

		}

803 804
		var renderer;

805
		if ( index !== null ) {
806

807 808
			renderer = indexedBufferRenderer;
			renderer.setIndex( index );
809

810
		} else {
811

812
			renderer = bufferRenderer;
813

814
		}
M
Mr.doob 已提交
815

816
		if ( updateBuffers ) {
M
Mr.doob 已提交
817

818
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
819

820
			if ( index !== null ) {
821

822
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );
823 824 825

			}

826
		}
827

M
Mr.doob 已提交
828
		//
829

M
Mr.doob 已提交
830 831
		var dataStart = 0;
		var dataCount = Infinity;
832

M
Mr.doob 已提交
833
		if ( index !== null ) {
834

M
Mr.doob 已提交
835
			dataCount = index.count;
836

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

M
Mr.doob 已提交
839
			dataCount = position.count;
840

M
Mr.doob 已提交
841
		}
842

M
Mr.doob 已提交
843 844
		var rangeStart = geometry.drawRange.start;
		var rangeCount = geometry.drawRange.count;
845

M
Mr.doob 已提交
846 847
		var groupStart = group !== null ? group.start : 0;
		var groupCount = group !== null ? group.count : Infinity;
848

M
Mr.doob 已提交
849 850 851 852 853 854
		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 );

		//
855

856
		if ( object instanceof THREE.Mesh ) {
857

858
			if ( material.wireframe === true ) {
859

860
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
861
				renderer.setMode( _gl.LINES );
862

863
			} else {
M
Mr.doob 已提交
864 865

				switch ( object.drawMode ) {
866

B
Ben Adams 已提交
867 868 869 870 871 872 873 874 875 876 877 878 879
					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;

				}
880

881
			}
882

883

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

886
			var lineWidth = material.linewidth;
887

888
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
889

890
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
891

892
			if ( object instanceof THREE.LineSegments ) {
893

894
				renderer.setMode( _gl.LINES );
895

896
			} else {
897

898
				renderer.setMode( _gl.LINE_STRIP );
899 900

			}
M
Mr.doob 已提交
901

902
		} else if ( object instanceof THREE.Points ) {
903 904

			renderer.setMode( _gl.POINTS );
905 906

		}
907

908 909 910 911 912 913
		if ( geometry instanceof THREE.InstancedBufferGeometry && geometry.maxInstancedCount > 0 ) {

			renderer.renderInstances( geometry, drawStart, drawCount );

		} else {

M
Mr.doob 已提交
914
			renderer.render( drawStart, drawCount );
915

M
Mr.doob 已提交
916 917 918 919
		}

	};

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

M
Mr.doob 已提交
922
		var extension;
B
Ben Adams 已提交
923

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

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

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

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

M
Mr.doob 已提交
933 934 935
			}

		}
B
Ben Adams 已提交
936

937 938
		if ( startIndex === undefined ) startIndex = 0;

939 940
		state.initAttributes();

941
		var geometryAttributes = geometry.attributes;
942

943
		var programAttributes = program.getAttributes();
944

945
		var materialDefaultAttributeValues = material.defaultAttributeValues;
946

947
		for ( var name in programAttributes ) {
948

949
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
950

M
Mr.doob 已提交
951
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
952

953
				var geometryAttribute = geometryAttributes[ name ];
954

M
Mr.doob 已提交
955
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
956

957
					var size = geometryAttribute.itemSize;
G
gero3 已提交
958
					var buffer = objects.getAttributeBuffer( geometryAttribute );
959

B
Ben Adams 已提交
960
					if ( geometryAttribute instanceof THREE.InterleavedBufferAttribute ) {
961

M
Mr.doob 已提交
962 963 964 965 966
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

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

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

M
Mr.doob 已提交
970
							if ( geometry.maxInstancedCount === undefined ) {
971

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

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

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

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

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

M
Mr.doob 已提交
982 983
						_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 已提交
984

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

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

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

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

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

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

M
Mr.doob 已提交
997 998 999 1000
						} else {

							state.enableAttribute( programAttribute );

M
Mr.doob 已提交
1001
						}
B
Ben Adams 已提交
1002

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

B
Ben Adams 已提交
1006
					}
M
Mr.doob 已提交
1007

1008 1009
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
1010
					var value = materialDefaultAttributeValues[ name ];
1011

1012
					if ( value !== undefined ) {
M
Mr.doob 已提交
1013

1014
						switch ( value.length ) {
M
Mr.doob 已提交
1015

1016 1017 1018
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
1019

1020 1021 1022
							case 3:
								_gl.vertexAttrib3fv( programAttribute, value );
								break;
M
Mr.doob 已提交
1023

1024 1025 1026
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
1027

1028 1029
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
1030 1031

						}
M
Mr.doob 已提交
1032 1033 1034 1035 1036 1037 1038 1039

					}

				}

			}

		}
1040

1041
		state.disableUnusedAttributes();
1042

M
Mr.doob 已提交
1043 1044
	}

M
Mr.doob 已提交
1045 1046
	// Sorting

1047
	function absNumericalSort( a, b ) {
1048

1049
		return Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );
1050 1051 1052

	}

M
Mr.doob 已提交
1053 1054
	function painterSortStable ( a, b ) {

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

U
unconed 已提交
1057
			return a.object.renderOrder - b.object.renderOrder;
1058

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

M
Mr.doob 已提交
1061
			return a.material.id - b.material.id;
1062 1063

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

M
Mr.doob 已提交
1065
			return a.z - b.z;
M
Mr.doob 已提交
1066 1067 1068

		} else {

1069
			return a.id - b.id;
M
Mr.doob 已提交
1070 1071 1072

		}

1073
	}
M
Mr.doob 已提交
1074

1075 1076
	function reversePainterSortStable ( a, b ) {

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

U
unconed 已提交
1079
			return a.object.renderOrder - b.object.renderOrder;
1080 1081

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

M
Mr.doob 已提交
1083
			return b.z - a.z;
1084 1085 1086 1087 1088 1089 1090

		} else {

			return a.id - b.id;

		}

1091
	}
1092

M
Mr.doob 已提交
1093 1094 1095 1096 1097 1098
	// Rendering

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

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

1099
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1100 1101 1102 1103
			return;

		}

M
Mr.doob 已提交
1104
		var fog = scene.fog;
M
Mr.doob 已提交
1105 1106 1107

		// reset caching for this frame

1108
		_currentGeometryProgram = '';
1109
		_currentMaterialId = - 1;
1110
		_currentCamera = null;
M
Mr.doob 已提交
1111 1112 1113

		// update scene graph

1114
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1115 1116 1117

		// update camera matrices and frustum

1118
		if ( camera.parent === null ) camera.updateMatrixWorld();
M
Mr.doob 已提交
1119 1120 1121 1122 1123 1124

		camera.matrixWorldInverse.getInverse( camera.matrixWorld );

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

M
Mr.doob 已提交
1125
		lights.length = 0;
1126

M
Mr.doob 已提交
1127 1128
		opaqueObjectsLastIndex = - 1;
		transparentObjectsLastIndex = - 1;
1129

M
Mr.doob 已提交
1130 1131 1132
		sprites.length = 0;
		lensFlares.length = 0;

1133
		projectObject( scene, camera );
M
Mr.doob 已提交
1134

1135 1136 1137
		opaqueObjects.length = opaqueObjectsLastIndex + 1;
		transparentObjects.length = transparentObjectsLastIndex + 1;

M
Mr.doob 已提交
1138
		if ( _this.sortObjects === true ) {
1139 1140 1141

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

1143 1144
		}

1145 1146
		setupLights( lights, camera );

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

M
Mr.doob 已提交
1149
		shadowMap.render( scene, camera );
M
Mr.doob 已提交
1150 1151 1152

		//

1153 1154 1155 1156
		_infoRender.calls = 0;
		_infoRender.vertices = 0;
		_infoRender.faces = 0;
		_infoRender.points = 0;
M
Mr.doob 已提交
1157

1158 1159 1160 1161 1162 1163
		if ( renderTarget === undefined ) {

			renderTarget = null;

		}

M
Mr.doob 已提交
1164 1165 1166 1167 1168 1169 1170 1171
		this.setRenderTarget( renderTarget );

		if ( this.autoClear || forceClear ) {

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

		}

1172
		//
M
Mr.doob 已提交
1173 1174 1175

		if ( scene.overrideMaterial ) {

1176
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1177

1178 1179
			renderObjects( opaqueObjects, camera, fog, overrideMaterial );
			renderObjects( transparentObjects, camera, fog, overrideMaterial );
1180

M
Mr.doob 已提交
1181 1182 1183 1184
		} else {

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

M
Mr.doob 已提交
1185
			state.setBlending( THREE.NoBlending );
1186
			renderObjects( opaqueObjects, camera, fog );
M
Mr.doob 已提交
1187 1188 1189

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

1190
			renderObjects( transparentObjects, camera, fog );
M
Mr.doob 已提交
1191 1192 1193 1194 1195

		}

		// custom render plugins (post pass)

M
Mr.doob 已提交
1196
		spritePlugin.render( scene, camera );
1197
		lensFlarePlugin.render( scene, camera, _currentViewport );
M
Mr.doob 已提交
1198 1199 1200

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

M
Mr.doob 已提交
1201 1202 1203
		if ( renderTarget ) {

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

M
Mr.doob 已提交
1205 1206 1207 1208 1209
			if ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&
					texture.minFilter !== THREE.NearestFilter &&
					texture.minFilter !== THREE.LinearFilter ) {

				updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1210 1211

			}
M
Mr.doob 已提交
1212 1213 1214

		}

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

M
Mr.doob 已提交
1217 1218
		state.setDepthTest( true );
		state.setDepthWrite( true );
1219
		state.setColorWrite( true );
M
Mr.doob 已提交
1220 1221 1222 1223

		// _gl.finish();

	};
M
Mr.doob 已提交
1224

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

1227
		var array, index;
M
Mr.doob 已提交
1228

1229
		// allocate the next position in the appropriate array
M
Mr.doob 已提交
1230 1231 1232

		if ( material.transparent ) {

1233 1234
			array = transparentObjects;
			index = ++ transparentObjectsLastIndex;
M
Mr.doob 已提交
1235 1236 1237

		} else {

1238 1239 1240 1241 1242
			array = opaqueObjects;
			index = ++ opaqueObjectsLastIndex;

		}

1243 1244
		// recycle existing render item or grow the array

1245 1246 1247 1248 1249 1250 1251 1252 1253 1254
		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 已提交
1255 1256 1257

		} else {

1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268
			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 已提交
1269 1270 1271 1272 1273

		}

	}

1274
	function projectObject( object, camera ) {
M
Mr.doob 已提交
1275

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

1278
		if ( object.layers.test( camera.layers ) ) {
M
Mr.doob 已提交
1279

1280
			if ( object instanceof THREE.Light ) {
M
Mr.doob 已提交
1281

1282
				lights.push( object );
M
Mr.doob 已提交
1283

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

1286 1287 1288 1289 1290
				if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) {

					sprites.push( object );

				}
M
Mr.doob 已提交
1291

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

1294
				lensFlares.push( object );
M
Mr.doob 已提交
1295

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

1298
				if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1299

1300 1301
					_vector3.setFromMatrixPosition( object.matrixWorld );
					_vector3.applyProjection( _projScreenMatrix );
M
Mr.doob 已提交
1302

1303
				}
1304

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

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

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

1311
					object.skeleton.update();
1312

1313
				}
1314

1315
				if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) {
1316

1317
					var material = object.material;
1318

1319
					if ( material.visible === true ) {
M
Mr.doob 已提交
1320

1321
						if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1322

1323 1324 1325 1326
							_vector3.setFromMatrixPosition( object.matrixWorld );
							_vector3.applyProjection( _projScreenMatrix );

						}
M
Mr.doob 已提交
1327

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

S
SUNAG 已提交
1330
						if ( material instanceof THREE.MultiMaterial ) {
1331

1332 1333
							var groups = geometry.groups;
							var materials = material.materials;
1334

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

1337 1338
								var group = groups[ i ];
								var groupMaterial = materials[ group.materialIndex ];
1339

1340
								if ( groupMaterial.visible === true ) {
1341

1342 1343 1344
									pushRenderItem( object, geometry, groupMaterial, _vector3.z, group );

								}
M
Mr.doob 已提交
1345

M
Mr.doob 已提交
1346
							}
M
Mr.doob 已提交
1347

1348
						} else {
M
Mr.doob 已提交
1349

1350
							pushRenderItem( object, geometry, material, _vector3.z, null );
1351

1352
						}
O
OpenShift guest 已提交
1353

1354
					}
M
Mr.doob 已提交
1355

1356
				}
M
Mr.doob 已提交
1357

1358
			}
M
Mr.doob 已提交
1359

M
Mr.doob 已提交
1360
		}
M
Mr.doob 已提交
1361

M
Mr.doob 已提交
1362
		var children = object.children;
M
Mr.doob 已提交
1363

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

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

1368
		}
1369

1370
	}
M
Mr.doob 已提交
1371

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

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

1376
			var renderItem = renderList[ i ];
M
Mr.doob 已提交
1377

1378
			var object = renderItem.object;
M
Mr.doob 已提交
1379 1380 1381
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
M
Mr.doob 已提交
1382

1383 1384
			object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
			object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
M
Mr.doob 已提交
1385

M
Mr.doob 已提交
1386
			if ( object instanceof THREE.ImmediateRenderObject ) {
M
Mr.doob 已提交
1387

M
Mr.doob 已提交
1388
				setMaterial( material );
M
Mr.doob 已提交
1389

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

M
Mr.doob 已提交
1392
				_currentGeometryProgram = '';
M
Mr.doob 已提交
1393

M
Mr.doob 已提交
1394
				object.render( function ( object ) {
M
Mr.doob 已提交
1395

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

M
Mr.doob 已提交
1398
				} );
1399

M
Mr.doob 已提交
1400
			} else {
M
Mr.doob 已提交
1401

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

M
Mr.doob 已提交
1404
			}
M
Mr.doob 已提交
1405

1406
		}
M
Mr.doob 已提交
1407

1408
	}
G
gero3 已提交
1409

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

1412
		var materialProperties = properties.get( material );
G
gero3 已提交
1413

1414
		var parameters = programCache.getParameters( material, _lights, fog, object );
G
gero3 已提交
1415
		var code = programCache.getProgramCode( material, parameters );
G
gero3 已提交
1416

1417
		var program = materialProperties.program;
T
tschw 已提交
1418
		var programChange = true;
1419

1420
		if ( program === undefined ) {
B
Ben Adams 已提交
1421

M
Mr.doob 已提交
1422 1423
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1424

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

M
Mr.doob 已提交
1427
			// changed glsl or parameters
1428
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1429

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

T
tschw 已提交
1432
			// same glsl and uniform list
T
tschw 已提交
1433 1434
			return;

T
tschw 已提交
1435
		} else {
B
Ben Adams 已提交
1436

T
tschw 已提交
1437 1438
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1439 1440 1441

		}

1442
		if ( programChange ) {
B
Ben Adams 已提交
1443

1444
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1445

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

1448 1449 1450 1451 1452 1453
				materialProperties.__webglShader = {
					name: material.type,
					uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
					vertexShader: shader.vertexShader,
					fragmentShader: shader.fragmentShader
				};
B
Ben Adams 已提交
1454

1455
			} else {
B
Ben Adams 已提交
1456

1457 1458 1459 1460 1461 1462
				materialProperties.__webglShader = {
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
					fragmentShader: material.fragmentShader
				};
G
gero3 已提交
1463

1464
			}
G
gero3 已提交
1465

1466
			material.__webglShader = materialProperties.__webglShader;
G
gero3 已提交
1467

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

1470 1471
			materialProperties.program = program;
			material.program = program;
1472 1473 1474

		}

1475
		var attributes = program.getAttributes();
M
Mr.doob 已提交
1476 1477 1478 1479 1480

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

M
Mr.doob 已提交
1483
				if ( attributes[ 'morphTarget' + i ] >= 0 ) {
M
Mr.doob 已提交
1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

M
Mr.doob 已提交
1499
				if ( attributes[ 'morphNormal' + i ] >= 0 ) {
M
Mr.doob 已提交
1500 1501 1502 1503 1504 1505 1506 1507 1508

					material.numSupportedMorphNormals ++;

				}

			}

		}

1509
		materialProperties.uniformsList = [];
M
Mr.doob 已提交
1510

1511 1512
		var uniforms = materialProperties.__webglShader.uniforms,
			uniformLocations = materialProperties.program.getUniforms();
M
Mr.doob 已提交
1513

1514
		for ( var u in uniforms ) {
M
Mr.doob 已提交
1515

1516
			var location = uniformLocations[ u ];
1517 1518

			if ( location ) {
G
gero3 已提交
1519

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

1522
			}
M
Mr.doob 已提交
1523 1524 1525

		}

1526 1527
		if ( material instanceof THREE.MeshPhongMaterial ||
				material instanceof THREE.MeshLambertMaterial ||
1528
				material instanceof THREE.MeshStandardMaterial ||
1529 1530
				material.lights ) {

1531 1532
			// store the light setup it was created for

1533 1534
			materialProperties.lightsHash = _lights.hash;

1535 1536 1537 1538 1539
			// 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 已提交
1540
			uniforms.pointLights.value = _lights.point;
1541 1542
			uniforms.hemisphereLights.value = _lights.hemi;

1543 1544 1545 1546 1547 1548
			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;
1549

1550 1551
		}

A
arose 已提交
1552 1553 1554 1555 1556 1557 1558 1559
		// detect dynamic uniforms

		materialProperties.hasDynamicUniforms = false;

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

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

1560
			if ( uniform.dynamic === true ) {
A
arose 已提交
1561 1562 1563 1564 1565 1566 1567 1568

				materialProperties.hasDynamicUniforms = true;
				break;

			}

		}

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

1571 1572
	function setMaterial( material ) {

M
Mr.doob 已提交
1573 1574
		setMaterialFaces( material );

1575 1576
		if ( material.transparent === true ) {

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

1579 1580 1581 1582
		} else {

			state.setBlending( THREE.NoBlending );

1583 1584
		}

B
Ben Adams 已提交
1585
		state.setDepthFunc( material.depthFunc );
M
Mr.doob 已提交
1586 1587
		state.setDepthTest( material.depthTest );
		state.setDepthWrite( material.depthWrite );
1588
		state.setColorWrite( material.colorWrite );
M
Mr.doob 已提交
1589
		state.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
1590 1591 1592

	}

M
Mr.doob 已提交
1593 1594
	function setMaterialFaces( material ) {

1595
		material.side !== THREE.DoubleSide ? state.enable( _gl.CULL_FACE ) : state.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
1596 1597 1598 1599
		state.setFlipSided( material.side === THREE.BackSide );

	}

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

		_usedTextureUnits = 0;

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

1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619
		if ( materialProperties.program === undefined ) {

			material.needsUpdate = true;

		}

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

			material.needsUpdate = true;

		}

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

1621
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1622 1623 1624 1625
			material.needsUpdate = false;

		}

1626
		var refreshProgram = false;
M
Mr.doob 已提交
1627
		var refreshMaterial = false;
1628
		var refreshLights = false;
M
Mr.doob 已提交
1629

1630
		var program = materialProperties.program,
1631
			p_uniforms = program.getUniforms(),
1632
			m_uniforms = materialProperties.__webglShader.uniforms;
M
Mr.doob 已提交
1633

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

1636 1637
			_gl.useProgram( program.program );
			_currentProgram = program.id;
M
Mr.doob 已提交
1638

1639
			refreshProgram = true;
M
Mr.doob 已提交
1640
			refreshMaterial = true;
1641
			refreshLights = true;
M
Mr.doob 已提交
1642 1643 1644 1645 1646 1647

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1648

M
Mr.doob 已提交
1649 1650 1651 1652
			refreshMaterial = true;

		}

1653
		if ( refreshProgram || camera !== _currentCamera ) {
M
Mr.doob 已提交
1654 1655 1656

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

G
gero3 已提交
1657
			if ( capabilities.logarithmicDepthBuffer ) {
1658

1659
				_gl.uniform1f( p_uniforms.logDepthBufFC, 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1660 1661 1662 1663

			}


1664 1665 1666 1667 1668 1669 1670 1671 1672
			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 已提交
1673
				refreshLights = true;		// remains set until update done
1674 1675

			}
M
Mr.doob 已提交
1676

1677 1678 1679 1680 1681
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
1682
				 material instanceof THREE.MeshStandardMaterial ||
1683 1684
				 material.envMap ) {

1685
				if ( p_uniforms.cameraPosition !== undefined ) {
1686 1687 1688 1689 1690 1691 1692 1693 1694 1695

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

				}

			}

			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
1696
				 material instanceof THREE.MeshBasicMaterial ||
1697
				 material instanceof THREE.MeshStandardMaterial ||
1698 1699 1700
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {

1701
				if ( p_uniforms.viewMatrix !== undefined ) {
1702 1703

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

1705 1706 1707 1708
				}

			}

B
Ben Houston 已提交
1709 1710 1711 1712

			if ( p_uniforms.toneMappingExposure !== undefined ) {

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

B
Ben Houston 已提交
1714 1715 1716 1717 1718 1719 1720
			}

			if ( p_uniforms.toneMappingWhitePoint !== undefined ) {

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

			}
M
Mr.doob 已提交
1721 1722 1723 1724 1725 1726 1727 1728
		}

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

1729
			if ( object.bindMatrix && p_uniforms.bindMatrix !== undefined ) {
1730 1731 1732 1733 1734

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

			}

1735
			if ( object.bindMatrixInverse && p_uniforms.bindMatrixInverse !== undefined ) {
1736 1737 1738 1739 1740

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

			}

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

1743
				if ( p_uniforms.boneTexture !== undefined ) {
M
Mr.doob 已提交
1744 1745 1746 1747

					var textureUnit = getTextureUnit();

					_gl.uniform1i( p_uniforms.boneTexture, textureUnit );
1748
					_this.setTexture( object.skeleton.boneTexture, textureUnit );
M
Mr.doob 已提交
1749 1750 1751

				}

1752
				if ( p_uniforms.boneTextureWidth !== undefined ) {
1753

1754
					_gl.uniform1i( p_uniforms.boneTextureWidth, object.skeleton.boneTextureWidth );
1755 1756 1757

				}

1758
				if ( p_uniforms.boneTextureHeight !== undefined ) {
1759

1760
					_gl.uniform1i( p_uniforms.boneTextureHeight, object.skeleton.boneTextureHeight );
1761 1762 1763

				}

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

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

1768
					_gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.skeleton.boneMatrices );
M
Mr.doob 已提交
1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779

				}

			}

		}

		if ( refreshMaterial ) {

			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
1780
				 material instanceof THREE.MeshStandardMaterial ||
M
Mr.doob 已提交
1781 1782
				 material.lights ) {

1783
				// the current material requires lighting info
M
Mr.doob 已提交
1784

T
tschw 已提交
1785 1786 1787 1788 1789 1790
				// 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 已提交
1791

T
tschw 已提交
1792
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1793

T
tschw 已提交
1794
			}
G
gero3 已提交
1795

T
tschw 已提交
1796
			// refresh uniforms common to several materials
G
gero3 已提交
1797

T
tschw 已提交
1798
			if ( fog && material.fog ) {
G
gero3 已提交
1799

T
tschw 已提交
1800
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1801 1802 1803 1804 1805

			}

			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
W
WestLangley 已提交
1806
				 material instanceof THREE.MeshPhongMaterial ||
1807
				 material instanceof THREE.MeshStandardMaterial ) {
M
Mr.doob 已提交
1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823

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

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

M
Mr.doob 已提交
1826
				refreshUniformsPoints( m_uniforms, material );
M
Mr.doob 已提交
1827

1828 1829 1830 1831
			} else if ( material instanceof THREE.MeshLambertMaterial ) {

				refreshUniformsLambert( m_uniforms, material );

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

				refreshUniformsPhong( m_uniforms, material );

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

1838
				refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1839

M
Mr.doob 已提交
1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853
			} 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

1854
			loadUniformsGeneric( materialProperties.uniformsList );
M
Mr.doob 已提交
1855 1856 1857 1858 1859

		}

		loadUniformsMatrices( p_uniforms, object );

1860
		if ( p_uniforms.modelMatrix !== undefined ) {
M
Mr.doob 已提交
1861 1862

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

M
Mr.doob 已提交
1864 1865
		}

1866
		if ( materialProperties.hasDynamicUniforms === true ) {
A
arose 已提交
1867

1868
			updateDynamicUniforms( materialProperties.uniformsList, object, camera );
A
arose 已提交
1869 1870 1871

		}

M
Mr.doob 已提交
1872 1873
		return program;

M
Mr.doob 已提交
1874
	}
M
Mr.doob 已提交
1875

1876
	function updateDynamicUniforms ( uniforms, object, camera ) {
A
arose 已提交
1877 1878 1879 1880 1881 1882

		var dynamicUniforms = [];

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

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

1885
			if ( onUpdateCallback !== undefined ) {
A
arose 已提交
1886

1887
				onUpdateCallback.bind( uniform )( object, camera );
A
arose 已提交
1888 1889 1890 1891 1892 1893 1894 1895 1896 1897
				dynamicUniforms.push( uniforms[ j ] );

			}

		}

		loadUniformsGeneric( dynamicUniforms );

	}

M
Mr.doob 已提交
1898 1899 1900 1901 1902 1903
	// Uniforms (refresh uniforms objects)

	function refreshUniformsCommon ( uniforms, material ) {

		uniforms.opacity.value = material.opacity;

1904
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
1905

1906
		if ( material.emissive ) {
M
Mr.doob 已提交
1907

1908
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
1909 1910 1911

		}

1912 1913 1914
		uniforms.map.value = material.map;
		uniforms.specularMap.value = material.specularMap;
		uniforms.alphaMap.value = material.alphaMap;
M
Mr.doob 已提交
1915

1916
		if ( material.aoMap ) {
1917

1918 1919
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1920 1921 1922

		}

M
Mr.doob 已提交
1923
		// uv repeat and offset setting priorities
M
Mr.doob 已提交
1924 1925 1926 1927 1928
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
1929
		// 6. emissive map
M
Mr.doob 已提交
1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

1941 1942 1943 1944
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
1945 1946 1947 1948 1949 1950 1951 1952
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

1953 1954 1955 1956 1957 1958 1959 1960
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

1961 1962 1963 1964
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

1965 1966 1967 1968
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
1969 1970 1971 1972
		}

		if ( uvScaleMap !== undefined ) {

M
Mr.doob 已提交
1973 1974 1975 1976 1977 1978
			if ( uvScaleMap instanceof THREE.WebGLRenderTarget ) {

				uvScaleMap = uvScaleMap.texture;

			}

M
Mr.doob 已提交
1979 1980 1981 1982 1983 1984 1985 1986
			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;
1987
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : - 1;
M
Mr.doob 已提交
1988

1989
		uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
1990 1991
		uniforms.refractionRatio.value = material.refractionRatio;

M
Mr.doob 已提交
1992
	}
M
Mr.doob 已提交
1993 1994 1995 1996 1997 1998

	function refreshUniformsLine ( uniforms, material ) {

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

M
Mr.doob 已提交
1999
	}
M
Mr.doob 已提交
2000 2001 2002 2003 2004 2005 2006

	function refreshUniformsDash ( uniforms, material ) {

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

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

M
Mr.doob 已提交
2009
	function refreshUniformsPoints ( uniforms, material ) {
M
Mr.doob 已提交
2010

2011
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
2012
		uniforms.opacity.value = material.opacity;
2013 2014
		uniforms.size.value = material.size * _pixelRatio;
		uniforms.scale.value = _canvas.clientHeight / 2.0; // TODO: Cache this.
M
Mr.doob 已提交
2015 2016 2017

		uniforms.map.value = material.map;

2018 2019 2020 2021 2022 2023 2024 2025 2026
		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 已提交
2027
	}
M
Mr.doob 已提交
2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043

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

2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062
	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 已提交
2063 2064
	function refreshUniformsPhong ( uniforms, material ) {

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

2068 2069 2070 2071
		if ( material.lightMap ) {

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

2073
		}
2074

2075
		if ( material.emissiveMap ) {
2076

2077
			uniforms.emissiveMap.value = material.emissiveMap;
2078

2079
		}
M
Mr.doob 已提交
2080

2081 2082 2083 2084
		if ( material.bumpMap ) {

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

2086
		}
M
Mr.doob 已提交
2087

2088 2089 2090 2091 2092 2093
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2094

2095 2096 2097 2098 2099
		if ( material.displacementMap ) {

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

2101
		}
2102 2103 2104

	}

2105
	function refreshUniformsStandard ( uniforms, material ) {
W
WestLangley 已提交
2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165

		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;

		}

	}

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

M
Mr.doob 已提交
2168
	function markUniformsLightsNeedsUpdate ( uniforms, value ) {
2169

M
Mr.doob 已提交
2170
		uniforms.ambientLightColor.needsUpdate = value;
2171

B
Ben Houston 已提交
2172 2173 2174 2175
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
		uniforms.hemisphereLights.needsUpdate = value;
2176

M
Mr.doob 已提交
2177
	}
2178

M
Mr.doob 已提交
2179 2180 2181 2182
	// Uniforms (load to GPU)

	function loadUniformsMatrices ( uniforms, object ) {

2183
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object.modelViewMatrix.elements );
M
Mr.doob 已提交
2184 2185 2186

		if ( uniforms.normalMatrix ) {

2187
			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object.normalMatrix.elements );
M
Mr.doob 已提交
2188 2189 2190

		}

M
Mr.doob 已提交
2191
	}
M
Mr.doob 已提交
2192 2193 2194 2195 2196

	function getTextureUnit() {

		var textureUnit = _usedTextureUnits;

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

G
gero3 已提交
2199
			console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
M
Mr.doob 已提交
2200 2201 2202 2203 2204 2205 2206

		}

		_usedTextureUnits += 1;

		return textureUnit;

M
Mr.doob 已提交
2207
	}
M
Mr.doob 已提交
2208

2209
	function loadUniformsGeneric ( uniforms ) {
M
Mr.doob 已提交
2210

M
Mr.doob 已提交
2211
		var texture, textureUnit;
M
Mr.doob 已提交
2212

M
Mr.doob 已提交
2213 2214 2215
		for ( var j = 0, jl = uniforms.length; j < jl; j ++ ) {

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

2217 2218
			// needsUpdate property is not added to all uniforms.
			if ( uniform.needsUpdate === false ) continue;
2219

M
Mr.doob 已提交
2220 2221
			var type = uniform.type;
			var value = uniform.value;
2222
			var location = uniforms[ j ][ 1 ];
M
Mr.doob 已提交
2223

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

2226
				_gl.uniform1i( location, value );
2227

2228
			} else if ( type === '1f' ) {
2229

2230
				_gl.uniform1f( location, value );
2231

2232
			} else if ( type === '2f' ) {
2233

2234
				_gl.uniform2f( location, value[ 0 ], value[ 1 ] );
2235

2236
			} else if ( type === '3f' ) {
2237

2238
				_gl.uniform3f( location, value[ 0 ], value[ 1 ], value[ 2 ] );
2239

2240
			} else if ( type === '4f' ) {
2241

2242
				_gl.uniform4f( location, value[ 0 ], value[ 1 ], value[ 2 ], value[ 3 ] );
2243

2244
			} else if ( type === '1iv' ) {
2245

2246
				_gl.uniform1iv( location, value );
2247

2248
			} else if ( type === '3iv' ) {
2249

2250
				_gl.uniform3iv( location, value );
2251

2252
			} else if ( type === '1fv' ) {
2253

2254
				_gl.uniform1fv( location, value );
2255

2256
			} else if ( type === '2fv' ) {
M
Mr.doob 已提交
2257

2258
				_gl.uniform2fv( location, value );
M
Mr.doob 已提交
2259

2260
			} else if ( type === '3fv' ) {
M
Mr.doob 已提交
2261

2262
				_gl.uniform3fv( location, value );
M
Mr.doob 已提交
2263

2264
			} else if ( type === '4fv' ) {
M
Mr.doob 已提交
2265

2266
				_gl.uniform4fv( location, value );
M
Mr.doob 已提交
2267

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

2270
				_gl.uniformMatrix2fv( location, false, value );
M
Mr.doob 已提交
2271

2272
			} else if ( type === 'Matrix3fv' ) {
M
Mr.doob 已提交
2273

2274
				_gl.uniformMatrix3fv( location, false, value );
M
Mr.doob 已提交
2275

2276
			} else if ( type === 'Matrix4fv' ) {
M
Mr.doob 已提交
2277

2278
				_gl.uniformMatrix4fv( location, false, value );
M
Mr.doob 已提交
2279

2280
			//
M
Mr.doob 已提交
2281

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

2284 2285
				// single integer
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
2286

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

2289 2290
				// single float
				_gl.uniform1f( location, value );
M
Mr.doob 已提交
2291

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

2294 2295
				// single THREE.Vector2
				_gl.uniform2f( location, value.x, value.y );
2296

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

2299 2300
				// single THREE.Vector3
				_gl.uniform3f( location, value.x, value.y, value.z );
M
Mr.doob 已提交
2301

2302
			} else if ( type === 'v4' ) {
2303

2304 2305
				// single THREE.Vector4
				_gl.uniform4f( location, value.x, value.y, value.z, value.w );
2306

2307
			} else if ( type === 'c' ) {
2308

2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347
				// single THREE.Color
				_gl.uniform3f( location, value.r, value.g, value.b );

			/*
			} else if ( type === 's' ) {

				// TODO: Optimize this

				for ( var propertyName in uniform.properties ) {

					var property = uniform.properties[ propertyName ];
					var locationProperty =  location[ propertyName ];
					var valueProperty = value[ propertyName ];

					type = property.type;

					if ( type === 'i' ) {

						_gl.uniform1i( locationProperty, valueProperty );

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

						_gl.uniform1f( locationProperty, valueProperty );

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

						_gl.uniform2f( locationProperty, valueProperty.x, valueProperty.y );

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

						_gl.uniform3f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z );

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

						_gl.uniform4f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w );

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

						_gl.uniform3f( locationProperty, valueProperty.r, valueProperty.g, valueProperty.b );
2348 2349

					}
M
Mr.doob 已提交
2350

2351 2352
				}

2353

2354
			*/
M
Mr.doob 已提交
2355

2356
			} else if ( type === 'sa' ) {
M
Mr.doob 已提交
2357

2358
				// TODO: Optimize this
M
Mr.doob 已提交
2359

2360
				for ( var i = 0; i < value.length; i ++ ) {
M
Mr.doob 已提交
2361

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

2364 2365 2366
						var property = uniform.properties[ propertyName ];
						var locationProperty =  location[ i ][ propertyName ];
						var valueProperty = value[ i ][ propertyName ];
M
Mr.doob 已提交
2367

2368
						type = property.type;
M
Mr.doob 已提交
2369

2370
						if ( type === 'i' ) {
M
Mr.doob 已提交
2371

2372
							_gl.uniform1i( locationProperty, valueProperty );
M
Mr.doob 已提交
2373

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

2376
							_gl.uniform1f( locationProperty, valueProperty );
M
Mr.doob 已提交
2377

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

2380
							_gl.uniform2f( locationProperty, valueProperty.x, valueProperty.y );
M
Mr.doob 已提交
2381

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

2384
							_gl.uniform3f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z );
M
Mr.doob 已提交
2385

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

2388 2389 2390
							_gl.uniform4f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w );

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

2392
							_gl.uniform3f( locationProperty, valueProperty.r, valueProperty.g, valueProperty.b );
M
Mr.doob 已提交
2393

2394 2395 2396 2397 2398
						} else if ( type === 'm4' ) {

							_gl.uniformMatrix4fv( locationProperty, false, valueProperty.elements );

						}
M
Mr.doob 已提交
2399

2400
					}
M
Mr.doob 已提交
2401

2402
				}
M
Mr.doob 已提交
2403

2404
			} else if ( type === 'iv1' ) {
M
Mr.doob 已提交
2405

2406 2407
				// flat array of integers (JS or typed array)
				_gl.uniform1iv( location, value );
M
Mr.doob 已提交
2408

2409
			} else if ( type === 'iv' ) {
M
Mr.doob 已提交
2410

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

2414
			} else if ( type === 'fv1' ) {
M
Mr.doob 已提交
2415

2416 2417
				// flat array of floats (JS or typed array)
				_gl.uniform1fv( location, value );
M
Mr.doob 已提交
2418

2419
			} else if ( type === 'fv' ) {
R
Ryan Tsao 已提交
2420

2421 2422
				// flat array of floats with 3 x N size (JS or typed array)
				_gl.uniform3fv( location, value );
R
Ryan Tsao 已提交
2423

2424
			} else if ( type === 'v2v' ) {
R
Ryan Tsao 已提交
2425

2426
				// array of THREE.Vector2
R
Ryan Tsao 已提交
2427

2428
				if ( uniform._array === undefined ) {
R
Ryan Tsao 已提交
2429

2430
					uniform._array = new Float32Array( 2 * value.length );
R
Ryan Tsao 已提交
2431

2432
				}
R
Ryan Tsao 已提交
2433

2434
				for ( var i = 0, i2 = 0, il = value.length; i < il; i ++, i2 += 2 ) {
R
Ryan Tsao 已提交
2435

2436 2437
					uniform._array[ i2 + 0 ] = value[ i ].x;
					uniform._array[ i2 + 1 ] = value[ i ].y;
R
Ryan Tsao 已提交
2438

2439
				}
M
Mr.doob 已提交
2440

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

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

2445
				// array of THREE.Vector3
M
Mr.doob 已提交
2446

2447
				if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2448

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

2451
				}
2452

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

2455 2456 2457
					uniform._array[ i3 + 0 ] = value[ i ].x;
					uniform._array[ i3 + 1 ] = value[ i ].y;
					uniform._array[ i3 + 2 ] = value[ i ].z;
2458

2459
				}
M
Mr.doob 已提交
2460

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

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

2465
				// array of THREE.Vector4
M
Mr.doob 已提交
2466

2467
				if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2468

2469
					uniform._array = new Float32Array( 4 * value.length );
M
Mr.doob 已提交
2470

2471
				}
M
Mr.doob 已提交
2472

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

2475 2476 2477 2478
					uniform._array[ i4 + 0 ] = value[ i ].x;
					uniform._array[ i4 + 1 ] = value[ i ].y;
					uniform._array[ i4 + 2 ] = value[ i ].z;
					uniform._array[ i4 + 3 ] = value[ i ].w;
M
Mr.doob 已提交
2479

2480
				}
M
Mr.doob 已提交
2481

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

2484
			} else if ( type === 'm2' ) {
M
Mr.doob 已提交
2485

2486 2487
				// single THREE.Matrix2
				_gl.uniformMatrix2fv( location, false, value.elements );
M
Mr.doob 已提交
2488

2489
			} else if ( type === 'm3' ) {
M
Mr.doob 已提交
2490

2491 2492
				// single THREE.Matrix3
				_gl.uniformMatrix3fv( location, false, value.elements );
M
Mr.doob 已提交
2493

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

2496
				// array of THREE.Matrix3
M
Mr.doob 已提交
2497

2498
				if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2499

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

2502
				}
M
Mr.doob 已提交
2503

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

2506
					value[ i ].flattenToArrayOffset( uniform._array, i * 9 );
2507

2508
				}
2509

2510
				_gl.uniformMatrix3fv( location, false, uniform._array );
2511

2512
			} else if ( type === 'm4' ) {
2513

2514 2515
				// single THREE.Matrix4
				_gl.uniformMatrix4fv( location, false, value.elements );
M
Mr.doob 已提交
2516

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

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

2521
				if ( uniform._array === undefined ) {
2522

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

2525
				}
M
Mr.doob 已提交
2526

2527
				for ( var i = 0, il = value.length; i < il; i ++ ) {
G
gero3 已提交
2528

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

2531
				}
M
Mr.doob 已提交
2532

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

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

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

2539 2540
				texture = value;
				textureUnit = getTextureUnit();
2541

2542
				_gl.uniform1i( location, textureUnit );
2543

2544
				if ( ! texture ) continue;
2545

2546 2547
				if ( texture instanceof THREE.CubeTexture ||
					 ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
2548

2549
					// CompressedTexture can have Array in image :/
2550

2551
					setCubeTexture( texture, textureUnit );
2552

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

2555
					setCubeTextureDynamic( texture.texture, textureUnit );
2556

2557
				} else if ( texture instanceof THREE.WebGLRenderTarget ) {
2558

2559
					_this.setTexture( texture.texture, textureUnit );
2560

2561
				} else {
2562

2563
					_this.setTexture( texture, textureUnit );
2564

2565
				}
2566

2567
			} else if ( type === 'tv' ) {
2568

2569
				// array of THREE.Texture (2d or cube)
2570

2571
				if ( uniform._array === undefined ) {
2572

2573
					uniform._array = [];
2574

2575
				}
M
Mr.doob 已提交
2576

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

2579
					uniform._array[ i ] = getTextureUnit();
M
Mr.doob 已提交
2580

2581
				}
M
Mr.doob 已提交
2582

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

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

2587 2588
					texture = uniform.value[ i ];
					textureUnit = uniform._array[ i ];
M
Mr.doob 已提交
2589

2590
					if ( ! texture ) continue;
M
Mr.doob 已提交
2591

2592 2593
					if ( texture instanceof THREE.CubeTexture ||
						 ( texture.image instanceof Array && texture.image.length === 6 ) ) {
M
Mr.doob 已提交
2594

2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609
						// CompressedTexture can have Array in image :/

						setCubeTexture( texture, textureUnit );

					} else if ( texture instanceof THREE.WebGLRenderTarget ) {

						_this.setTexture( texture.texture, textureUnit );

					} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {

						setCubeTextureDynamic( texture.texture, textureUnit );

					} else {

						_this.setTexture( texture, textureUnit );
2610 2611 2612

					}

2613
				}
2614

2615
			} else {
2616

2617
				console.warn( 'THREE.WebGLRenderer: Unknown uniform type: ' + type );
2618

M
Mr.doob 已提交
2619 2620 2621 2622
			}

		}

M
Mr.doob 已提交
2623
	}
M
Mr.doob 已提交
2624

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

B
brason 已提交
2627
		var l, ll, light,
M
Mr.doob 已提交
2628
		r = 0, g = 0, b = 0,
B
Ben Houston 已提交
2629
		color,
B
brason 已提交
2630
		intensity,
M
Mr.doob 已提交
2631 2632
		distance,

2633
		viewMatrix = camera.matrixWorldInverse,
M
Mr.doob 已提交
2634

M
Mr.doob 已提交
2635
		directionalLength = 0,
M
Mr.doob 已提交
2636 2637
		pointLength = 0,
		spotLength = 0,
2638 2639 2640
		hemiLength = 0,

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

2642 2643
		_lights.shadowsPointLight = 0;

M
Mr.doob 已提交
2644 2645 2646 2647 2648 2649 2650 2651 2652 2653
		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 ) {

2654 2655 2656
				r += color.r * intensity;
				g += color.g * intensity;
				b += color.b * intensity;
M
Mr.doob 已提交
2657 2658 2659

			} else if ( light instanceof THREE.DirectionalLight ) {

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

2662
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
M
Mr.doob 已提交
2663
				uniforms.direction.setFromMatrixPosition( light.matrixWorld );
2664
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
M
Mr.doob 已提交
2665 2666 2667
				uniforms.direction.sub( _vector3 );
				uniforms.direction.transformDirection( viewMatrix );

2668
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2669

2670
				if ( light.castShadow ) {
M
Mr.doob 已提交
2671

2672 2673 2674
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;
2675

2676
					_lights.shadows[ shadowsLength ++ ] = light;
2677

2678 2679
				}

2680 2681
				_lights.directionalShadowMap[ directionalLength ] = light.shadow.map;
				_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
2682
				_lights.directional[ directionalLength ++ ] = uniforms;
M
Mr.doob 已提交
2683

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

M
Mr.doob 已提交
2686
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2687 2688 2689

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

M
Mr.doob 已提交
2691 2692 2693 2694 2695 2696 2697 2698
				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 );

2699 2700
				uniforms.coneCos = Math.cos( light.angle );
				uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
M
Mr.doob 已提交
2701
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
M
Mr.doob 已提交
2702

2703
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2704

2705 2706
				if ( light.castShadow ) {

2707 2708 2709
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;
2710

2711
					_lights.shadows[ shadowsLength ++ ] = light;
2712

2713 2714
				}

2715 2716
				_lights.spotShadowMap[ spotLength ] = light.shadow.map;
				_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;
M
Mr.doob 已提交
2717
				_lights.spot[ spotLength ++ ] = uniforms;
2718

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

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

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

M
Mr.doob 已提交
2726 2727
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
				uniforms.distance = light.distance;
M
Mr.doob 已提交
2728 2729
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;

2730
				uniforms.shadow = light.castShadow;
2731

M
Mr.doob 已提交
2732
				if ( light.castShadow ) {
2733

2734 2735 2736 2737 2738
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;

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

2740
				}
2741

2742
				_lights.pointShadowMap[ pointLength ] = light.shadow.map;
2743

2744 2745 2746
				if ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {

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

2748 2749
				}

2750 2751 2752 2753 2754
				// 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 已提交
2755
				_lights.point[ pointLength ++ ] = uniforms;
2756

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

M
Mr.doob 已提交
2759
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2760 2761 2762 2763

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

M
Mr.doob 已提交
2765 2766
				uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
				uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
M
Mr.doob 已提交
2767

M
Mr.doob 已提交
2768
				_lights.hemi[ hemiLength ++ ] = uniforms;
M
Mr.doob 已提交
2769 2770 2771 2772 2773

			}

		}

M
Mr.doob 已提交
2774 2775 2776
		_lights.ambient[ 0 ] = r;
		_lights.ambient[ 1 ] = g;
		_lights.ambient[ 2 ] = b;
M
Mr.doob 已提交
2777

M
Mr.doob 已提交
2778 2779
		_lights.directional.length = directionalLength;
		_lights.spot.length = spotLength;
2780
		_lights.point.length = pointLength;
M
Mr.doob 已提交
2781
		_lights.hemi.length = hemiLength;
2782

2783 2784
		_lights.shadows.length = shadowsLength;

2785
		_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + hemiLength + ',' + shadowsLength;
2786

M
Mr.doob 已提交
2787
	}
M
Mr.doob 已提交
2788 2789 2790 2791 2792 2793 2794

	// GL state setting

	this.setFaceCulling = function ( cullFace, frontFaceDirection ) {

		if ( cullFace === THREE.CullFaceNone ) {

2795
			state.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822

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

			}

2823
			state.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
2824 2825 2826 2827 2828 2829 2830

		}

	};

	// Textures

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

2833 2834
		var extension;

M
Mr.doob 已提交
2835
		if ( isPowerOfTwoImage ) {
M
Mr.doob 已提交
2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846

			_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 已提交
2847 2848 2849

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

M
Mr.doob 已提交
2850
				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 已提交
2851

2852
			}
M
Mr.doob 已提交
2853 2854 2855 2856

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

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

M
Mr.doob 已提交
2859
				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 已提交
2860

2861
			}
M
Mr.doob 已提交
2862

M
Mr.doob 已提交
2863 2864
		}

2865 2866
		extension = extensions.get( 'EXT_texture_filter_anisotropic' );

2867
		if ( extension ) {
M
Mr.doob 已提交
2868

2869 2870
			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 已提交
2871

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

2874
				_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _this.getMaxAnisotropy() ) );
2875
				properties.get( texture ).__currentAnisotropy = texture.anisotropy;
M
Mr.doob 已提交
2876 2877 2878 2879 2880

			}

		}

M
Mr.doob 已提交
2881
	}
M
Mr.doob 已提交
2882

2883
	function uploadTexture( textureProperties, texture, slot ) {
2884

2885
		if ( textureProperties.__webglInit === undefined ) {
2886

2887
			textureProperties.__webglInit = true;
2888 2889 2890

			texture.addEventListener( 'dispose', onTextureDispose );

2891
			textureProperties.__webglTexture = _gl.createTexture();
2892

2893
			_infoMemory.textures ++;
2894 2895

		}
M
Mr.doob 已提交
2896

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

H
Henri Astre 已提交
2900 2901 2902 2903
		_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 );

2904
		var image = clampToMaxSize( texture.image, capabilities.maxTextureSize );
2905

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

2908
			image = makePowerOfTwo( image );
M
Mr.doob 已提交
2909 2910 2911

		}

M
Mr.doob 已提交
2912
		var isPowerOfTwoImage = isPowerOfTwo( image ),
H
Henri Astre 已提交
2913 2914
		glFormat = paramThreeToGL( texture.format ),
		glType = paramThreeToGL( texture.type );
M
Mr.doob 已提交
2915

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

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

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

H
Henri Astre 已提交
2922 2923 2924
			// 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 已提交
2925

M
Mr.doob 已提交
2926
			if ( mipmaps.length > 0 && isPowerOfTwoImage ) {
H
Henri Astre 已提交
2927 2928

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

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

H
Henri Astre 已提交
2933
				}
M
Mr.doob 已提交
2934

H
Henri Astre 已提交
2935
				texture.generateMipmaps = false;
M
Mr.doob 已提交
2936

H
Henri Astre 已提交
2937
			} else {
M
Mr.doob 已提交
2938

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

H
Henri Astre 已提交
2941
			}
M
Mr.doob 已提交
2942

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

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

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

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

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

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

2955
					} else {
M
Mr.doob 已提交
2956

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

2959
					}
M
Mr.doob 已提交
2960

H
Henri Astre 已提交
2961
				} else {
M
Mr.doob 已提交
2962

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

M
Mr.doob 已提交
2965 2966
				}

H
Henri Astre 已提交
2967 2968
			}

G
gero3 已提交
2969 2970 2971
		} else {

			// regular Texture (image, video, canvas)
H
Henri Astre 已提交
2972 2973 2974 2975 2976

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

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

					mipmap = mipmaps[ i ];
2982
					state.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );
M
Mr.doob 已提交
2983 2984 2985

				}

H
Henri Astre 已提交
2986
				texture.generateMipmaps = false;
M
Mr.doob 已提交
2987

H
Henri Astre 已提交
2988
			} else {
M
Mr.doob 已提交
2989

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

H
Henri Astre 已提交
2992
			}
M
Mr.doob 已提交
2993

H
Henri Astre 已提交
2994
		}
M
Mr.doob 已提交
2995

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

2998
		textureProperties.__version = texture.version;
M
Mr.doob 已提交
2999

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

3002
	}
M
Mr.doob 已提交
3003

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

3006 3007 3008
		var textureProperties = properties.get( texture );

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

3010
			var image = texture.image;
M
Mr.doob 已提交
3011

3012 3013
			if ( image === undefined ) {

3014
				console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );
3015 3016 3017 3018
				return;

			}

3019
			if ( image.complete === false ) {
M
Mr.doob 已提交
3020

3021
				console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );
3022 3023 3024 3025
				return;

			}

3026
			uploadTexture( textureProperties, texture, slot );
3027

3028
			return;
M
Mr.doob 已提交
3029 3030 3031

		}

B
Ben Adams 已提交
3032
		state.activeTexture( _gl.TEXTURE0 + slot );
3033
		state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
3034

M
Mr.doob 已提交
3035 3036 3037 3038
	};

	function clampToMaxSize ( image, maxSize ) {

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

3041 3042
			// Warning: Scaling through the canvas will only work with images that use
			// premultiplied alpha.
M
Mr.doob 已提交
3043

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

3046 3047 3048
			var canvas = document.createElement( 'canvas' );
			canvas.width = Math.floor( image.width * scale );
			canvas.height = Math.floor( image.height * scale );
M
Mr.doob 已提交
3049

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

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

3055 3056 3057
			return canvas;

		}
M
Mr.doob 已提交
3058

3059
		return image;
M
Mr.doob 已提交
3060 3061 3062

	}

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

3101
		var textureProperties = properties.get( texture );
3102

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

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

3107
				if ( ! textureProperties.__image__webglTextureCube ) {
M
Mr.doob 已提交
3108

3109 3110
					texture.addEventListener( 'dispose', onTextureDispose );

3111
					textureProperties.__image__webglTextureCube = _gl.createTexture();
M
Mr.doob 已提交
3112

3113
					_infoMemory.textures ++;
M
Mr.doob 已提交
3114 3115 3116

				}

B
Ben Adams 已提交
3117
				state.activeTexture( _gl.TEXTURE0 + slot );
3118
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
3119 3120 3121

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

M
Mr.doob 已提交
3122 3123
				var isCompressed = texture instanceof THREE.CompressedTexture;
				var isDataTexture = texture.image[ 0 ] instanceof THREE.DataTexture;
M
Mr.doob 已提交
3124 3125 3126 3127 3128

				var cubeImage = [];

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

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

G
gero3 已提交
3131
						cubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );
M
Mr.doob 已提交
3132 3133 3134

					} else {

3135
						cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];
M
Mr.doob 已提交
3136 3137 3138 3139 3140 3141

					}

				}

				var image = cubeImage[ 0 ],
M
Mr.doob 已提交
3142
				isPowerOfTwoImage = isPowerOfTwo( image ),
M
Mr.doob 已提交
3143 3144 3145
				glFormat = paramThreeToGL( texture.format ),
				glType = paramThreeToGL( texture.type );

M
Mr.doob 已提交
3146
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );
M
Mr.doob 已提交
3147 3148 3149

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

3150
					if ( ! isCompressed ) {
M
Mr.doob 已提交
3151

M
Mr.doob 已提交
3152
						if ( isDataTexture ) {
3153

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

M
Mr.doob 已提交
3156
						} else {
3157

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

M
Mr.doob 已提交
3160 3161
						}

3162
					} else {
3163

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

3166
						for ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {
M
Mr.doob 已提交
3167 3168

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

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

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

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

3176
								} else {
M
Mr.doob 已提交
3177

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

3180
								}
M
Mr.doob 已提交
3181

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

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

3186
							}
M
Mr.doob 已提交
3187

3188
						}
M
Mr.doob 已提交
3189

M
Mr.doob 已提交
3190
					}
M
Mr.doob 已提交
3191

M
Mr.doob 已提交
3192 3193
				}

M
Mr.doob 已提交
3194
				if ( texture.generateMipmaps && isPowerOfTwoImage ) {
M
Mr.doob 已提交
3195 3196 3197 3198 3199

					_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

				}

3200
				textureProperties.__version = texture.version;
M
Mr.doob 已提交
3201

B
Ben Adams 已提交
3202
				if ( texture.onUpdate ) texture.onUpdate( texture );
M
Mr.doob 已提交
3203 3204 3205

			} else {

B
Ben Adams 已提交
3206
				state.activeTexture( _gl.TEXTURE0 + slot );
3207
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
3208 3209 3210 3211 3212

			}

		}

M
Mr.doob 已提交
3213
	}
M
Mr.doob 已提交
3214 3215 3216

	function setCubeTextureDynamic ( texture, slot ) {

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

M
Mr.doob 已提交
3220
	}
M
Mr.doob 已提交
3221 3222 3223

	// Render targets

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

3227 3228 3229
		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 已提交
3230
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
3231 3232
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
M
Mr.doob 已提交
3233

M
Mr.doob 已提交
3234
	}
M
Mr.doob 已提交
3235

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

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

3253
			// FIXME: We don't support !depth !stencil
M
Mr.doob 已提交
3254 3255 3256 3257
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );

		}

3258
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
M
Mr.doob 已提交
3259

M
Mr.doob 已提交
3260
	}
M
Mr.doob 已提交
3261

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

3265
		var renderTargetProperties = properties.get( renderTarget );
M
Mr.doob 已提交
3266 3267

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

3269
		if ( isCube ) {
M
Mr.doob 已提交
3270

3271
			renderTargetProperties.__webglDepthbuffer = [];
M
Mr.doob 已提交
3272

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

M
Marius Kintel 已提交
3275
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );
3276 3277
				renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();
				setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );
M
Mr.doob 已提交
3278 3279

			}
B
Ben Adams 已提交
3280

M
Mr.doob 已提交
3281
		} else {
M
Mr.doob 已提交
3282

M
Marius Kintel 已提交
3283
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );
3284 3285
			renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
			setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );
M
Mr.doob 已提交
3286

3287
		}
M
Mr.doob 已提交
3288

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

M
Mr.doob 已提交
3291
	}
M
Mr.doob 已提交
3292

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

3296 3297
		var renderTargetProperties = properties.get( renderTarget );
		var textureProperties = properties.get( renderTarget.texture );
M
Mr.doob 已提交
3298

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

3301
		textureProperties.__webglTexture = _gl.createTexture();
M
Mr.doob 已提交
3302

3303
		_infoMemory.textures ++;
M
Mr.doob 已提交
3304

3305 3306
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
		var isTargetPowerOfTwo = THREE.Math.isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height );
M
Mr.doob 已提交
3307

3308
		// Setup framebuffer
M
Mr.doob 已提交
3309

3310
		if ( isCube ) {
M
Mr.doob 已提交
3311

3312
			renderTargetProperties.__webglFramebuffer = [];
M
Mr.doob 已提交
3313

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

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

3318
			}
M
Mr.doob 已提交
3319

3320
		} else {
M
Mr.doob 已提交
3321

3322
			renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
M
Mr.doob 已提交
3323

3324
		}
M
Mr.doob 已提交
3325

3326
		// Setup color buffer
M
Mr.doob 已提交
3327

3328
		if ( isCube ) {
M
Mr.doob 已提交
3329

3330 3331
			state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
			setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );
M
Mr.doob 已提交
3332

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

3335
				setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
M
Mr.doob 已提交
3336 3337 3338

			}

3339 3340
			if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
			state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
M
Mr.doob 已提交
3341

3342
		} else {
M
Mr.doob 已提交
3343

3344 3345 3346
			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 已提交
3347

3348 3349
			if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
			state.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
3350

3351
		}
M
Mr.doob 已提交
3352

3353
		// Setup depth and stencil buffers
3354

3355
		if ( renderTarget.depthBuffer ) {
M
Mr.doob 已提交
3356

M
Marius Kintel 已提交
3357
			setupDepthRenderbuffer( renderTarget );
M
Mr.doob 已提交
3358

3359
		}
M
Mr.doob 已提交
3360

3361
	}
M
Mr.doob 已提交
3362

3363 3364 3365 3366 3367 3368
	this.getCurrentRenderTarget = function() {

		return _currentRenderTarget;

	}

3369
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
3370

3371 3372
		_currentRenderTarget = renderTarget;

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

M
Marius Kintel 已提交
3375
			setupRenderTarget( renderTarget );
M
Mr.doob 已提交
3376 3377 3378

		}

3379
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
3380
		var framebuffer;
M
Mr.doob 已提交
3381 3382 3383

		if ( renderTarget ) {

3384
			var renderTargetProperties = properties.get( renderTarget );
F
Fordy 已提交
3385

M
Mr.doob 已提交
3386 3387
			if ( isCube ) {

3388
				framebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
3389 3390 3391

			} else {

3392
				framebuffer = renderTargetProperties.__webglFramebuffer;
M
Mr.doob 已提交
3393 3394 3395

			}

3396 3397
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
3398

3399
			_currentViewport.copy( renderTarget.viewport );
M
Mr.doob 已提交
3400 3401 3402 3403 3404

		} else {

			framebuffer = null;

3405
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
3406
			_currentScissorTest = _scissorTest;
3407

3408
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
M
Mr.doob 已提交
3409 3410 3411

		}

M
Mr.doob 已提交
3412
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
3413 3414 3415 3416 3417 3418

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

		}

3419 3420
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
3421

3422
		state.viewport( _currentViewport );
3423

M
Mr.doob 已提交
3424 3425 3426 3427 3428 3429 3430
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, 0 );

		}

M
Mr.doob 已提交
3431 3432
	};

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

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

3437
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
3438
			return;
3439

G
gero3 已提交
3440
		}
3441

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

M
Mr.doob 已提交
3444
		if ( framebuffer ) {
3445

G
gero3 已提交
3446
			var restore = false;
3447

M
Mr.doob 已提交
3448
			if ( framebuffer !== _currentFramebuffer ) {
3449

M
Mr.doob 已提交
3450
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
3451

G
gero3 已提交
3452
				restore = true;
3453

G
gero3 已提交
3454
			}
3455

M
Mr.doob 已提交
3456
			try {
3457

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

M
Mr.doob 已提交
3460 3461
				if ( texture.format !== THREE.RGBAFormat
					&& paramThreeToGL( texture.format ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
3462

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

M
Mr.doob 已提交
3466
				}
3467

M
Mr.doob 已提交
3468 3469 3470 3471
				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' ) ) ) {
3472

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

M
Mr.doob 已提交
3476
				}
3477

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

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

M
Mr.doob 已提交
3482
				} else {
M
Mr.doob 已提交
3483

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

				}
M
Mr.doob 已提交
3487

M
Mr.doob 已提交
3488
			} finally {
M
Mr.doob 已提交
3489

M
Mr.doob 已提交
3490 3491 3492
				if ( restore ) {

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

M
Mr.doob 已提交
3494 3495 3496
				}

			}
M
Mr.doob 已提交
3497 3498 3499

		}

M
Mr.doob 已提交
3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510
	};

	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 已提交
3511
	}
M
Mr.doob 已提交
3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524

	// 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 已提交
3525
	}
M
Mr.doob 已提交
3526 3527 3528 3529 3530

	// Map three.js constants to WebGL constants

	function paramThreeToGL ( p ) {

3531 3532
		var extension;

M
Mr.doob 已提交
3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556
		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;

3557 3558 3559 3560 3561 3562 3563 3564
		extension = extensions.get( 'OES_texture_half_float' );

		if ( extension !== null ) {

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

		}

M
Mr.doob 已提交
3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587
		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;

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

3590 3591 3592 3593 3594 3595
		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 已提交
3596 3597 3598

		}

3599 3600 3601
		extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );

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

3603 3604 3605 3606
			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 已提交
3607 3608 3609

		}

3610 3611 3612 3613 3614 3615 3616 3617
		extension = extensions.get( 'WEBGL_compressed_texture_etc1' );

		if ( extension !== null ) {

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

		}

3618 3619 3620
		extension = extensions.get( 'EXT_blend_minmax' );

		if ( extension !== null ) {
3621

3622 3623
			if ( p === THREE.MinEquation ) return extension.MIN_EXT;
			if ( p === THREE.MaxEquation ) return extension.MAX_EXT;
3624 3625 3626

		}

M
Mr.doob 已提交
3627 3628
		return 0;

M
Mr.doob 已提交
3629
	}
M
Mr.doob 已提交
3630 3631

};