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

THREE.WebGLRenderer = function ( parameters ) {

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

	parameters = parameters || {};

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

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

20 21
	pixelRatio = 1,

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

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

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

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

39 40
	var morphInfluences = new Float32Array( 8 );

41

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

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

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

	// clearing

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

	// scene graph

	this.sortObjects = true;

	// physically based shading

63
	this.gammaFactor = 2.0;	// for backwards compatibility
M
Mr.doob 已提交
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
	this.gammaInput = false;
	this.gammaOutput = false;

	// morphs

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

	// flags

	this.autoScaleCubemaps = true;

	// internal properties

	var _this = this,

	// internal state cache

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

	_usedTextureUnits = 0,

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

	// frustum

	_frustum = new THREE.Frustum(),

	 // camera matrices cache

	_projScreenMatrix = new THREE.Matrix4(),

	_vector3 = new THREE.Vector3(),

	// light arrays cache

	_lights = {

111 112
		hash: '',

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

119
		shadows: [],
120
		shadowsPointLight: 0
M
Mr.doob 已提交
121

122 123
	},

M
Mr.doob 已提交
124 125
	// info

126
	_infoMemory = {
127 128

		geometries: 0,
T
tschw 已提交
129
		textures: 0
130 131 132

	},

133
	_infoRender = {
134 135 136 137 138 139

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

M
Mr.doob 已提交
140 141
	};

M
Mr.doob 已提交
142
	this.info = {
143

M
Mr.doob 已提交
144 145
		render: _infoRender,
		memory: _infoMemory,
146
		programs: null
M
Mr.doob 已提交
147 148

	};
149

150

M
Mr.doob 已提交
151 152 153 154
	// initialize

	var _gl;

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

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

			} else {

				throw 'Error creating WebGL context.';

			}
M
Mr.doob 已提交
179 180 181

		}

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

M
Mr.doob 已提交
184 185
	} catch ( error ) {

186
		console.error( 'THREE.WebGLRenderer: ' + error );
M
Mr.doob 已提交
187 188 189

	}

190 191
	var extensions = new THREE.WebGLExtensions( _gl );

192 193
	extensions.get( 'OES_texture_float' );
	extensions.get( 'OES_texture_float_linear' );
194 195
	extensions.get( 'OES_texture_half_float' );
	extensions.get( 'OES_texture_half_float_linear' );
196
	extensions.get( 'OES_standard_derivatives' );
B
Ben Adams 已提交
197
	extensions.get( 'ANGLE_instanced_arrays' );
198

199 200
	if ( extensions.get( 'OES_element_index_uint' ) ) {

201
		THREE.BufferGeometry.MaxIndex = 4294967296;
202 203 204

	}

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

207 208 209
	var state = new THREE.WebGLState( _gl, extensions, paramThreeToGL );
	var properties = new THREE.WebGLProperties();
	var objects = new THREE.WebGLObjects( _gl, properties, this.info );
G
gero3 已提交
210
	var programCache = new THREE.WebGLPrograms( this, capabilities );
M
Mr.doob 已提交
211
	var lightCache = new THREE.WebGLLights();
212

213 214
	this.info.programs = programCache.programs;

215 216
	var bufferRenderer = new THREE.WebGLBufferRenderer( _gl, extensions, _infoRender );
	var indexedBufferRenderer = new THREE.WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
217

M
Mr.doob 已提交
218 219
	//

220
	function glClearColor( r, g, b, a ) {
221 222 223

		if ( _premultipliedAlpha === true ) {

224
			r *= a; g *= a; b *= a;
225 226 227

		}

228 229
		_gl.clearColor( r, g, b, a );

230
	}
231

232
	function setDefaultGLState() {
M
Mr.doob 已提交
233

M
Mr.doob 已提交
234
		state.init();
M
Mr.doob 已提交
235 236 237

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

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

240
	}
241

242
	function resetGLState() {
243 244 245 246

		_currentProgram = null;
		_currentCamera = null;

247
		_currentGeometryProgram = '';
248 249
		_currentMaterialId = - 1;

M
Mr.doob 已提交
250 251
		state.reset();

252
	}
M
Mr.doob 已提交
253 254 255 256

	setDefaultGLState();

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

M
Mr.doob 已提交
261 262
	// shadow map

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

265
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
266

M
Mr.doob 已提交
267

M
Mr.doob 已提交
268 269 270 271 272
	// Plugins

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

M
Mr.doob 已提交
273 274 275 276 277 278 279 280
	// API

	this.getContext = function () {

		return _gl;

	};

281 282 283 284 285 286
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

287 288 289 290 291 292
	this.forceContextLoss = function () {

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

	};

293
	this.getMaxAnisotropy = ( function () {
M
Mr.doob 已提交
294

295
		var value;
M
Mr.doob 已提交
296

297
		return function getMaxAnisotropy() {
298

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

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

M
Mr.doob 已提交
303
			if ( extension !== null ) {
304

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

M
Mr.doob 已提交
307 308 309 310 311
			} else {

				value = 0;

			}
312 313 314

			return value;

M
Mr.doob 已提交
315
		};
316 317

	} )();
M
Mr.doob 已提交
318 319 320

	this.getPrecision = function () {

G
gero3 已提交
321
		return capabilities.precision;
M
Mr.doob 已提交
322 323 324

	};

325 326 327 328 329 330 331 332
	this.getPixelRatio = function () {

		return pixelRatio;

	};

	this.setPixelRatio = function ( value ) {

333
		if ( value !== undefined ) pixelRatio = value;
334 335 336

	};

337 338 339 340 341 342 343 344 345
	this.getSize = function () {

		return {
			width: _width,
			height: _height
		};

	};

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

348 349 350
		_width = width;
		_height = height;

351 352
		_canvas.width = width * pixelRatio;
		_canvas.height = height * pixelRatio;
353

354
		if ( updateStyle !== false ) {
355

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

G
gero3 已提交
359
		}
M
Mr.doob 已提交
360

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

	};

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

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

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

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

	};

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

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

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

	};

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

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

	};

398
	this.enableScissorTest = function ( boolean ) {
M
Mr.doob 已提交
399

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

	};

	// Clearing

M
Mr.doob 已提交
406
	this.getClearColor = function () {
M
Mr.doob 已提交
407

M
Mr.doob 已提交
408
		return _clearColor;
M
Mr.doob 已提交
409 410 411

	};

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

M
Mr.doob 已提交
414
		_clearColor.set( color );
415

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

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

	};

M
Mr.doob 已提交
422
	this.getClearAlpha = function () {
M
Mr.doob 已提交
423

M
Mr.doob 已提交
424
		return _clearAlpha;
M
Mr.doob 已提交
425 426 427

	};

M
Mr.doob 已提交
428
	this.setClearAlpha = function ( alpha ) {
M
Mr.doob 已提交
429

M
Mr.doob 已提交
430
		_clearAlpha = alpha;
M
Mr.doob 已提交
431

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

	};

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

	};

	this.clearColor = function () {

		_gl.clear( _gl.COLOR_BUFFER_BIT );

	};

	this.clearDepth = function () {

		_gl.clear( _gl.DEPTH_BUFFER_BIT );

	};

	this.clearStencil = function () {

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

	};

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

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

	};

M
Mr.doob 已提交
473 474
	// Reset

475
	this.resetGLState = resetGLState;
M
Mr.doob 已提交
476

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

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

	};

M
Mr.doob 已提交
483
	// Events
M
Mr.doob 已提交
484

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

		event.preventDefault();

		resetGLState();
		setDefaultGLState();

		properties.clear();

	};

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

		var texture = event.target;

		texture.removeEventListener( 'dispose', onTextureDispose );

		deallocateTexture( texture );

504
		_infoMemory.textures --;
M
Mr.doob 已提交
505 506


507
	}
M
Mr.doob 已提交
508

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

		var renderTarget = event.target;

		renderTarget.removeEventListener( 'dispose', onRenderTargetDispose );

		deallocateRenderTarget( renderTarget );

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

519
	}
M
Mr.doob 已提交
520

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

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

529
	}
M
Mr.doob 已提交
530 531 532

	// Buffer deallocation

533
	function deallocateTexture( texture ) {
M
Mr.doob 已提交
534

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

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

			// cube texture

541
			_gl.deleteTexture( textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
542

543 544 545 546
		} else {

			// 2D texture

547
			if ( textureProperties.__webglInit === undefined ) return;
548

549
			_gl.deleteTexture( textureProperties.__webglTexture );
550

M
Mr.doob 已提交
551 552
		}

553
		// remove all webgl properties
554
		properties.delete( texture );
555

556
	}
M
Mr.doob 已提交
557

558
	function deallocateRenderTarget( renderTarget ) {
M
Mr.doob 已提交
559

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

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

M
Mr.doob 已提交
565
		_gl.deleteTexture( textureProperties.__webglTexture );
M
Mr.doob 已提交
566

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

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

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

			}

		} else {

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

		}

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

586
	}
M
Mr.doob 已提交
587

588
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
589

590 591 592 593
		releaseMaterialProgramReference( material );

		properties.delete( material );

594
	}
595 596


597
	function releaseMaterialProgramReference( material ) {
598

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

		material.program = undefined;

603
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
604

605
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
606

M
Mr.doob 已提交
607 608
		}

609
	}
M
Mr.doob 已提交
610 611 612 613 614

	// Buffer rendering

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

615
		state.initAttributes();
616

617
		var buffers = properties.get( object );
618

619 620 621 622
		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 已提交
623

624
		var attributes = program.getAttributes();
625

M
Mr.doob 已提交
626 627
		if ( object.hasPositions ) {

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

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

		}

		if ( object.hasNormals ) {

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

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

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

644
					var array = object.normalArray;
M
Mr.doob 已提交
645

646 647 648
					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 已提交
649

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

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

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

				}

			}

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

668
			state.enableAttribute( attributes.normal );
669

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

		}

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

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

679
			state.enableAttribute( attributes.uv );
680

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

		}

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

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

690
			state.enableAttribute( attributes.color );
691

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

		}

696
		state.disableUnusedAttributes();
697

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

		object.count = 0;

	};

704
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
705

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

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

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

		if ( geometryProgram !== _currentGeometryProgram ) {

			_currentGeometryProgram = geometryProgram;
			updateBuffers = true;

		}

		// morph targets

		var morphTargetInfluences = object.morphTargetInfluences;

		if ( morphTargetInfluences !== undefined ) {

			var activeInfluences = [];

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

				var influence = morphTargetInfluences[ i ];
				activeInfluences.push( [ influence, i ] );

			}

			activeInfluences.sort( numericalSort );

			if ( activeInfluences.length > 8 ) {

				activeInfluences.length = 8;

			}

743 744
			var morphAttributes = geometry.morphAttributes;

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

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

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

752
					var index = influence[ 1 ];
M
Mr.doob 已提交
753

754 755
					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 已提交
756 757 758

				} else {

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

				}

			}

			var uniforms = program.getUniforms();

			if ( uniforms.morphTargetInfluences !== null ) {

				_gl.uniform1fv( uniforms.morphTargetInfluences, morphInfluences );

			}

			updateBuffers = true;

		}

M
Mr.doob 已提交
778 779
		//

780
		var index = geometry.index;
781 782
		var position = geometry.attributes.position;

783 784
		if ( material.wireframe === true ) {

785
			index = objects.getWireframeAttribute( geometry );
786 787 788

		}

789 790
		var renderer;

791
		if ( index !== null ) {
792

793 794
			renderer = indexedBufferRenderer;
			renderer.setIndex( index );
795

796
		} else {
797

798
			renderer = bufferRenderer;
799

800
		}
M
Mr.doob 已提交
801

802
		if ( updateBuffers ) {
M
Mr.doob 已提交
803

804
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
805

806
			if ( index !== null ) {
807

808
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );
809 810 811

			}

812
		}
813

M
Mr.doob 已提交
814
		//
815

M
Mr.doob 已提交
816 817
		var dataStart = 0;
		var dataCount = Infinity;
818

M
Mr.doob 已提交
819
		if ( index !== null ) {
820

M
Mr.doob 已提交
821
			dataCount = index.count
822

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

M
Mr.doob 已提交
825
			dataCount = position.count;
826

M
Mr.doob 已提交
827
		}
828

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

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

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

		//
841

842
		if ( object instanceof THREE.Mesh ) {
843

844
			if ( material.wireframe === true ) {
845

846 847
				state.setLineWidth( material.wireframeLinewidth * pixelRatio );
				renderer.setMode( _gl.LINES );
848

849
			} else {
M
Mr.doob 已提交
850 851

				switch ( object.drawMode ) {
852

B
Ben Adams 已提交
853 854 855 856 857 858 859 860 861 862 863 864 865
					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;

				}
866

867
			}
868

869

870
		} else if ( object instanceof THREE.Line ) {
871

872
			var lineWidth = material.linewidth;
873

874
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
875

876
			state.setLineWidth( lineWidth * pixelRatio );
877

878
			if ( object instanceof THREE.LineSegments ) {
879

880
				renderer.setMode( _gl.LINES );
881

882
			} else {
883

884
				renderer.setMode( _gl.LINE_STRIP );
885 886

			}
M
Mr.doob 已提交
887

888
		} else if ( object instanceof THREE.Points ) {
889 890

			renderer.setMode( _gl.POINTS );
891 892

		}
893

894 895 896 897 898 899
		if ( geometry instanceof THREE.InstancedBufferGeometry && geometry.maxInstancedCount > 0 ) {

			renderer.renderInstances( geometry, drawStart, drawCount );

		} else {

M
Mr.doob 已提交
900
			renderer.render( drawStart, drawCount );
901

M
Mr.doob 已提交
902 903 904 905
		}

	};

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

M
Mr.doob 已提交
908
		var extension;
B
Ben Adams 已提交
909

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

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

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

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

M
Mr.doob 已提交
919 920 921
			}

		}
B
Ben Adams 已提交
922

923 924
		if ( startIndex === undefined ) startIndex = 0;

925 926
		state.initAttributes();

927
		var geometryAttributes = geometry.attributes;
928

929
		var programAttributes = program.getAttributes();
930

931
		var materialDefaultAttributeValues = material.defaultAttributeValues;
932

933
		for ( var name in programAttributes ) {
934

935
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
936

M
Mr.doob 已提交
937
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
938

939
				var geometryAttribute = geometryAttributes[ name ];
940

M
Mr.doob 已提交
941
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
942

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

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

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

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

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

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

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

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

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

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

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

M
Mr.doob 已提交
968 969
						_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 已提交
970

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

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

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

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

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

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

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

							state.enableAttribute( programAttribute );

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

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

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

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

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

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

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

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

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

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

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

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

					}

				}

			}

		}
1026

1027
		state.disableUnusedAttributes();
1028

M
Mr.doob 已提交
1029 1030
	}

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

1033 1034 1035 1036 1037 1038
	function numericalSort ( a, b ) {

		return b[ 0 ] - a[ 0 ];

	}

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

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

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

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

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

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

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

		} else {

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

		}

1059
	}
M
Mr.doob 已提交
1060

1061 1062
	function reversePainterSortStable ( a, b ) {

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

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

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

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

		} else {

			return a.id - b.id;

		}

1077
	}
1078

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

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

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

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

		}

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

		// reset caching for this frame

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

		// update scene graph

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

		// update camera matrices and frustum

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

		camera.matrixWorldInverse.getInverse( camera.matrixWorld );

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

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

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

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

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

1121 1122 1123
		opaqueObjects.length = opaqueObjectsLastIndex + 1;
		transparentObjects.length = transparentObjectsLastIndex + 1;

M
Mr.doob 已提交
1124
		if ( _this.sortObjects === true ) {
1125 1126 1127

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

1129 1130
		}

1131 1132
		setupLights( lights, camera );

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

M
Mr.doob 已提交
1135
		shadowMap.render( scene, camera );
M
Mr.doob 已提交
1136 1137 1138

		//

1139 1140 1141 1142
		_infoRender.calls = 0;
		_infoRender.vertices = 0;
		_infoRender.faces = 0;
		_infoRender.points = 0;
M
Mr.doob 已提交
1143 1144 1145 1146 1147 1148 1149 1150 1151

		this.setRenderTarget( renderTarget );

		if ( this.autoClear || forceClear ) {

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

		}

1152
		//
M
Mr.doob 已提交
1153 1154 1155

		if ( scene.overrideMaterial ) {

1156
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1157

1158 1159
			renderObjects( opaqueObjects, camera, fog, overrideMaterial );
			renderObjects( transparentObjects, camera, fog, overrideMaterial );
1160

M
Mr.doob 已提交
1161 1162 1163 1164
		} else {

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

M
Mr.doob 已提交
1165
			state.setBlending( THREE.NoBlending );
1166
			renderObjects( opaqueObjects, camera, fog );
M
Mr.doob 已提交
1167 1168 1169

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

1170
			renderObjects( transparentObjects, camera, fog );
M
Mr.doob 已提交
1171 1172 1173 1174 1175

		}

		// custom render plugins (post pass)

M
Mr.doob 已提交
1176 1177
		spritePlugin.render( scene, camera );
		lensFlarePlugin.render( scene, camera, _currentWidth, _currentHeight );
M
Mr.doob 已提交
1178 1179 1180

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

M
Mr.doob 已提交
1181 1182 1183
		if ( renderTarget ) {

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

M
Mr.doob 已提交
1185 1186 1187 1188 1189
			if ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&
					texture.minFilter !== THREE.NearestFilter &&
					texture.minFilter !== THREE.LinearFilter ) {

				updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1190 1191

			}
M
Mr.doob 已提交
1192 1193 1194 1195 1196

		}

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

M
Mr.doob 已提交
1197 1198
		state.setDepthTest( true );
		state.setDepthWrite( true );
1199
		state.setColorWrite( true );
M
Mr.doob 已提交
1200 1201 1202 1203

		// _gl.finish();

	};
M
Mr.doob 已提交
1204

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

1207
		var array, index;
M
Mr.doob 已提交
1208

1209
		// allocate the next position in the appropriate array
M
Mr.doob 已提交
1210 1211 1212

		if ( material.transparent ) {

1213 1214
			array = transparentObjects;
			index = ++ transparentObjectsLastIndex;
M
Mr.doob 已提交
1215 1216 1217

		} else {

1218 1219 1220 1221 1222
			array = opaqueObjects;
			index = ++ opaqueObjectsLastIndex;

		}

1223 1224
		// recycle existing render item or grow the array

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

		} else {

1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248
			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 已提交
1249 1250 1251 1252 1253

		}

	}

1254
	function projectObject( object, camera ) {
M
Mr.doob 已提交
1255

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

1258
		if ( object.layers.test( camera.layers ) ) {
M
Mr.doob 已提交
1259

1260
			if ( object instanceof THREE.Light ) {
M
Mr.doob 已提交
1261

1262
				lights.push( object );
M
Mr.doob 已提交
1263

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

1266 1267 1268 1269 1270
				if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) {

					sprites.push( object );

				}
M
Mr.doob 已提交
1271

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

1274
				lensFlares.push( object );
M
Mr.doob 已提交
1275

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

1278
				if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1279

1280 1281
					_vector3.setFromMatrixPosition( object.matrixWorld );
					_vector3.applyProjection( _projScreenMatrix );
M
Mr.doob 已提交
1282

1283
				}
1284

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

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

1289
				if ( object instanceof THREE.SkinnedMesh ) {
M
Mr.doob 已提交
1290

1291
					object.skeleton.update();
1292

1293
				}
1294

1295
				if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) {
1296

1297
					var material = object.material;
1298

1299
					if ( material.visible === true ) {
M
Mr.doob 已提交
1300

1301
						if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1302

1303 1304 1305 1306
							_vector3.setFromMatrixPosition( object.matrixWorld );
							_vector3.applyProjection( _projScreenMatrix );

						}
M
Mr.doob 已提交
1307

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

1310
						if ( material instanceof THREE.MeshFaceMaterial ) {
1311

1312 1313
							var groups = geometry.groups;
							var materials = material.materials;
1314

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

1317 1318
								var group = groups[ i ];
								var groupMaterial = materials[ group.materialIndex ];
1319

1320
								if ( groupMaterial.visible === true ) {
1321

1322 1323 1324
									pushRenderItem( object, geometry, groupMaterial, _vector3.z, group );

								}
M
Mr.doob 已提交
1325

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

1328
						} else {
M
Mr.doob 已提交
1329

1330
							pushRenderItem( object, geometry, material, _vector3.z, null );
1331

1332
						}
O
OpenShift guest 已提交
1333

1334
					}
M
Mr.doob 已提交
1335

1336
				}
M
Mr.doob 已提交
1337

1338
			}
M
Mr.doob 已提交
1339

M
Mr.doob 已提交
1340
		}
M
Mr.doob 已提交
1341

M
Mr.doob 已提交
1342
		var children = object.children;
M
Mr.doob 已提交
1343

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

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

1348
		}
1349

1350
	}
M
Mr.doob 已提交
1351

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

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

1356
			var renderItem = renderList[ i ];
M
Mr.doob 已提交
1357

1358
			var object = renderItem.object;
M
Mr.doob 已提交
1359 1360 1361
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
M
Mr.doob 已提交
1362

1363 1364
			object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
			object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
M
Mr.doob 已提交
1365

M
Mr.doob 已提交
1366
			if ( object instanceof THREE.ImmediateRenderObject ) {
M
Mr.doob 已提交
1367

M
Mr.doob 已提交
1368
				setMaterial( material );
M
Mr.doob 已提交
1369

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

M
Mr.doob 已提交
1372
				_currentGeometryProgram = '';
M
Mr.doob 已提交
1373

M
Mr.doob 已提交
1374
				object.render( function ( object ) {
M
Mr.doob 已提交
1375

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

M
Mr.doob 已提交
1378
				} );
1379

M
Mr.doob 已提交
1380
			} else {
M
Mr.doob 已提交
1381

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

M
Mr.doob 已提交
1384
			}
M
Mr.doob 已提交
1385

1386
		}
M
Mr.doob 已提交
1387

1388
	}
G
gero3 已提交
1389

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

1392
		var materialProperties = properties.get( material );
G
gero3 已提交
1393

1394
		var parameters = programCache.getParameters( material, _lights, fog, object );
G
gero3 已提交
1395
		var code = programCache.getProgramCode( material, parameters );
G
gero3 已提交
1396

1397
		var program = materialProperties.program;
T
tschw 已提交
1398
		var programChange = true;
1399

1400
		if ( program === undefined ) {
B
Ben Adams 已提交
1401

M
Mr.doob 已提交
1402 1403
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1404

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

M
Mr.doob 已提交
1407
			// changed glsl or parameters
1408
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1409

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

T
tschw 已提交
1412
			// same glsl and uniform list
T
tschw 已提交
1413 1414
			return;

T
tschw 已提交
1415
		} else {
B
Ben Adams 已提交
1416

T
tschw 已提交
1417 1418
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1419 1420 1421

		}

1422
		if ( programChange ) {
B
Ben Adams 已提交
1423

1424
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1425

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

1428 1429 1430 1431 1432 1433
				materialProperties.__webglShader = {
					name: material.type,
					uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
					vertexShader: shader.vertexShader,
					fragmentShader: shader.fragmentShader
				};
B
Ben Adams 已提交
1434

1435
			} else {
B
Ben Adams 已提交
1436

1437 1438 1439 1440 1441 1442
				materialProperties.__webglShader = {
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
					fragmentShader: material.fragmentShader
				};
G
gero3 已提交
1443

1444
			}
G
gero3 已提交
1445

1446
			material.__webglShader = materialProperties.__webglShader;
G
gero3 已提交
1447

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

1450 1451
			materialProperties.program = program;
			material.program = program;
1452 1453 1454

		}

1455
		var attributes = program.getAttributes();
M
Mr.doob 已提交
1456 1457 1458 1459 1460

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

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

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

M
Mr.doob 已提交
1479
				if ( attributes[ 'morphNormal' + i ] >= 0 ) {
M
Mr.doob 已提交
1480 1481 1482 1483 1484 1485 1486 1487 1488

					material.numSupportedMorphNormals ++;

				}

			}

		}

1489
		materialProperties.uniformsList = [];
M
Mr.doob 已提交
1490

1491 1492
		var uniforms = materialProperties.__webglShader.uniforms,
			uniformLocations = materialProperties.program.getUniforms();
M
Mr.doob 已提交
1493

1494
		for ( var u in uniforms ) {
M
Mr.doob 已提交
1495

1496
			var location = uniformLocations[ u ];
1497 1498

			if ( location ) {
G
gero3 已提交
1499

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

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

		}

1506 1507
		if ( material instanceof THREE.MeshPhongMaterial ||
				material instanceof THREE.MeshLambertMaterial ||
1508
				material instanceof THREE.MeshStandardMaterial ||
1509 1510
				material.lights ) {

1511 1512
			// store the light setup it was created for

1513 1514
			materialProperties.lightsHash = _lights.hash;

1515 1516 1517 1518 1519 1520 1521 1522 1523 1524
			// wire up the material to this renderer's lighting state

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

		}

A
arose 已提交
1525 1526 1527 1528 1529 1530 1531 1532
		// detect dynamic uniforms

		materialProperties.hasDynamicUniforms = false;

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

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

1533
			if ( uniform.dynamic === true ) {
A
arose 已提交
1534 1535 1536 1537 1538 1539 1540 1541

				materialProperties.hasDynamicUniforms = true;
				break;

			}

		}

M
Mr.doob 已提交
1542
	}
M
Mr.doob 已提交
1543

1544 1545
	function setMaterial( material ) {

M
Mr.doob 已提交
1546 1547
		setMaterialFaces( material );

1548 1549
		if ( material.transparent === true ) {

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

1552 1553 1554 1555
		} else {

			state.setBlending( THREE.NoBlending );

1556 1557
		}

B
Ben Adams 已提交
1558
		state.setDepthFunc( material.depthFunc );
M
Mr.doob 已提交
1559 1560
		state.setDepthTest( material.depthTest );
		state.setDepthWrite( material.depthWrite );
1561
		state.setColorWrite( material.colorWrite );
M
Mr.doob 已提交
1562
		state.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
1563 1564 1565

	}

M
Mr.doob 已提交
1566 1567
	function setMaterialFaces( material ) {

1568
		material.side !== THREE.DoubleSide ? state.enable( _gl.CULL_FACE ) : state.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
1569 1570 1571 1572
		state.setFlipSided( material.side === THREE.BackSide );

	}

1573
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1574 1575 1576

		_usedTextureUnits = 0;

1577
		var materialProperties = properties.get( material );
1578

1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592
		if ( materialProperties.program === undefined ) {

			material.needsUpdate = true;

		}

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

			material.needsUpdate = true;

		}

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

1594
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1595 1596 1597 1598
			material.needsUpdate = false;

		}

1599
		var refreshProgram = false;
M
Mr.doob 已提交
1600
		var refreshMaterial = false;
1601
		var refreshLights = false;
M
Mr.doob 已提交
1602

1603
		var program = materialProperties.program,
1604
			p_uniforms = program.getUniforms(),
1605
			m_uniforms = materialProperties.__webglShader.uniforms;
M
Mr.doob 已提交
1606

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

1609 1610
			_gl.useProgram( program.program );
			_currentProgram = program.id;
M
Mr.doob 已提交
1611

1612
			refreshProgram = true;
M
Mr.doob 已提交
1613
			refreshMaterial = true;
1614
			refreshLights = true;
M
Mr.doob 已提交
1615 1616 1617 1618 1619 1620

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1621

M
Mr.doob 已提交
1622 1623 1624 1625
			refreshMaterial = true;

		}

1626
		if ( refreshProgram || camera !== _currentCamera ) {
M
Mr.doob 已提交
1627 1628 1629

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

G
gero3 已提交
1630
			if ( capabilities.logarithmicDepthBuffer ) {
1631

1632
				_gl.uniform1f( p_uniforms.logDepthBufFC, 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1633 1634 1635 1636

			}


1637 1638 1639 1640 1641 1642 1643 1644 1645
			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 已提交
1646
				refreshLights = true;		// remains set until update done
1647 1648

			}
M
Mr.doob 已提交
1649

1650 1651 1652 1653 1654
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
1655
				 material instanceof THREE.MeshStandardMaterial ||
1656 1657
				 material.envMap ) {

1658
				if ( p_uniforms.cameraPosition !== undefined ) {
1659 1660 1661 1662 1663 1664 1665 1666 1667 1668

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

				}

			}

			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
1669
				 material instanceof THREE.MeshBasicMaterial ||
1670
				 material instanceof THREE.MeshStandardMaterial ||
1671 1672 1673
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {

1674
				if ( p_uniforms.viewMatrix !== undefined ) {
1675 1676

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

1678 1679 1680 1681
				}

			}

M
Mr.doob 已提交
1682 1683 1684 1685 1686 1687 1688 1689
		}

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

1690
			if ( object.bindMatrix && p_uniforms.bindMatrix !== undefined ) {
1691 1692 1693 1694 1695

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

			}

1696
			if ( object.bindMatrixInverse && p_uniforms.bindMatrixInverse !== undefined ) {
1697 1698 1699 1700 1701

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

			}

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

1704
				if ( p_uniforms.boneTexture !== undefined ) {
M
Mr.doob 已提交
1705 1706 1707 1708

					var textureUnit = getTextureUnit();

					_gl.uniform1i( p_uniforms.boneTexture, textureUnit );
1709
					_this.setTexture( object.skeleton.boneTexture, textureUnit );
M
Mr.doob 已提交
1710 1711 1712

				}

1713
				if ( p_uniforms.boneTextureWidth !== undefined ) {
1714

1715
					_gl.uniform1i( p_uniforms.boneTextureWidth, object.skeleton.boneTextureWidth );
1716 1717 1718

				}

1719
				if ( p_uniforms.boneTextureHeight !== undefined ) {
1720

1721
					_gl.uniform1i( p_uniforms.boneTextureHeight, object.skeleton.boneTextureHeight );
1722 1723 1724

				}

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

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

1729
					_gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.skeleton.boneMatrices );
M
Mr.doob 已提交
1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740

				}

			}

		}

		if ( refreshMaterial ) {

			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
1741
				 material instanceof THREE.MeshStandardMaterial ||
M
Mr.doob 已提交
1742 1743
				 material.lights ) {

1744
				// the current material requires lighting info
M
Mr.doob 已提交
1745

T
tschw 已提交
1746 1747 1748 1749 1750 1751
				// 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 已提交
1752

T
tschw 已提交
1753
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1754

T
tschw 已提交
1755
			}
G
gero3 已提交
1756

T
tschw 已提交
1757
			// refresh uniforms common to several materials
G
gero3 已提交
1758

T
tschw 已提交
1759
			if ( fog && material.fog ) {
G
gero3 已提交
1760

T
tschw 已提交
1761
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1762 1763 1764 1765 1766

			}

			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
W
WestLangley 已提交
1767
				 material instanceof THREE.MeshPhongMaterial ||
1768
				 material instanceof THREE.MeshStandardMaterial ) {
M
Mr.doob 已提交
1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784

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

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

M
Mr.doob 已提交
1787
				refreshUniformsPoints( m_uniforms, material );
M
Mr.doob 已提交
1788 1789 1790 1791 1792

			} else if ( material instanceof THREE.MeshPhongMaterial ) {

				refreshUniformsPhong( m_uniforms, material );

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

1795
				refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1796

M
Mr.doob 已提交
1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808
			} else if ( material instanceof THREE.MeshDepthMaterial ) {

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

			} else if ( material instanceof THREE.MeshNormalMaterial ) {

				m_uniforms.opacity.value = material.opacity;

			}

M
Mr.doob 已提交
1809
			if ( shadowMap.enabled ) {
M
Mr.doob 已提交
1810

1811 1812
				if ( object.receiveShadow && ! material._shadowPass ) {

1813
					refreshUniformsShadow( m_uniforms, camera );
1814 1815

				}
M
Mr.doob 已提交
1816 1817 1818 1819 1820

			}

			// load common uniforms

1821
			loadUniformsGeneric( materialProperties.uniformsList );
M
Mr.doob 已提交
1822 1823 1824 1825 1826

		}

		loadUniformsMatrices( p_uniforms, object );

1827
		if ( p_uniforms.modelMatrix !== undefined ) {
M
Mr.doob 已提交
1828 1829

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

M
Mr.doob 已提交
1831 1832
		}

1833
		if ( materialProperties.hasDynamicUniforms === true ) {
A
arose 已提交
1834

1835
			updateDynamicUniforms( materialProperties.uniformsList, object, camera );
A
arose 已提交
1836 1837 1838

		}

M
Mr.doob 已提交
1839 1840
		return program;

M
Mr.doob 已提交
1841
	}
M
Mr.doob 已提交
1842

1843
	function updateDynamicUniforms ( uniforms, object, camera ) {
A
arose 已提交
1844 1845 1846 1847 1848 1849

		var dynamicUniforms = [];

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

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

1852
			if ( onUpdateCallback !== undefined ) {
A
arose 已提交
1853

1854
				onUpdateCallback.bind( uniform )( object, camera );
A
arose 已提交
1855 1856 1857 1858 1859 1860 1861 1862 1863 1864
				dynamicUniforms.push( uniforms[ j ] );

			}

		}

		loadUniformsGeneric( dynamicUniforms );

	}

M
Mr.doob 已提交
1865 1866 1867 1868 1869 1870
	// Uniforms (refresh uniforms objects)

	function refreshUniformsCommon ( uniforms, material ) {

		uniforms.opacity.value = material.opacity;

1871
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
1872

1873
		if ( material.emissive ) {
M
Mr.doob 已提交
1874

1875
			uniforms.emissive.value = material.emissive;
M
Mr.doob 已提交
1876 1877 1878

		}

1879 1880 1881
		uniforms.map.value = material.map;
		uniforms.specularMap.value = material.specularMap;
		uniforms.alphaMap.value = material.alphaMap;
M
Mr.doob 已提交
1882

1883
		if ( material.aoMap ) {
1884

1885 1886
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1887 1888 1889

		}

M
Mr.doob 已提交
1890
		// uv repeat and offset setting priorities
M
Mr.doob 已提交
1891 1892 1893 1894 1895
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
1896
		// 6. emissive map
M
Mr.doob 已提交
1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

1908 1909 1910 1911
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
1912 1913 1914 1915 1916 1917 1918 1919
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

1920 1921 1922 1923 1924 1925 1926 1927
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

1928 1929 1930 1931
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

1932 1933 1934 1935
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
1936 1937 1938 1939
		}

		if ( uvScaleMap !== undefined ) {

M
Mr.doob 已提交
1940 1941 1942 1943 1944 1945
			if ( uvScaleMap instanceof THREE.WebGLRenderTarget ) {

				uvScaleMap = uvScaleMap.texture;

			}

M
Mr.doob 已提交
1946 1947 1948 1949 1950 1951 1952 1953
			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;
1954
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : - 1;
M
Mr.doob 已提交
1955

1956
		uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
1957 1958
		uniforms.refractionRatio.value = material.refractionRatio;

M
Mr.doob 已提交
1959
	}
M
Mr.doob 已提交
1960 1961 1962 1963 1964 1965

	function refreshUniformsLine ( uniforms, material ) {

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

M
Mr.doob 已提交
1966
	}
M
Mr.doob 已提交
1967 1968 1969 1970 1971 1972 1973

	function refreshUniformsDash ( uniforms, material ) {

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

M
Mr.doob 已提交
1974
	}
M
Mr.doob 已提交
1975

M
Mr.doob 已提交
1976
	function refreshUniformsPoints ( uniforms, material ) {
M
Mr.doob 已提交
1977 1978 1979

		uniforms.psColor.value = material.color;
		uniforms.opacity.value = material.opacity;
1980
		uniforms.size.value = material.size * pixelRatio;
M
Mr.doob 已提交
1981 1982 1983 1984
		uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.

		uniforms.map.value = material.map;

1985 1986 1987 1988 1989 1990 1991 1992 1993
		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 已提交
1994
	}
M
Mr.doob 已提交
1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010

	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 已提交
2011
	}
M
Mr.doob 已提交
2012 2013 2014

	function refreshUniformsPhong ( uniforms, material ) {

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

2018 2019 2020 2021
		if ( material.lightMap ) {

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

2023
		}
2024

2025
		if ( material.emissiveMap ) {
2026

2027
			uniforms.emissiveMap.value = material.emissiveMap;
2028

2029
		}
M
Mr.doob 已提交
2030

2031 2032 2033 2034
		if ( material.bumpMap ) {

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

2036
		}
M
Mr.doob 已提交
2037

2038 2039 2040 2041 2042 2043
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2044

2045 2046 2047 2048 2049
		if ( material.displacementMap ) {

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

2051
		}
2052 2053 2054

	}

2055
	function refreshUniformsStandard ( uniforms, material ) {
W
WestLangley 已提交
2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115

		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;

		}

	}

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

M
Mr.doob 已提交
2118
	function markUniformsLightsNeedsUpdate ( uniforms, value ) {
2119

M
Mr.doob 已提交
2120
		uniforms.ambientLightColor.needsUpdate = value;
2121

B
Ben Houston 已提交
2122 2123 2124 2125
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
		uniforms.hemisphereLights.needsUpdate = value;
2126

M
Mr.doob 已提交
2127
	}
2128

2129
	function refreshUniformsShadow ( uniforms, camera ) {
M
Mr.doob 已提交
2130 2131 2132

		if ( uniforms.shadowMatrix ) {

2133
			var shadows = _lights.shadows;
M
Mr.doob 已提交
2134

2135
			for ( var i = 0, l = shadows.length; i < l; i ++ ) {
M
Mr.doob 已提交
2136

2137
				var light = shadows[ i ];
2138
				var shadow = light.shadow;
M
Mr.doob 已提交
2139

2140
				if ( light instanceof THREE.PointLight ) {
M
Mr.doob 已提交
2141

2142 2143 2144 2145
					// for point lights we set the shadow matrix to be a translation-only matrix
					// equal to inverse of the light's position
					_vector3.setFromMatrixPosition( light.matrixWorld ).negate();
					shadow.matrix.identity().setPosition( _vector3 );
M
Mr.doob 已提交
2146

2147 2148
					// for point lights we set the sign of the shadowDarkness uniform to be negative
					uniforms.shadowDarkness.value[ i ] = - shadow.darkness;
M
Mr.doob 已提交
2149

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

2152
					uniforms.shadowDarkness.value[ i ] = shadow.darkness;
M
Mr.doob 已提交
2153 2154 2155

				}

2156 2157 2158 2159 2160
				uniforms.shadowBias.value[ i ] = shadow.bias;
				uniforms.shadowMap.value[ i ] = shadow.map;
				uniforms.shadowMapSize.value[ i ] = shadow.mapSize;
				uniforms.shadowMatrix.value[ i ] = shadow.matrix;

M
Mr.doob 已提交
2161 2162 2163 2164
			}

		}

M
Mr.doob 已提交
2165
	}
M
Mr.doob 已提交
2166 2167 2168 2169 2170

	// Uniforms (load to GPU)

	function loadUniformsMatrices ( uniforms, object ) {

2171
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object.modelViewMatrix.elements );
M
Mr.doob 已提交
2172 2173 2174

		if ( uniforms.normalMatrix ) {

2175
			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object.normalMatrix.elements );
M
Mr.doob 已提交
2176 2177 2178

		}

M
Mr.doob 已提交
2179
	}
M
Mr.doob 已提交
2180 2181 2182 2183 2184

	function getTextureUnit() {

		var textureUnit = _usedTextureUnits;

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

G
gero3 已提交
2187
			console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
M
Mr.doob 已提交
2188 2189 2190 2191 2192 2193 2194

		}

		_usedTextureUnits += 1;

		return textureUnit;

M
Mr.doob 已提交
2195
	}
M
Mr.doob 已提交
2196

2197
	function loadUniformsGeneric ( uniforms ) {
M
Mr.doob 已提交
2198

M
Mr.doob 已提交
2199
		var texture, textureUnit;
M
Mr.doob 已提交
2200

M
Mr.doob 已提交
2201 2202 2203
		for ( var j = 0, jl = uniforms.length; j < jl; j ++ ) {

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

2205 2206
			// needsUpdate property is not added to all uniforms.
			if ( uniform.needsUpdate === false ) continue;
2207

M
Mr.doob 已提交
2208 2209
			var type = uniform.type;
			var value = uniform.value;
2210
			var location = uniforms[ j ][ 1 ];
M
Mr.doob 已提交
2211

2212
			switch ( type ) {
M
Mr.doob 已提交
2213

2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257
				case '1i':
					_gl.uniform1i( location, value );
					break;

				case '1f':
					_gl.uniform1f( location, value );
					break;

				case '2f':
					_gl.uniform2f( location, value[ 0 ], value[ 1 ] );
					break;

				case '3f':
					_gl.uniform3f( location, value[ 0 ], value[ 1 ], value[ 2 ] );
					break;

				case '4f':
					_gl.uniform4f( location, value[ 0 ], value[ 1 ], value[ 2 ], value[ 3 ] );
					break;

				case '1iv':
					_gl.uniform1iv( location, value );
					break;

				case '3iv':
					_gl.uniform3iv( location, value );
					break;

				case '1fv':
					_gl.uniform1fv( location, value );
					break;

				case '2fv':
					_gl.uniform2fv( location, value );
					break;

				case '3fv':
					_gl.uniform3fv( location, value );
					break;

				case '4fv':
					_gl.uniform4fv( location, value );
					break;

2258 2259 2260 2261
				case 'Matrix2fv':
					_gl.uniformMatrix2fv( location, false, value );
					break;

2262 2263 2264 2265 2266 2267 2268 2269 2270 2271
				case 'Matrix3fv':
					_gl.uniformMatrix3fv( location, false, value );
					break;

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

				//

M
Mr.doob 已提交
2272
				case 'i':
M
Mr.doob 已提交
2273

2274 2275
					// single integer
					_gl.uniform1i( location, value );
M
Mr.doob 已提交
2276

2277
					break;
M
Mr.doob 已提交
2278

2279
				case 'f':
M
Mr.doob 已提交
2280

2281 2282
					// single float
					_gl.uniform1f( location, value );
M
Mr.doob 已提交
2283

2284
					break;
M
Mr.doob 已提交
2285

2286
				case 'v2':
M
Mr.doob 已提交
2287

2288 2289
					// single THREE.Vector2
					_gl.uniform2f( location, value.x, value.y );
M
Mr.doob 已提交
2290

2291
					break;
M
Mr.doob 已提交
2292

2293
				case 'v3':
M
Mr.doob 已提交
2294

2295 2296
					// single THREE.Vector3
					_gl.uniform3f( location, value.x, value.y, value.z );
M
Mr.doob 已提交
2297

2298
					break;
M
Mr.doob 已提交
2299

M
Mr.doob 已提交
2300
				case 'v4':
M
Mr.doob 已提交
2301

2302 2303
					// single THREE.Vector4
					_gl.uniform4f( location, value.x, value.y, value.z, value.w );
M
Mr.doob 已提交
2304

2305
					break;
M
Mr.doob 已提交
2306

2307
				case 'c':
M
Mr.doob 已提交
2308

2309 2310
					// single THREE.Color
					_gl.uniform3f( location, value.r, value.g, value.b );
M
Mr.doob 已提交
2311

2312
					break;
M
Mr.doob 已提交
2313

2314
				/*
2315 2316 2317
				case 's':

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

B
Ben Houston 已提交
2320 2321 2322
						var property = uniform.properties[ propertyName ];
						var locationProperty =  location[ propertyName ];
						var valueProperty = value[ propertyName ];
M
Mr.doob 已提交
2323

2324
						switch( property.type ) {
2325 2326 2327
							case 'i':
								_gl.uniform1i( locationProperty, valueProperty );
								break;
2328
							case 'f':
B
Ben Houston 已提交
2329
								_gl.uniform1f( locationProperty, valueProperty );
2330 2331
								break;
							case 'v2':
B
Ben Houston 已提交
2332
								_gl.uniform2f( locationProperty, valueProperty.x, valueProperty.y );
2333 2334
								break;
							case 'v3':
B
Ben Houston 已提交
2335
								_gl.uniform3f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z );
2336 2337
								break;
							case 'v4':
B
Ben Houston 已提交
2338
								_gl.uniform4f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w );
2339 2340
								break;
							case 'c':
B
Ben Houston 已提交
2341
								_gl.uniform3f( locationProperty, valueProperty.r, valueProperty.g, valueProperty.b );
2342 2343
								break;
						};
2344 2345 2346 2347

					}

					break;
2348
				*/
2349

2350
				case 'sa':
2351

2352
					// TODO: Optimize this.
M
Mr.doob 已提交
2353
					for ( var i = 0; i < value.length; i ++ ) {
2354

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

B
Ben Houston 已提交
2357 2358
							var property = uniform.properties[ propertyName ];
							var locationProperty =  location[ i ][ propertyName ];
2359
							var valueProperty = value[ i ][ propertyName ];
M
Mr.doob 已提交
2360

2361
							switch ( property.type ) {
2362 2363 2364
								case 'i':
									_gl.uniform1i( locationProperty, valueProperty );
									break;
2365
								case 'f':
B
Ben Houston 已提交
2366
									_gl.uniform1f( locationProperty, valueProperty );
2367 2368
									break;
								case 'v2':
B
Ben Houston 已提交
2369
									_gl.uniform2f( locationProperty, valueProperty.x, valueProperty.y );
2370 2371
									break;
								case 'v3':
B
Ben Houston 已提交
2372
									_gl.uniform3f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z );
2373 2374
									break;
								case 'v4':
B
Ben Houston 已提交
2375
									_gl.uniform4f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w );
2376 2377
									break;
								case 'c':
B
Ben Houston 已提交
2378
									_gl.uniform3f( locationProperty, valueProperty.r, valueProperty.g, valueProperty.b );
2379 2380
									break;
							};
2381

2382
						}
2383 2384

					}
M
Mr.doob 已提交
2385

2386 2387
					break;

2388
				case 'iv1':
M
Mr.doob 已提交
2389

2390 2391
					// flat array of integers (JS or typed array)
					_gl.uniform1iv( location, value );
M
Mr.doob 已提交
2392

2393
					break;
M
Mr.doob 已提交
2394

2395
				case 'iv':
M
Mr.doob 已提交
2396

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

2400
					break;
M
Mr.doob 已提交
2401

2402
				case 'fv1':
M
Mr.doob 已提交
2403

2404 2405
					// flat array of floats (JS or typed array)
					_gl.uniform1fv( location, value );
M
Mr.doob 已提交
2406

2407
					break;
M
Mr.doob 已提交
2408

2409
				case 'fv':
M
Mr.doob 已提交
2410

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

2414
					break;
M
Mr.doob 已提交
2415

2416
				case 'v2v':
M
Mr.doob 已提交
2417

2418
					// array of THREE.Vector2
M
Mr.doob 已提交
2419

2420
					if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2421

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

2424
					}
M
Mr.doob 已提交
2425

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

M
Mr.doob 已提交
2428 2429
						uniform._array[ i2 + 0 ] = value[ i ].x;
						uniform._array[ i2 + 1 ] = value[ i ].y;
M
Mr.doob 已提交
2430

2431
					}
M
Mr.doob 已提交
2432

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

2435
					break;
M
Mr.doob 已提交
2436

2437
				case 'v3v':
M
Mr.doob 已提交
2438

2439
					// array of THREE.Vector3
M
Mr.doob 已提交
2440

2441
					if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2442

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

2445
					}
M
Mr.doob 已提交
2446

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

M
Mr.doob 已提交
2449 2450 2451
						uniform._array[ i3 + 0 ] = value[ i ].x;
						uniform._array[ i3 + 1 ] = value[ i ].y;
						uniform._array[ i3 + 2 ] = value[ i ].z;
R
Ryan Tsao 已提交
2452

2453
					}
R
Ryan Tsao 已提交
2454

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

2457
					break;
R
Ryan Tsao 已提交
2458

2459
				case 'v4v':
R
Ryan Tsao 已提交
2460

2461
					// array of THREE.Vector4
R
Ryan Tsao 已提交
2462

2463
					if ( uniform._array === undefined ) {
R
Ryan Tsao 已提交
2464

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

2467
					}
M
Mr.doob 已提交
2468

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

M
Mr.doob 已提交
2471 2472 2473 2474
						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 已提交
2475

2476
					}
M
Mr.doob 已提交
2477

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

2480
					break;
M
Mr.doob 已提交
2481

2482 2483 2484 2485 2486 2487 2488
				case 'm2':

					// single THREE.Matrix2
					_gl.uniformMatrix2fv( location, false, value.elements );

					break;

2489
				case 'm3':
M
Mr.doob 已提交
2490

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

2494
					break;
M
Mr.doob 已提交
2495

2496
				case 'm3v':
M
Mr.doob 已提交
2497

2498
					// array of THREE.Matrix3
M
Mr.doob 已提交
2499

2500
					if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2501

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

2504
					}
M
Mr.doob 已提交
2505

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

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

2510
					}
M
Mr.doob 已提交
2511

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

2514
					break;
M
Mr.doob 已提交
2515

2516
				case 'm4':
M
Mr.doob 已提交
2517

2518 2519
					// single THREE.Matrix4
					_gl.uniformMatrix4fv( location, false, value.elements );
M
Mr.doob 已提交
2520

2521
					break;
M
Mr.doob 已提交
2522

2523
				case 'm4v':
M
Mr.doob 已提交
2524

2525
					// array of THREE.Matrix4
M
Mr.doob 已提交
2526

2527
					if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2528

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

2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541
					}

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

						value[ i ].flattenToArrayOffset( uniform._array, i * 16 );

					}

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

					break;
M
Mr.doob 已提交
2542

2543
				case 't':
M
Mr.doob 已提交
2544

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

2547 2548 2549 2550
					texture = value;
					textureUnit = getTextureUnit();

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

2552
					if ( ! texture ) continue;
M
Mr.doob 已提交
2553

2554
					if ( texture instanceof THREE.CubeTexture ||
G
gero3 已提交
2555 2556 2557
						 ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {

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

2559
						setCubeTexture( texture, textureUnit );
M
Mr.doob 已提交
2560

2561 2562
					} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {

M
Mr.doob 已提交
2563 2564 2565 2566 2567
						setCubeTextureDynamic( texture.texture, textureUnit );

					} else if ( texture instanceof THREE.WebGLRenderTarget ) {

						_this.setTexture( texture.texture, textureUnit );
2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578

					} else {

						_this.setTexture( texture, textureUnit );

					}

					break;

				case 'tv':

M
Mr.doob 已提交
2579
					// array of THREE.Texture (2d or cube)
2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601

					if ( uniform._array === undefined ) {

						uniform._array = [];

					}

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

						uniform._array[ i ] = getTextureUnit();

					}

					_gl.uniform1iv( location, uniform._array );

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

						texture = uniform.value[ i ];
						textureUnit = uniform._array[ i ];

						if ( ! texture ) continue;

M
Mr.doob 已提交
2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621
						if ( texture instanceof THREE.CubeTexture ||
							 ( texture.image instanceof Array && texture.image.length === 6 ) ) {

							// CompressedTexture can have Array in image :/

							setCubeTexture( texture, textureUnit );

						} else if ( texture instanceof THREE.WebGLRenderTarget ) {

							_this.setTexture( texture.texture, textureUnit );

						} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {

							setCubeTextureDynamic( texture.texture, textureUnit );

						} else {

							_this.setTexture( texture, textureUnit );

						}
2622 2623 2624 2625 2626 2627

					}

					break;

				default:
2628

2629
					console.warn( 'THREE.WebGLRenderer: Unknown uniform type: ' + type );
2630

M
Mr.doob 已提交
2631 2632 2633 2634
			}

		}

M
Mr.doob 已提交
2635
	}
M
Mr.doob 已提交
2636

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

B
brason 已提交
2639
		var l, ll, light,
M
Mr.doob 已提交
2640
		r = 0, g = 0, b = 0,
B
Ben Houston 已提交
2641
		color,
B
brason 已提交
2642
		intensity,
M
Mr.doob 已提交
2643 2644
		distance,

2645
		viewMatrix = camera.matrixWorldInverse,
M
Mr.doob 已提交
2646

M
Mr.doob 已提交
2647
		directionalLength = 0,
M
Mr.doob 已提交
2648 2649
		pointLength = 0,
		spotLength = 0,
2650 2651 2652
		hemiLength = 0,

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

2654 2655
		_lights.shadowsPointLight = 0;

M
Mr.doob 已提交
2656 2657 2658 2659 2660 2661 2662 2663 2664 2665
		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 ) {

2666 2667 2668
				r += color.r * intensity;
				g += color.g * intensity;
				b += color.b * intensity;
M
Mr.doob 已提交
2669 2670 2671

			} else if ( light instanceof THREE.DirectionalLight ) {

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

M
Mr.doob 已提交
2674
				uniforms.direction.setFromMatrixPosition( light.matrixWorld );
2675
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
M
Mr.doob 已提交
2676 2677 2678 2679
				uniforms.direction.sub( _vector3 );
				uniforms.direction.transformDirection( viewMatrix );
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );

2680
				if ( light.castShadow ) {
M
Mr.doob 已提交
2681

2682 2683
					uniforms.shadow = shadowsLength;

2684
					_lights.shadows[ shadowsLength ++ ] = light;
2685

2686 2687
				} else {

M
Mr.doob 已提交
2688
					uniforms.shadow = - 1;
2689

2690 2691 2692
				}

				_lights.directional[ directionalLength ++ ] = uniforms;
M
Mr.doob 已提交
2693 2694 2695

			} else if ( light instanceof THREE.PointLight ) {

M
Mr.doob 已提交
2696
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2697 2698 2699

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

M
Mr.doob 已提交
2701 2702 2703
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
				uniforms.distance = light.distance;
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
M
Mr.doob 已提交
2704

2705 2706
				if ( light.castShadow ) {

2707 2708
					uniforms.shadow = shadowsLength;

2709
					_lights.shadows[ shadowsLength ++ ] = light;
2710 2711
					_lights.shadowsPointLight ++;

2712 2713
				} else {

M
Mr.doob 已提交
2714
					uniforms.shadow = - 1;
2715

2716 2717
				}

2718 2719
				_lights.point[ pointLength ++ ] = uniforms;

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

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

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

M
Mr.doob 已提交
2727 2728
				uniforms.color.copy( color ).multiplyScalar( intensity );
				uniforms.distance = distance;
M
Mr.doob 已提交
2729

M
Mr.doob 已提交
2730
				uniforms.direction.setFromMatrixPosition( light.matrixWorld );
2731
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
M
Mr.doob 已提交
2732 2733
				uniforms.direction.sub( _vector3 );
				uniforms.direction.transformDirection( viewMatrix );
M
Mr.doob 已提交
2734

M
Mr.doob 已提交
2735 2736 2737 2738
				uniforms.angleCos = Math.cos( light.angle );
				uniforms.exponent = light.exponent;
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;

2739 2740
				if ( light.castShadow ) {

2741 2742
					uniforms.shadow = shadowsLength;

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

2745 2746
				} else {

M
Mr.doob 已提交
2747
					uniforms.shadow = - 1;
2748

2749 2750 2751
				}

				_lights.spot[ spotLength ++ ] = uniforms;
2752

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

M
Mr.doob 已提交
2755
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2756 2757 2758 2759

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

M
Mr.doob 已提交
2761 2762
				uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
				uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
M
Mr.doob 已提交
2763

M
Mr.doob 已提交
2764
				_lights.hemi[ hemiLength ++ ] = uniforms;
M
Mr.doob 已提交
2765 2766 2767 2768 2769

			}

		}

M
Mr.doob 已提交
2770 2771 2772
		_lights.ambient[ 0 ] = r;
		_lights.ambient[ 1 ] = g;
		_lights.ambient[ 2 ] = b;
M
Mr.doob 已提交
2773

M
Mr.doob 已提交
2774 2775 2776 2777
		_lights.directional.length = directionalLength;
		_lights.point.length = pointLength;
		_lights.spot.length = spotLength;
		_lights.hemi.length = hemiLength;
2778

2779 2780
		_lights.shadows.length = shadowsLength;

2781
		_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + hemiLength + ',' + shadowsLength;
2782

M
Mr.doob 已提交
2783
	}
M
Mr.doob 已提交
2784 2785 2786 2787 2788 2789 2790

	// GL state setting

	this.setFaceCulling = function ( cullFace, frontFaceDirection ) {

		if ( cullFace === THREE.CullFaceNone ) {

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

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

			}

2819
			state.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
2820 2821 2822 2823 2824 2825 2826 2827 2828

		}

	};

	// Textures

	function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {

2829 2830
		var extension;

M
Mr.doob 已提交
2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842
		if ( isImagePowerOfTwo ) {

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

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

		} else {

			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
M
Mr.doob 已提交
2843 2844 2845

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

M
Mr.doob 已提交
2846
				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 已提交
2847

2848
			}
M
Mr.doob 已提交
2849 2850 2851 2852

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

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

M
Mr.doob 已提交
2855
				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 已提交
2856

2857
			}
M
Mr.doob 已提交
2858

M
Mr.doob 已提交
2859 2860
		}

2861 2862
		extension = extensions.get( 'EXT_texture_filter_anisotropic' );

2863
		if ( extension ) {
M
Mr.doob 已提交
2864

2865 2866
			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 已提交
2867

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

2870
				_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _this.getMaxAnisotropy() ) );
2871
				properties.get( texture ).__currentAnisotropy = texture.anisotropy;
M
Mr.doob 已提交
2872 2873 2874 2875 2876

			}

		}

M
Mr.doob 已提交
2877
	}
M
Mr.doob 已提交
2878

2879
	function uploadTexture( textureProperties, texture, slot ) {
2880

2881
		if ( textureProperties.__webglInit === undefined ) {
2882

2883
			textureProperties.__webglInit = true;
2884 2885 2886

			texture.addEventListener( 'dispose', onTextureDispose );

2887
			textureProperties.__webglTexture = _gl.createTexture();
2888

2889
			_infoMemory.textures ++;
2890 2891

		}
M
Mr.doob 已提交
2892

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

H
Henri Astre 已提交
2896 2897 2898 2899
		_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
		_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
		_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );

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

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

			texture.image = makePowerOfTwo( texture.image );

		}

H
Henri Astre 已提交
2908
		var image = texture.image,
M
Mr.doob 已提交
2909
		isImagePowerOfTwo = isPowerOfTwo( image ),
H
Henri Astre 已提交
2910 2911
		glFormat = paramThreeToGL( texture.format ),
		glType = paramThreeToGL( texture.type );
M
Mr.doob 已提交
2912

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

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

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

H
Henri Astre 已提交
2919 2920 2921
			// 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 已提交
2922

H
Henri Astre 已提交
2923 2924 2925
			if ( mipmaps.length > 0 && isImagePowerOfTwo ) {

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

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

H
Henri Astre 已提交
2930
				}
M
Mr.doob 已提交
2931

H
Henri Astre 已提交
2932
				texture.generateMipmaps = false;
M
Mr.doob 已提交
2933

H
Henri Astre 已提交
2934
			} else {
M
Mr.doob 已提交
2935

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

H
Henri Astre 已提交
2938
			}
M
Mr.doob 已提交
2939

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

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

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

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

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

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

2952
					} else {
M
Mr.doob 已提交
2953

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

2956
					}
M
Mr.doob 已提交
2957

H
Henri Astre 已提交
2958
				} else {
M
Mr.doob 已提交
2959

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

M
Mr.doob 已提交
2962 2963
				}

H
Henri Astre 已提交
2964 2965
			}

G
gero3 已提交
2966 2967 2968
		} else {

			// regular Texture (image, video, canvas)
H
Henri Astre 已提交
2969 2970 2971 2972 2973 2974

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

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

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

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

				}

H
Henri Astre 已提交
2983
				texture.generateMipmaps = false;
M
Mr.doob 已提交
2984

H
Henri Astre 已提交
2985
			} else {
M
Mr.doob 已提交
2986

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

H
Henri Astre 已提交
2989
			}
M
Mr.doob 已提交
2990

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

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

2995
		textureProperties.__version = texture.version;
M
Mr.doob 已提交
2996

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

2999
	}
M
Mr.doob 已提交
3000

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

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

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

3007
			var image = texture.image;
M
Mr.doob 已提交
3008

3009 3010
			if ( image === undefined ) {

3011
				console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );
3012 3013 3014 3015
				return;

			}

3016
			if ( image.complete === false ) {
M
Mr.doob 已提交
3017

3018
				console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );
3019 3020 3021 3022
				return;

			}

3023
			uploadTexture( textureProperties, texture, slot );
3024

3025
			return;
M
Mr.doob 已提交
3026 3027 3028

		}

B
Ben Adams 已提交
3029
		state.activeTexture( _gl.TEXTURE0 + slot );
3030
		state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
3031

M
Mr.doob 已提交
3032 3033 3034 3035
	};

	function clampToMaxSize ( image, maxSize ) {

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

3038 3039
			// Warning: Scaling through the canvas will only work with images that use
			// premultiplied alpha.
M
Mr.doob 已提交
3040

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

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

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

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

3052 3053 3054
			return canvas;

		}
M
Mr.doob 已提交
3055

3056
		return image;
M
Mr.doob 已提交
3057 3058 3059

	}

M
Mr.doob 已提交
3060 3061 3062 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
	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 已提交
3096 3097
	function setCubeTexture ( texture, slot ) {

3098
		var textureProperties = properties.get( texture );
3099

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

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

3104
				if ( ! textureProperties.__image__webglTextureCube ) {
M
Mr.doob 已提交
3105

3106 3107
					texture.addEventListener( 'dispose', onTextureDispose );

3108
					textureProperties.__image__webglTextureCube = _gl.createTexture();
M
Mr.doob 已提交
3109

3110
					_infoMemory.textures ++;
M
Mr.doob 已提交
3111 3112 3113

				}

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

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

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

				var cubeImage = [];

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

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

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

					} else {

3132
						cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];
M
Mr.doob 已提交
3133 3134 3135 3136 3137 3138

					}

				}

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

				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo );

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

3147
					if ( ! isCompressed ) {
M
Mr.doob 已提交
3148

M
Mr.doob 已提交
3149
						if ( isDataTexture ) {
3150

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

M
Mr.doob 已提交
3153
						} else {
3154

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

M
Mr.doob 已提交
3157 3158
						}

3159
					} else {
3160

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

3163
						for ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {
M
Mr.doob 已提交
3164 3165

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

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

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

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

3173
								} else {
M
Mr.doob 已提交
3174

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

3177
								}
M
Mr.doob 已提交
3178

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

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

3183
							}
M
Mr.doob 已提交
3184

3185
						}
M
Mr.doob 已提交
3186

M
Mr.doob 已提交
3187
					}
M
Mr.doob 已提交
3188

M
Mr.doob 已提交
3189 3190 3191 3192 3193 3194 3195 3196
				}

				if ( texture.generateMipmaps && isImagePowerOfTwo ) {

					_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

				}

3197
				textureProperties.__version = texture.version;
M
Mr.doob 已提交
3198

B
Ben Adams 已提交
3199
				if ( texture.onUpdate ) texture.onUpdate( texture );
M
Mr.doob 已提交
3200 3201 3202

			} else {

B
Ben Adams 已提交
3203
				state.activeTexture( _gl.TEXTURE0 + slot );
3204
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
3205 3206 3207 3208 3209

			}

		}

M
Mr.doob 已提交
3210
	}
M
Mr.doob 已提交
3211 3212 3213

	function setCubeTextureDynamic ( texture, slot ) {

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

M
Mr.doob 已提交
3217
	}
M
Mr.doob 已提交
3218 3219 3220

	// Render targets

3221 3222
	// Setup storage for target texture and bind it to correct framebuffer
	function setupFrameBufferTexture ( framebuffer, renderTarget, attachment, textureTarget ) {
M
Mr.doob 已提交
3223

3224 3225 3226
		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 已提交
3227
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
3228 3229
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
M
Mr.doob 已提交
3230

M
Mr.doob 已提交
3231
	}
M
Mr.doob 已提交
3232

3233 3234
	// Setup storage for internal depth/stencil buffers and bind to correct framebuffer
	function setupRenderBufferStorage ( renderbuffer, renderTarget ) {
M
Mr.doob 已提交
3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249

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

3250
			// FIXME: We don't support !depth !stencil
M
Mr.doob 已提交
3251 3252 3253 3254
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );

		}

3255
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
M
Mr.doob 已提交
3256

M
Mr.doob 已提交
3257
	}
M
Mr.doob 已提交
3258

3259
	// Setup GL resources for a non-texture depth buffer
M
Marius Kintel 已提交
3260
	function setupDepthRenderbuffer( renderTarget ) {
M
Mr.doob 已提交
3261

3262
		var renderTargetProperties = properties.get( renderTarget );
M
Mr.doob 已提交
3263 3264

		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
M
Mr.doob 已提交
3265

3266
		if ( isCube ) {
M
Mr.doob 已提交
3267

3268
			renderTargetProperties.__webglDepthbuffer = [];
M
Mr.doob 已提交
3269

3270
			for ( var i = 0; i < 6; i ++ ) {
M
Mr.doob 已提交
3271

M
Marius Kintel 已提交
3272
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );
3273 3274
				renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();
				setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );
M
Mr.doob 已提交
3275 3276

			}
B
Ben Adams 已提交
3277

M
Mr.doob 已提交
3278
		} else {
M
Mr.doob 已提交
3279

M
Marius Kintel 已提交
3280
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );
3281 3282
			renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
			setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );
M
Mr.doob 已提交
3283

3284
		}
M
Mr.doob 已提交
3285

M
Marius Kintel 已提交
3286
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
M
Mr.doob 已提交
3287

M
Mr.doob 已提交
3288
	}
M
Mr.doob 已提交
3289

3290
	// Set up GL resources for the render target
M
Marius Kintel 已提交
3291
	function setupRenderTarget( renderTarget ) {
M
Mr.doob 已提交
3292

3293 3294
		var renderTargetProperties = properties.get( renderTarget );
		var textureProperties = properties.get( renderTarget.texture );
M
Mr.doob 已提交
3295

3296
		renderTarget.addEventListener( 'dispose', onRenderTargetDispose );
M
Mr.doob 已提交
3297

3298
		textureProperties.__webglTexture = _gl.createTexture();
M
Mr.doob 已提交
3299

3300
		_infoMemory.textures ++;
M
Mr.doob 已提交
3301

3302 3303 3304 3305
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
		var isTargetPowerOfTwo = THREE.Math.isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height );
		var glFormat = paramThreeToGL( renderTarget.texture.format );
		var glType = paramThreeToGL( renderTarget.texture.type );
M
Mr.doob 已提交
3306

3307
		// Setup framebuffer
M
Mr.doob 已提交
3308

3309
		if ( isCube ) {
M
Mr.doob 已提交
3310

3311
			renderTargetProperties.__webglFramebuffer = [];
M
Mr.doob 已提交
3312

3313
			for ( var i = 0; i < 6; i ++ ) {
M
Mr.doob 已提交
3314

3315
				renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();
M
Mr.doob 已提交
3316

3317
			}
M
Mr.doob 已提交
3318

3319
		} else {
M
Mr.doob 已提交
3320

3321
			renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
M
Mr.doob 已提交
3322

3323
		}
M
Mr.doob 已提交
3324

3325
		// Setup color buffer
M
Mr.doob 已提交
3326

3327
		if ( isCube ) {
M
Mr.doob 已提交
3328

3329 3330 3331
			state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
			setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );
			for ( var i = 0; i < 6; i ++ ) {
M
Mr.doob 已提交
3332

3333
				setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
M
Mr.doob 已提交
3334 3335 3336

			}

3337 3338
			if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
			state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
M
Mr.doob 已提交
3339

3340
		} else {
M
Mr.doob 已提交
3341

3342 3343 3344
			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 已提交
3345

3346 3347
			if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
			state.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
3348

3349
		}
M
Mr.doob 已提交
3350

3351
		// Setup depth and stencil buffers
3352

3353
		if ( renderTarget.depthBuffer ) {
M
Mr.doob 已提交
3354

M
Marius Kintel 已提交
3355
			setupDepthRenderbuffer( renderTarget );
M
Mr.doob 已提交
3356

3357
		}
M
Mr.doob 已提交
3358

3359
	}
M
Mr.doob 已提交
3360

3361
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
3362

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

M
Marius Kintel 已提交
3365
			setupRenderTarget( renderTarget );
M
Mr.doob 已提交
3366 3367 3368

		}

3369
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
M
Mr.doob 已提交
3370 3371 3372 3373
		var framebuffer, width, height, vx, vy;

		if ( renderTarget ) {

3374
			var renderTargetProperties = properties.get( renderTarget );
F
Fordy 已提交
3375

M
Mr.doob 已提交
3376 3377
			if ( isCube ) {

3378
				framebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
3379 3380 3381

			} else {

3382
				framebuffer = renderTargetProperties.__webglFramebuffer;
M
Mr.doob 已提交
3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412

			}

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

			vx = 0;
			vy = 0;

		} else {

			framebuffer = null;

			width = _viewportWidth;
			height = _viewportHeight;

			vx = _viewportX;
			vy = _viewportY;

		}

		if ( framebuffer !== _currentFramebuffer ) {

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

			_currentFramebuffer = framebuffer;

		}

M
Mr.doob 已提交
3413 3414 3415 3416 3417 3418 3419
		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 已提交
3420 3421 3422 3423 3424
		_currentWidth = width;
		_currentHeight = height;

	};

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

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

3429
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
3430
			return;
3431

G
gero3 已提交
3432
		}
3433

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

M
Mr.doob 已提交
3436
		if ( framebuffer ) {
3437

G
gero3 已提交
3438
			var restore = false;
3439

M
Mr.doob 已提交
3440
			if ( framebuffer !== _currentFramebuffer ) {
3441

M
Mr.doob 已提交
3442
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
3443

G
gero3 已提交
3444
				restore = true;
3445

G
gero3 已提交
3446
			}
3447

M
Mr.doob 已提交
3448
			try {
3449

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

M
Mr.doob 已提交
3452 3453
				if ( texture.format !== THREE.RGBAFormat
					&& paramThreeToGL( texture.format ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
3454

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

M
Mr.doob 已提交
3458
				}
3459

M
Mr.doob 已提交
3460 3461 3462 3463
				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' ) ) ) {
3464

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

M
Mr.doob 已提交
3468
				}
3469

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

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

M
Mr.doob 已提交
3474
				} else {
M
Mr.doob 已提交
3475

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

				}
M
Mr.doob 已提交
3479

M
Mr.doob 已提交
3480
			} finally {
M
Mr.doob 已提交
3481

M
Mr.doob 已提交
3482 3483 3484
				if ( restore ) {

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

M
Mr.doob 已提交
3486 3487 3488
				}

			}
M
Mr.doob 已提交
3489 3490 3491

		}

M
Mr.doob 已提交
3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502
	};

	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 已提交
3503
	}
M
Mr.doob 已提交
3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516

	// 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 已提交
3517
	}
M
Mr.doob 已提交
3518 3519 3520 3521 3522

	// Map three.js constants to WebGL constants

	function paramThreeToGL ( p ) {

3523 3524
		var extension;

M
Mr.doob 已提交
3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548
		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;

3549 3550 3551 3552 3553 3554 3555 3556
		extension = extensions.get( 'OES_texture_half_float' );

		if ( extension !== null ) {

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

		}

M
Mr.doob 已提交
3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579
		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;

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

3582 3583 3584 3585 3586 3587
		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 已提交
3588 3589 3590

		}

3591 3592 3593
		extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );

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

3595 3596 3597 3598
			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 已提交
3599 3600 3601

		}

3602 3603 3604
		extension = extensions.get( 'EXT_blend_minmax' );

		if ( extension !== null ) {
3605

3606 3607
			if ( p === THREE.MinEquation ) return extension.MIN_EXT;
			if ( p === THREE.MaxEquation ) return extension.MAX_EXT;
3608 3609 3610

		}

M
Mr.doob 已提交
3611 3612
		return 0;

M
Mr.doob 已提交
3613
	}
M
Mr.doob 已提交
3614 3615

};