WebGLRenderer.js 94.4 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,

M
Mr.doob 已提交
22 23
	_precision = parameters.precision !== undefined ? parameters.precision : 'highp',

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

32 33
	_clearColor = new THREE.Color( 0x000000 ),
	_clearAlpha = 0;
M
Mr.doob 已提交
34

M
Mr.doob 已提交
35
	var lights = [];
M
Mr.doob 已提交
36

O
OpenShift guest 已提交
37
	var opaqueObjects = [];
38
	var transparentObjects = [];
39

40 41 42
	var opaqueImmediateObjects = [];
	var transparentImmediateObjects = [];

43 44
	var morphInfluences = new Float32Array( 8 );

M
Mr.doob 已提交
45 46 47
	var sprites = [];
	var lensFlares = [];

M
Mr.doob 已提交
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
	// 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

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

	// morphs

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

	// flags

	this.autoScaleCubemaps = true;

	// internal properties

	var _this = this,

	_programs = [],

	// internal state cache

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

	_usedTextureUnits = 0,

	_viewportX = 0,
	_viewportY = 0,
97 98
	_viewportWidth = _canvas.width,
	_viewportHeight = _canvas.height,
M
Mr.doob 已提交
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
	_currentWidth = 0,
	_currentHeight = 0,

	// frustum

	_frustum = new THREE.Frustum(),

	 // camera matrices cache

	_projScreenMatrix = new THREE.Matrix4(),

	_vector3 = new THREE.Vector3(),

	// light arrays cache

	_direction = new THREE.Vector3(),

	_lightsNeedUpdate = true,

	_lights = {

		ambient: [ 0, 0, 0 ],
G
gero3 已提交
121
		directional: { length: 0, colors: [], positions: [] },
M
Mr.doob 已提交
122 123
		point: { length: 0, colors: [], positions: [], distances: [], decays: [] },
		spot: { length: 0, colors: [], positions: [], distances: [], directions: [], anglesCos: [], exponents: [], decays: [] },
G
gero3 已提交
124
		hemi: { length: 0, skyColors: [], groundColors: [], positions: [] }
M
Mr.doob 已提交
125

126 127
	},

M
Mr.doob 已提交
128 129
	// info

130
	_infoMemory = {
131 132 133 134 135 136 137

		programs: 0,
		geometries: 0,
		textures: 0

	},

138
	_infoRender = {
139 140 141 142 143 144

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

M
Mr.doob 已提交
145 146
	};

M
Mr.doob 已提交
147
	this.info = {
148

M
Mr.doob 已提交
149 150 151 152 153
		render: _infoRender,
		memory: _infoMemory,
		programs: _programs

	};
154

M
Mr.doob 已提交
155 156 157 158
	// initialize

	var _gl;

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

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

			} else {

				throw 'Error creating WebGL context.';

			}
M
Mr.doob 已提交
183 184 185

		}

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

M
Mr.doob 已提交
188 189
	} catch ( error ) {

190
		console.error( 'THREE.WebGLRenderer: ' + error );
M
Mr.doob 已提交
191 192 193

	}

194 195
	var extensions = new THREE.WebGLExtensions( _gl );

196 197
	extensions.get( 'OES_texture_float' );
	extensions.get( 'OES_texture_float_linear' );
198 199
	extensions.get( 'OES_texture_half_float' );
	extensions.get( 'OES_texture_half_float_linear' );
200
	extensions.get( 'OES_standard_derivatives' );
B
Ben Adams 已提交
201
	extensions.get( 'ANGLE_instanced_arrays' );
202

203 204
	if ( extensions.get( 'OES_element_index_uint' ) ) {

205
		THREE.BufferGeometry.MaxIndex = 4294967296;
206 207 208

	}

M
Mr.doob 已提交
209 210
	if ( _logarithmicDepthBuffer ) {

211
		extensions.get( 'EXT_frag_depth' );
M
Mr.doob 已提交
212 213 214

	}

215 216 217 218
	var state = new THREE.WebGLState( _gl, extensions, paramThreeToGL );
	var properties = new THREE.WebGLProperties();
	var objects = new THREE.WebGLObjects( _gl, properties, this.info );

M
Mr.doob 已提交
219 220
	//

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

		if ( _premultipliedAlpha === true ) {

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

		}

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

231
	}
232

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

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

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

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

241
	}
242

243
	function resetGLState() {
244 245 246 247

		_currentProgram = null;
		_currentCamera = null;

248
		_currentGeometryProgram = '';
249 250 251 252
		_currentMaterialId = - 1;

		_lightsNeedUpdate = true;

M
Mr.doob 已提交
253 254
		state.reset();

255
	}
M
Mr.doob 已提交
256 257 258 259

	setDefaultGLState();

	this.context = _gl;
260
	this.extensions = extensions;
M
Mr.doob 已提交
261
	this.state = state;
M
Mr.doob 已提交
262

M
Mr.doob 已提交
263 264
	// shadow map

M
Mr.doob 已提交
265
	var shadowMap = new THREE.WebGLShadowMap( this, lights, objects );
M
Mr.doob 已提交
266

267
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
268

M
Mr.doob 已提交
269 270 271 272 273 274 275
	// GPU capabilities

	var _maxTextures = _gl.getParameter( _gl.MAX_TEXTURE_IMAGE_UNITS );
	var _maxVertexTextures = _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );
	var _maxTextureSize = _gl.getParameter( _gl.MAX_TEXTURE_SIZE );
	var _maxCubemapSize = _gl.getParameter( _gl.MAX_CUBE_MAP_TEXTURE_SIZE );

276 277
	var _supportsVertexTextures = _maxVertexTextures > 0;
	var _supportsBoneTextures = _supportsVertexTextures && extensions.get( 'OES_texture_float' );
B
Ben Adams 已提交
278
	var _supportsInstancedArrays = extensions.get( 'ANGLE_instanced_arrays' );
M
Mr.doob 已提交
279

280
	//
281

M
Mr.doob 已提交
282 283


284
	//
M
Mr.doob 已提交
285

286
	var _maxPrecision = state.getMaxPrecision( _precision );
M
Mr.doob 已提交
287

288
	if ( _maxPrecision !== _precision ) {
M
Mr.doob 已提交
289

290 291
		console.warn( 'THREE.WebGLRenderer:', _precision, 'not supported, using', _maxPrecision, 'instead.' );
		_precision = _maxPrecision;
M
Mr.doob 已提交
292 293 294

	}

M
Mr.doob 已提交
295 296 297 298 299
	// Plugins

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

M
Mr.doob 已提交
300 301 302 303 304 305 306 307
	// API

	this.getContext = function () {

		return _gl;

	};

308 309 310 311 312 313
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

314 315 316 317 318 319
	this.forceContextLoss = function () {

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

	};

M
Mr.doob 已提交
320 321 322 323 324 325
	this.supportsVertexTextures = function () {

		return _supportsVertexTextures;

	};

B
Ben Adams 已提交
326 327
	this.supportsInstancedArrays = function () {

M
Mr.doob 已提交
328
		return _supportsInstancedArrays;
B
Ben Adams 已提交
329 330 331

	};

332
	this.getMaxAnisotropy = ( function () {
M
Mr.doob 已提交
333

334
		var value;
M
Mr.doob 已提交
335

336
		return function getMaxAnisotropy() {
337

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

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

M
Mr.doob 已提交
342
			if ( extension !== null ) {
343

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

M
Mr.doob 已提交
346 347 348 349 350
			} else {

				value = 0;

			}
351 352 353 354 355 356

			return value;

		}

	} )();
M
Mr.doob 已提交
357 358 359 360 361 362 363

	this.getPrecision = function () {

		return _precision;

	};

364 365 366 367 368 369 370 371
	this.getPixelRatio = function () {

		return pixelRatio;

	};

	this.setPixelRatio = function ( value ) {

372
		if ( value !== undefined ) pixelRatio = value;
373 374 375

	};

376 377 378 379 380 381 382 383 384
	this.getSize = function () {

		return {
			width: _width,
			height: _height
		};

	};

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

387 388 389
		_width = width;
		_height = height;

390 391
		_canvas.width = width * pixelRatio;
		_canvas.height = height * pixelRatio;
392

393
		if ( updateStyle !== false ) {
394

G
gero3 已提交
395 396
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
397

G
gero3 已提交
398
		}
M
Mr.doob 已提交
399

400
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
401 402 403 404 405

	};

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

406 407
		_viewportX = x * pixelRatio;
		_viewportY = y * pixelRatio;
M
Mr.doob 已提交
408

409 410
		_viewportWidth = width * pixelRatio;
		_viewportHeight = height * pixelRatio;
M
Mr.doob 已提交
411 412 413 414 415 416 417

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

	};

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

418
		_gl.scissor(
419 420 421 422
			x * pixelRatio,
			y * pixelRatio,
			width * pixelRatio,
			height * pixelRatio
423
		);
M
Mr.doob 已提交
424 425 426

	};

427
	this.enableScissorTest = function ( boolean ) {
M
Mr.doob 已提交
428

M
Mr.doob 已提交
429
		state.setScissorTest( boolean );
M
Mr.doob 已提交
430 431 432 433 434

	};

	// Clearing

M
Mr.doob 已提交
435
	this.getClearColor = function () {
M
Mr.doob 已提交
436

M
Mr.doob 已提交
437
		return _clearColor;
M
Mr.doob 已提交
438 439 440

	};

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

M
Mr.doob 已提交
443
		_clearColor.set( color );
444

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

447
		glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
M
Mr.doob 已提交
448 449 450

	};

M
Mr.doob 已提交
451
	this.getClearAlpha = function () {
M
Mr.doob 已提交
452

M
Mr.doob 已提交
453
		return _clearAlpha;
M
Mr.doob 已提交
454 455 456

	};

M
Mr.doob 已提交
457
	this.setClearAlpha = function ( alpha ) {
M
Mr.doob 已提交
458

M
Mr.doob 已提交
459
		_clearAlpha = alpha;
M
Mr.doob 已提交
460

461
		glClearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
M
Mr.doob 已提交
462 463 464 465 466 467 468 469 470 471 472 473

	};

	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 );
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491

	};

	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 已提交
492 493 494 495 496 497 498 499 500 501

	};

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

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

	};

M
Mr.doob 已提交
502 503
	// Reset

504
	this.resetGLState = resetGLState;
M
Mr.doob 已提交
505

D
dubejf 已提交
506 507 508 509 510 511
	this.dispose = function() {

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

	};

M
Mr.doob 已提交
512
	// Events
M
Mr.doob 已提交
513

D
dubejf 已提交
514 515 516 517 518 519 520 521 522 523 524 525
	function onContextLost( event ) {

		event.preventDefault();

		resetGLState();
		setDefaultGLState();

		objects.clear();
		properties.clear();

	};

526
	function onTextureDispose( event ) {
M
Mr.doob 已提交
527 528 529 530 531 532 533

		var texture = event.target;

		texture.removeEventListener( 'dispose', onTextureDispose );

		deallocateTexture( texture );

534
		_infoMemory.textures --;
M
Mr.doob 已提交
535 536


537
	}
M
Mr.doob 已提交
538

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

		var renderTarget = event.target;

		renderTarget.removeEventListener( 'dispose', onRenderTargetDispose );

		deallocateRenderTarget( renderTarget );

547
		_infoMemory.textures --;
M
Mr.doob 已提交
548

549
	}
M
Mr.doob 已提交
550

551
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
552 553 554 555 556 557 558

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

559
	}
M
Mr.doob 已提交
560 561 562

	// Buffer deallocation

563
	function deallocateTexture( texture ) {
M
Mr.doob 已提交
564

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

567
		if ( texture.image && textureProperties.__image__webglTextureCube ) {
M
Mr.doob 已提交
568 569 570

			// cube texture

571
			_gl.deleteTexture( textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
572

573 574 575 576
		} else {

			// 2D texture

577
			if ( textureProperties.__webglInit === undefined ) return;
578

579
			_gl.deleteTexture( textureProperties.__webglTexture );
580

M
Mr.doob 已提交
581 582
		}

583
		// remove all webgl properties
584
		properties.delete( texture );
585

586
	}
M
Mr.doob 已提交
587

588
	function deallocateRenderTarget( renderTarget ) {
M
Mr.doob 已提交
589

590
		var renderTargetProperties = properties.get( renderTarget );
M
Mr.doob 已提交
591

592
		if ( ! renderTarget || renderTargetProperties.__webglTexture === undefined ) return;
M
Mr.doob 已提交
593

594
		_gl.deleteTexture( renderTargetProperties.__webglTexture );
M
Mr.doob 已提交
595

M
Mr.doob 已提交
596 597 598 599
		if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {

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

600 601
				_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );
				_gl.deleteRenderbuffer( renderTargetProperties.__webglRenderbuffer[ i ] );
M
Mr.doob 已提交
602 603 604 605 606

			}

		} else {

607 608
			_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );
			_gl.deleteRenderbuffer( renderTargetProperties.__webglRenderbuffer );
M
Mr.doob 已提交
609 610 611

		}

D
Daosheng Mu 已提交
612
		properties.delete( renderTarget );
M
Mr.doob 已提交
613

614
	}
M
Mr.doob 已提交
615

616
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
617

618 619 620 621
		releaseMaterialProgramReference( material );

		properties.delete( material );

622
	}
623 624


625
	function releaseMaterialProgramReference( material ) {
626

627
		var program = properties.get( material ).program.program;
M
Mr.doob 已提交
628 629 630 631 632

		if ( program === undefined ) return;

		material.program = undefined;

633
		for ( var i = 0, n = _programs.length; i !== n; ++ i ) {
M
Mr.doob 已提交
634

635
			var programInfo = _programs[ i ];
M
Mr.doob 已提交
636 637 638

			if ( programInfo.program === program ) {

639
				var newReferenceCount = -- programInfo.usedTimes;
M
Mr.doob 已提交
640

641
				if ( newReferenceCount === 0 ) {
M
Mr.doob 已提交
642

643 644 645
					// the last meterial that has been using the program let
					// go of it, so remove it from the (unordered) _programs
					// set and deallocate the GL resource
M
Mr.doob 已提交
646

647
					var newLength = n - 1;
M
Mr.doob 已提交
648

649 650
					_programs[ i ] = _programs[ newLength ];
					_programs.pop();
M
Mr.doob 已提交
651

652
					_gl.deleteProgram( program );
M
Mr.doob 已提交
653

654
					_infoMemory.programs = newLength;
M
Mr.doob 已提交
655

656
				}
M
Mr.doob 已提交
657

658
				break;
M
Mr.doob 已提交
659

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

		}

664
	}
M
Mr.doob 已提交
665 666 667 668 669

	// Buffer rendering

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

670
		state.initAttributes();
671

672
		var buffers = properties.get( object );
673

674 675 676 677
		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 已提交
678

679
		var attributes = program.getAttributes();
680

M
Mr.doob 已提交
681 682
		if ( object.hasPositions ) {

683
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
M
Mr.doob 已提交
684
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
685

686 687
			state.enableAttribute( attributes.position );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
688 689 690 691 692

		}

		if ( object.hasNormals ) {

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

M
Mr.doob 已提交
695
			if ( material instanceof THREE.MeshPhongMaterial === false && material.shading === THREE.FlatShading ) {
M
Mr.doob 已提交
696 697 698 699 700 701

				var nx, ny, nz,
					nax, nbx, ncx, nay, nby, ncy, naz, nbz, ncz,
					normalArray,
					i, il = object.count * 3;

702
				for ( i = 0; i < il; i += 9 ) {
M
Mr.doob 已提交
703 704 705

					normalArray = object.normalArray;

M
Mr.doob 已提交
706 707 708
					nax = normalArray[ i ];
					nay = normalArray[ i + 1 ];
					naz = normalArray[ i + 2 ];
M
Mr.doob 已提交
709

M
Mr.doob 已提交
710 711 712
					nbx = normalArray[ i + 3 ];
					nby = normalArray[ i + 4 ];
					nbz = normalArray[ i + 5 ];
M
Mr.doob 已提交
713

M
Mr.doob 已提交
714 715 716
					ncx = normalArray[ i + 6 ];
					ncy = normalArray[ i + 7 ];
					ncz = normalArray[ i + 8 ];
M
Mr.doob 已提交
717 718 719 720 721

					nx = ( nax + nbx + ncx ) / 3;
					ny = ( nay + nby + ncy ) / 3;
					nz = ( naz + nbz + ncz ) / 3;

G
gero3 已提交
722
					normalArray[ i ] = nx;
M
Mr.doob 已提交
723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738
					normalArray[ i + 1 ] = ny;
					normalArray[ i + 2 ] = nz;

					normalArray[ i + 3 ] = nx;
					normalArray[ i + 4 ] = ny;
					normalArray[ i + 5 ] = nz;

					normalArray[ i + 6 ] = nx;
					normalArray[ i + 7 ] = ny;
					normalArray[ i + 8 ] = nz;

				}

			}

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

740
			state.enableAttribute( attributes.normal );
741

742
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
743 744 745 746 747

		}

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

748
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
M
Mr.doob 已提交
749
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
750

751
			state.enableAttribute( attributes.uv );
752

753
			_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
754 755 756 757 758

		}

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

759
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
M
Mr.doob 已提交
760
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
761

762
			state.enableAttribute( attributes.color );
763

764
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
765 766 767

		}

768
		state.disableUnusedAttributes();
769

M
Mr.doob 已提交
770 771 772 773 774 775
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

776
	this.renderBufferDirect = function ( camera, lights, fog, geometry, material, object ) {
M
Mr.doob 已提交
777 778 779 780 781

		setMaterial( material );

		var program = setProgram( camera, lights, fog, material, object );

M
Mr.doob 已提交
782 783
		var updateBuffers = false;
		var geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;
M
Mr.doob 已提交
784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814

		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;

			}

815 816
			var morphAttributes = geometry.morphAttributes;

M
Mr.doob 已提交
817 818 819 820 821 822 823
			for ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {

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

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

824
					var index = influence[ 1 ];
M
Mr.doob 已提交
825

826 827
					if ( material.morphTargets === true ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );
					if ( material.morphNormals === true ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );
M
Mr.doob 已提交
828 829 830

				} else {

831 832
					if ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );
					if ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );
M
Mr.doob 已提交
833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851

				}

			}

			var uniforms = program.getUniforms();

			if ( uniforms.morphTargetInfluences !== null ) {

				_gl.uniform1fv( uniforms.morphTargetInfluences, morphInfluences );

			}

			updateBuffers = true;

		}

		if ( object instanceof THREE.Mesh ) {

852
			renderMesh( material, geometry, program, updateBuffers );
M
Mr.doob 已提交
853 854 855

		} else if ( object instanceof THREE.Line ) {

856
			renderLine( material, geometry, object, program, updateBuffers );
M
Mr.doob 已提交
857 858 859

		} else if ( object instanceof THREE.PointCloud ) {

860
			renderPointCloud( material, geometry, program, updateBuffers );
M
Mr.doob 已提交
861 862 863 864 865

		}

	};

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

M
Mr.doob 已提交
868
		var extension;
B
Ben Adams 已提交
869

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

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

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

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

M
Mr.doob 已提交
879 880 881
			}

		}
B
Ben Adams 已提交
882

883 884
		state.initAttributes();

885
		var geometryAttributes = geometry.attributes;
886

887
		var programAttributes = program.getAttributes();
888

889
		var materialDefaultAttributeValues = material.defaultAttributeValues;
890

891
		for ( var name in programAttributes ) {
892

893
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
894

M
Mr.doob 已提交
895
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
896

897
				var geometryAttribute = geometryAttributes[ name ];
898

M
Mr.doob 已提交
899
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
900

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

903
					var size = geometryAttribute.itemSize;
G
gero3 已提交
904
					var buffer = objects.getAttributeBuffer( geometryAttribute );
905

B
Ben Adams 已提交
906
					if ( geometryAttribute instanceof THREE.InterleavedBufferAttribute ) {
907

M
Mr.doob 已提交
908 909 910 911
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

912
						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
M
Mr.doob 已提交
913
						_gl.vertexAttribPointer( programAttribute, size, _gl.FLOAT, false, stride * data.array.BYTES_PER_ELEMENT, ( startIndex * stride + offset ) * data.array.BYTES_PER_ELEMENT );
914

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

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

919
								console.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferAttribute but hardware does not support extension ANGLE_instanced_arrays.' );
M
Mr.doob 已提交
920
								return;
B
Ben Adams 已提交
921

M
Mr.doob 已提交
922
							}
B
Ben Adams 已提交
923

M
Mr.doob 已提交
924
							extension.vertexAttribDivisorANGLE( programAttribute, data.meshPerAttribute );
B
Ben Adams 已提交
925

M
Mr.doob 已提交
926
							if ( geometry.maxInstancedCount === undefined ) {
927

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

M
Mr.doob 已提交
930
							}
B
Ben Adams 已提交
931

M
Mr.doob 已提交
932
						}
B
Ben Adams 已提交
933

B
Ben Adams 已提交
934 935
					} else {

936
						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
M
Mr.doob 已提交
937
						_gl.vertexAttribPointer( programAttribute, size, _gl.FLOAT, false, 0, startIndex * size * 4 ); // 4 bytes per Float32
B
Ben Adams 已提交
938

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

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

943
								console.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferAttribute but hardware does not support extension ANGLE_instanced_arrays.' );
M
Mr.doob 已提交
944
								return;
B
Ben Adams 已提交
945

M
Mr.doob 已提交
946
							}
B
Ben Adams 已提交
947

M
Mr.doob 已提交
948
							extension.vertexAttribDivisorANGLE( programAttribute, geometryAttribute.meshPerAttribute );
B
Ben Adams 已提交
949

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

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

M
Mr.doob 已提交
954
							}
B
Ben Adams 已提交
955

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

					}
M
Mr.doob 已提交
959

960 961
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
962
					var value = materialDefaultAttributeValues[ name ];
963

964
					if ( value !== undefined ) {
M
Mr.doob 已提交
965

966
						switch ( value.length ) {
M
Mr.doob 已提交
967

968 969 970
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
971

972 973 974
							case 3:
								_gl.vertexAttrib3fv( programAttribute, value );
								break;
M
Mr.doob 已提交
975

976 977 978
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
979

980 981
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
982 983

						}
M
Mr.doob 已提交
984 985 986 987 988 989 990 991

					}

				}

			}

		}
992

993
		state.disableUnusedAttributes();
994

M
Mr.doob 已提交
995 996
	}

997
	function renderMesh( material, geometry, program, updateBuffers ) {
998

999 1000 1001 1002 1003 1004 1005
		var mode = _gl.TRIANGLES;

		if ( material.wireframe === true ) {

			mode = _gl.LINES;
			state.setLineWidth( material.wireframeLinewidth * pixelRatio );

1006 1007 1008 1009 1010 1011 1012 1013 1014
			if ( geometry._wireframe === undefined ) {

				geometry._wireframe = new THREE.WireframeGeometry( geometry );
				objects.updateAttribute( geometry._wireframe.attributes.position );

			}

			geometry = geometry._wireframe;

1015
		}
1016

1017
		var index = geometry.attributes.index;
1018

1019
		if ( index ) {
M
Mr.doob 已提交
1020

1021
			// indexed triangles
1022

1023
			var type, size;
1024

G
gero3 已提交
1025
			var indexBuffer = objects.getAttributeBuffer( index );
1026

1027
			if ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {
1028

1029 1030
				type = _gl.UNSIGNED_INT;
				size = 4;
1031

1032
			} else {
B
Ben Adams 已提交
1033

1034 1035
				type = _gl.UNSIGNED_SHORT;
				size = 2;
B
Ben Adams 已提交
1036

1037
			}
1038

D
dubejf 已提交
1039
			var offsets = geometry.drawcalls;
B
Ben Adams 已提交
1040

1041
			if ( offsets.length === 0 ) {
1042

1043
				if ( updateBuffers ) {
B
Ben Adams 已提交
1044

1045
					setupVertexAttributes( material, program, geometry, 0 );
1046
					_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, indexBuffer );
1047 1048 1049 1050

				}

				if ( geometry instanceof THREE.InstancedBufferGeometry && geometry.maxInstancedCount > 0 ) {
B
Ben Adams 已提交
1051

1052 1053 1054 1055
					var extension = extensions.get( 'ANGLE_instanced_arrays' );

					if ( extension === null ) {

1056
						console.error( 'THREE.WebGLRenderer.renderMesh: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
1057
						return;
B
Ben Adams 已提交
1058 1059

					}
1060

1061
					extension.drawElementsInstancedANGLE( mode, index.array.length, type, 0, geometry.maxInstancedCount ); // Draw the instanced meshes
1062

1063
				} else {
M
Mr.doob 已提交
1064

1065
					_gl.drawElements( mode, index.array.length, type, 0 );
M
Mr.doob 已提交
1066

1067
				}
1068 1069 1070
				_infoRender.calls ++;
				_infoRender.vertices += index.array.length; // not really true, here vertices can be shared
				_infoRender.faces += index.array.length / 3;
M
Mr.doob 已提交
1071

1072
			} else {
M
Mr.doob 已提交
1073

1074 1075 1076
				// if there is more than 1 chunk
				// must set attribute pointers to use new offsets for each chunk
				// even if geometry and materials didn't change
M
Mr.doob 已提交
1077

1078
				updateBuffers = true;
1079

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

1082
					var startIndex = offsets[ i ].index;
M
Mr.doob 已提交
1083

1084
					if ( updateBuffers ) {
M
Mr.doob 已提交
1085

1086
						setupVertexAttributes( material, program, geometry, startIndex );
1087
						_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, indexBuffer );
B
Ben Adams 已提交
1088

1089
					}
B
Ben Adams 已提交
1090

1091
					// render indexed triangles
B
Ben Adams 已提交
1092

G
gero3 已提交
1093
					if ( geometry instanceof THREE.InstancedBufferGeometry && offsets[ i ].instances > 0 ) {
B
Ben Adams 已提交
1094

1095
						var extension = extensions.get( 'ANGLE_instanced_arrays' );
B
Ben Adams 已提交
1096

1097
						if ( extension === null ) {
B
Ben Adams 已提交
1098

1099
							console.error( 'THREE.WebGLRenderer.renderMesh: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
1100
							return;
M
Mr.doob 已提交
1101

B
Ben Adams 已提交
1102
						}
M
Mr.doob 已提交
1103

G
gero3 已提交
1104
						extension.drawElementsInstancedANGLE( mode, offsets[ i ].count, type, offsets[ i ].start * size, offsets[ i ].count, type, offsets[ i ].instances ); // Draw the instanced meshes
1105 1106 1107 1108

					} else {

						_gl.drawElements( mode, offsets[ i ].count, type, offsets[ i ].start * size );
M
Mr.doob 已提交
1109

1110
					}
M
Mr.doob 已提交
1111

1112 1113 1114
					_infoRender.calls ++;
					_infoRender.vertices += offsets[ i ].count; // not really true, here vertices can be shared
					_infoRender.faces += offsets[ i ].count / 3;
1115

M
Mr.doob 已提交
1116 1117
				}

1118
			}
M
Mr.doob 已提交
1119

1120
		} else {
1121

1122
			// non-indexed triangles
1123

D
dubejf 已提交
1124
			var offsets = geometry.drawcalls;
1125 1126

			if ( offsets.length === 0 ) {
M
Mr.doob 已提交
1127

1128
				if ( updateBuffers ) {
M
Mr.doob 已提交
1129

1130
					setupVertexAttributes( material, program, geometry, 0 );
M
Mr.doob 已提交
1131

1132
				}
1133

M
Mr.doob 已提交
1134
				var position = geometry.attributes.position;
M
Mr.doob 已提交
1135

1136
				// render non-indexed triangles
B
Ben Adams 已提交
1137

1138
				if ( geometry instanceof THREE.InstancedBufferGeometry && geometry.maxInstancedCount > 0 ) {
B
Ben Adams 已提交
1139

1140
					var extension = extensions.get( 'ANGLE_instanced_arrays' );
B
Ben Adams 已提交
1141

1142
					if ( extension === null ) {
M
Mr.doob 已提交
1143

1144
						console.error( 'THREE.WebGLRenderer.renderMesh: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
1145
						return;
M
Mr.doob 已提交
1146

1147 1148 1149 1150
					}

					if ( position instanceof THREE.InterleavedBufferAttribute ) {

D
dubejf 已提交
1151
						extension.drawArraysInstancedANGLE( mode, 0, position.data.count, geometry.maxInstancedCount ); // Draw the instanced meshes
B
Ben Adams 已提交
1152

1153 1154
					} else {

D
dubejf 已提交
1155
						extension.drawArraysInstancedANGLE( mode, 0, position.count, geometry.maxInstancedCount ); // Draw the instanced meshes
B
Ben Adams 已提交
1156

1157
					}
B
Ben Adams 已提交
1158

1159
				} else {
B
Ben Adams 已提交
1160

1161 1162
					if ( position instanceof THREE.InterleavedBufferAttribute ) {

D
dubejf 已提交
1163
						_gl.drawArrays( mode, 0, position.data.count );
1164 1165 1166

					} else {

D
dubejf 已提交
1167
						_gl.drawArrays( mode, 0, position.count );
1168 1169

					}
B
Ben Adams 已提交
1170

1171
				}
B
Ben Adams 已提交
1172

G
gero3 已提交
1173
				_infoRender.calls ++;
1174 1175
				_infoRender.vertices += position.count;
				_infoRender.faces += position.array.length / 3;
1176

1177
			} else {
B
Ben Adams 已提交
1178

1179 1180 1181
				// if there is more than 1 chunk
				// must set attribute pointers to use new offsets for each chunk
				// even if geometry and materials didn't change
B
Ben Adams 已提交
1182

B
Ben Adams 已提交
1183
				if ( updateBuffers ) {
M
Mr.doob 已提交
1184

B
Ben Adams 已提交
1185
					setupVertexAttributes( material, program, geometry, 0 );
1186

B
Ben Adams 已提交
1187
				}
M
Mr.doob 已提交
1188

G
gero3 已提交
1189
				for ( var i = 0, il = offsets.length; i < il; i ++ ) {
M
Mr.doob 已提交
1190

1191 1192 1193 1194
					// render non-indexed triangles

					if ( geometry instanceof THREE.InstancedBufferGeometry ) {

1195
						console.error( 'THREE.WebGLRenderer.renderMesh: cannot use drawCalls with THREE.InstancedBufferGeometry.' );
1196 1197 1198 1199
						return;

					} else {

B
Ben Adams 已提交
1200
						_gl.drawArrays( mode, offsets[ i ].start, offsets[ i ].count );
1201 1202 1203

					}

G
gero3 已提交
1204
					_infoRender.calls ++;
1205 1206
					_infoRender.vertices += offsets[ i ].count;
					_infoRender.faces += ( offsets[ i ].count  ) / 3;
1207 1208

				}
G
gero3 已提交
1209

1210
			}
G
gero3 已提交
1211

1212
		}
1213

M
Mr.doob 已提交
1214
	}
M
Mr.doob 已提交
1215

1216
	function renderLine( material, geometry, object, program, updateBuffers ) {
M
Mr.doob 已提交
1217

1218
		var mode = object instanceof THREE.LineSegments ? _gl.LINES : _gl.LINE_STRIP;
M
Mr.doob 已提交
1219 1220 1221 1222 1223

		// In case user is not using Line*Material by mistake
		var lineWidth = material.linewidth !== undefined ? material.linewidth : 1;

		state.setLineWidth( lineWidth * pixelRatio );
1224

1225
		var index = geometry.attributes.index;
M
mschuetz 已提交
1226

1227
		if ( index ) {
M
mschuetz 已提交
1228

M
Mr.doob 已提交
1229
			// indexed lines
M
mschuetz 已提交
1230

1231
			var type, size;
M
mschuetz 已提交
1232

G
gero3 已提交
1233
			var indexBuffer = objects.getAttributeBuffer( index );
1234

1235
			if ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {
M
Mr.doob 已提交
1236

1237 1238
				type = _gl.UNSIGNED_INT;
				size = 4;
M
mschuetz 已提交
1239

1240
			} else {
M
mschuetz 已提交
1241

1242 1243
				type = _gl.UNSIGNED_SHORT;
				size = 2;
M
mschuetz 已提交
1244

1245
			}
M
mschuetz 已提交
1246

D
dubejf 已提交
1247
			var offsets = geometry.drawcalls;
M
mschuetz 已提交
1248

1249
			if ( offsets.length === 0 ) {
M
mschuetz 已提交
1250

1251
				if ( updateBuffers ) {
M
mschuetz 已提交
1252

1253
					setupVertexAttributes( material, program, geometry, 0 );
1254
					_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, indexBuffer );
M
mschuetz 已提交
1255

1256
				}
M
mschuetz 已提交
1257

M
Mr.doob 已提交
1258
				_gl.drawElements( mode, index.array.length, type, 0 ); // 2 bytes per Uint16Array
1259

1260 1261
				_infoRender.calls ++;
				_infoRender.vertices += index.array.length; // not really true, here vertices can be shared
M
mschuetz 已提交
1262

1263
			} else {
M
mschuetz 已提交
1264

1265 1266 1267
				// if there is more than 1 chunk
				// must set attribute pointers to use new offsets for each chunk
				// even if geometry and materials didn't change
M
mschuetz 已提交
1268

1269
				if ( offsets.length > 1 ) updateBuffers = true;
M
mschuetz 已提交
1270

1271
				for ( var i = 0, il = offsets.length; i < il; i ++ ) {
M
mschuetz 已提交
1272

1273
					var startIndex = offsets[ i ].index;
M
mschuetz 已提交
1274

1275
					if ( updateBuffers ) {
M
mschuetz 已提交
1276

1277
						setupVertexAttributes( material, program, geometry, startIndex );
1278
						_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, indexBuffer );
M
mschuetz 已提交
1279

1280
					}
M
mschuetz 已提交
1281

M
Mr.doob 已提交
1282
					// render indexed lines
M
mschuetz 已提交
1283

M
Mr.doob 已提交
1284
					_gl.drawElements( mode, offsets[ i ].count, type, offsets[ i ].start * size ); // 2 bytes per Uint16Array
M
mschuetz 已提交
1285

1286 1287
					_infoRender.calls ++;
					_infoRender.vertices += offsets[ i ].count; // not really true, here vertices can be shared
M
mschuetz 已提交
1288

M
mschuetz 已提交
1289
				}
M
mschuetz 已提交
1290

1291
			}
M
Mr.doob 已提交
1292

1293
		} else {
M
mschuetz 已提交
1294

M
Mr.doob 已提交
1295
			// non-indexed lines
M
mschuetz 已提交
1296

1297
			if ( updateBuffers ) {
M
mschuetz 已提交
1298

1299
				setupVertexAttributes( material, program, geometry, 0 );
M
mschuetz 已提交
1300

1301
			}
M
mschuetz 已提交
1302

1303
			var position = geometry.attributes.position;
D
dubejf 已提交
1304
			var offsets = geometry.drawcalls;
M
mschuetz 已提交
1305

1306
			if ( offsets.length === 0 ) {
1307

1308
				_gl.drawArrays( mode, 0, position.array.length / 3 );
1309

1310 1311
				_infoRender.calls ++;
				_infoRender.vertices += position.array.length / 3;
1312

1313
			} else {
1314

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

1317
					_gl.drawArrays( mode, offsets[ i ].index, offsets[ i ].count );
1318

1319 1320
					_infoRender.calls ++;
					_infoRender.vertices += offsets[ i ].count;
1321 1322

				}
M
Mr.doob 已提交
1323

M
mschuetz 已提交
1324
			}
M
Mr.doob 已提交
1325

1326
		}
M
Mr.doob 已提交
1327

M
Mr.doob 已提交
1328
	}
1329

1330
	function renderPointCloud( material, geometry, program, updateBuffers ) {
M
Mr.doob 已提交
1331

M
Mr.doob 已提交
1332
		var mode = _gl.POINTS;
1333

1334
		var index = geometry.attributes.index;
M
Mr.doob 已提交
1335

1336
		if ( index ) {
M
Mr.doob 已提交
1337

M
Mr.doob 已提交
1338
			// indexed points
1339

1340
			var type, size;
1341

1342
			var indexBuffer = objects.getAttributeBuffer( index );
1343

M
Mr.doob 已提交
1344
			if ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {
1345

1346 1347
				type = _gl.UNSIGNED_INT;
				size = 4;
1348

1349
			} else {
1350

1351 1352
				type = _gl.UNSIGNED_SHORT;
				size = 2;
M
Mr.doob 已提交
1353

1354
			}
M
Mr.doob 已提交
1355

D
dubejf 已提交
1356
			var offsets = geometry.drawcalls;
M
Mr.doob 已提交
1357

1358
			if ( offsets.length === 0 ) {
M
Mr.doob 已提交
1359

1360
				if ( updateBuffers ) {
M
Mr.doob 已提交
1361

1362
					setupVertexAttributes( material, program, geometry, 0 );
1363
					_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, indexBuffer );
1364

1365
				}
1366

G
gero3 已提交
1367
				_gl.drawElements( mode, index.array.length, type, 0 );
1368

1369 1370
				_infoRender.calls ++;
				_infoRender.points += index.array.length;
M
Mr.doob 已提交
1371

1372
			} else {
1373

1374 1375 1376
				// if there is more than 1 chunk
				// must set attribute pointers to use new offsets for each chunk
				// even if geometry and materials didn't change
1377

1378
				if ( offsets.length > 1 ) updateBuffers = true;
1379

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

1382
					var startIndex = offsets[ i ].index;
1383

1384
					if ( updateBuffers ) {
1385

1386
						setupVertexAttributes( material, program, geometry, startIndex );
1387
						_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, indexBuffer );
1388

1389
					}
1390

M
Mr.doob 已提交
1391
					// render indexed points
1392

M
Mr.doob 已提交
1393
					_gl.drawElements( mode, offsets[ i ].count, type, offsets[ i ].start * size );
1394

1395 1396
					_infoRender.calls ++;
					_infoRender.points += offsets[ i ].count;
1397 1398 1399

				}

1400
			}
1401

1402
		} else {
M
Mr.doob 已提交
1403

M
Mr.doob 已提交
1404
			// non-indexed points
1405

1406
			if ( updateBuffers ) {
1407

1408
				setupVertexAttributes( material, program, geometry, 0 );
1409

1410
			}
1411

1412
			var position = geometry.attributes.position;
D
dubejf 已提交
1413
			var offsets = geometry.drawcalls;
1414

1415
			if ( offsets.length === 0 ) {
1416

1417
				_gl.drawArrays( mode, 0, position.array.length / 3 );
1418

1419 1420
				_infoRender.calls ++;
				_infoRender.points += position.array.length / 3;
1421

1422
			} else {
1423

1424
				for ( var i = 0, il = offsets.length; i < il; i ++ ) {
1425

1426
					_gl.drawArrays( mode, offsets[ i ].index, offsets[ i ].count );
1427

1428 1429
					_infoRender.calls ++;
					_infoRender.points += offsets[ i ].count;
1430 1431

				}
M
Mr.doob 已提交
1432

1433
			}
M
Mr.doob 已提交
1434

1435
		}
M
Mr.doob 已提交
1436

M
Mr.doob 已提交
1437
	}
M
Mr.doob 已提交
1438 1439 1440

	// Sorting

1441 1442 1443 1444 1445 1446
	function numericalSort ( a, b ) {

		return b[ 0 ] - a[ 0 ];

	}

M
Mr.doob 已提交
1447 1448
	function painterSortStable ( a, b ) {

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

U
unconed 已提交
1451
			return a.object.renderOrder - b.object.renderOrder;
1452

1453
		} else if ( a.object.material.id !== b.object.material.id ) {
M
Mr.doob 已提交
1454

1455
			return a.object.material.id - b.object.material.id;
1456 1457

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

M
Mr.doob 已提交
1459
			return a.z - b.z;
M
Mr.doob 已提交
1460 1461 1462

		} else {

1463
			return a.id - b.id;
M
Mr.doob 已提交
1464 1465 1466

		}

1467
	}
M
Mr.doob 已提交
1468

1469 1470
	function reversePainterSortStable ( a, b ) {

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

U
unconed 已提交
1473
			return a.object.renderOrder - b.object.renderOrder;
1474 1475

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

M
Mr.doob 已提交
1477
			return b.z - a.z;
1478 1479 1480 1481 1482 1483 1484

		} else {

			return a.id - b.id;

		}

1485
	}
1486

M
Mr.doob 已提交
1487 1488 1489 1490 1491 1492
	// Rendering

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

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

1493
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1494 1495 1496 1497
			return;

		}

M
Mr.doob 已提交
1498
		var fog = scene.fog;
M
Mr.doob 已提交
1499 1500 1501

		// reset caching for this frame

1502
		_currentGeometryProgram = '';
1503
		_currentMaterialId = - 1;
1504
		_currentCamera = null;
M
Mr.doob 已提交
1505 1506 1507 1508
		_lightsNeedUpdate = true;

		// update scene graph

1509
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1510 1511 1512

		// update camera matrices and frustum

1513
		if ( camera.parent === null ) camera.updateMatrixWorld();
M
Mr.doob 已提交
1514 1515 1516 1517 1518 1519

		camera.matrixWorldInverse.getInverse( camera.matrixWorld );

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

M
Mr.doob 已提交
1520
		lights.length = 0;
1521

1522 1523
		opaqueObjects.length = 0;
		transparentObjects.length = 0;
M
Mr.doob 已提交
1524

1525 1526 1527
		opaqueImmediateObjects.length = 0;
		transparentImmediateObjects.length = 0;

M
Mr.doob 已提交
1528 1529 1530
		sprites.length = 0;
		lensFlares.length = 0;

1531
		projectObject( scene );
M
Mr.doob 已提交
1532

M
Mr.doob 已提交
1533
		if ( _this.sortObjects === true ) {
1534 1535 1536

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

1538 1539
		}

M
Mr.doob 已提交
1540
		//
M
Mr.doob 已提交
1541

1542
		shadowMap.render( scene, camera );
M
Mr.doob 已提交
1543 1544 1545

		//

1546 1547 1548 1549
		_infoRender.calls = 0;
		_infoRender.vertices = 0;
		_infoRender.faces = 0;
		_infoRender.points = 0;
M
Mr.doob 已提交
1550 1551 1552 1553 1554 1555 1556 1557 1558

		this.setRenderTarget( renderTarget );

		if ( this.autoClear || forceClear ) {

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

		}

1559
		//
M
Mr.doob 已提交
1560 1561 1562

		if ( scene.overrideMaterial ) {

1563
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1564

1565 1566
			renderObjects( opaqueObjects, camera, lights, fog, overrideMaterial );
			renderObjects( transparentObjects, camera, lights, fog, overrideMaterial );
1567 1568 1569

			renderObjectsImmediate( opaqueImmediateObjects, camera, lights, fog, overrideMaterial );
			renderObjectsImmediate( transparentImmediateObjects, camera, lights, fog, overrideMaterial );
M
Mr.doob 已提交
1570 1571 1572 1573 1574

		} else {

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

M
Mr.doob 已提交
1575
			state.setBlending( THREE.NoBlending );
M
Mr.doob 已提交
1576

1577 1578
			renderObjects( opaqueObjects, camera, lights, fog );
			renderObjectsImmediate( opaqueImmediateObjects, camera, lights, fog );
M
Mr.doob 已提交
1579 1580 1581

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

1582 1583
			renderObjects( transparentObjects, camera, lights, fog );
			renderObjectsImmediate( transparentImmediateObjects, camera, lights, fog );
M
Mr.doob 已提交
1584 1585 1586 1587 1588

		}

		// custom render plugins (post pass)

M
Mr.doob 已提交
1589 1590
		spritePlugin.render( scene, camera );
		lensFlarePlugin.render( scene, camera, _currentWidth, _currentHeight );
M
Mr.doob 已提交
1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601

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

		if ( renderTarget && renderTarget.generateMipmaps && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {

			updateRenderTargetMipmap( renderTarget );

		}

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

M
Mr.doob 已提交
1602 1603
		state.setDepthTest( true );
		state.setDepthWrite( true );
1604
		state.setColorWrite( true );
M
Mr.doob 已提交
1605 1606 1607 1608

		// _gl.finish();

	};
M
Mr.doob 已提交
1609

1610
	function projectObject( object ) {
M
Mr.doob 已提交
1611

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

M
Mr.doob 已提交
1614
		if ( object instanceof THREE.Scene || object instanceof THREE.Group ) {
M
Mr.doob 已提交
1615

M
Mr.doob 已提交
1616
			// skip
M
Mr.doob 已提交
1617

M
Mr.doob 已提交
1618
		} else {
B
Ben Adams 已提交
1619

M
Mr.doob 已提交
1620 1621
			// update Skeleton objects
			if ( object instanceof THREE.SkinnedMesh ) {
B
Ben Adams 已提交
1622

M
Mr.doob 已提交
1623
				object.skeleton.update();
B
Ben Adams 已提交
1624

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

M
Mr.doob 已提交
1627
			objects.init( object );
M
Mr.doob 已提交
1628

M
Mr.doob 已提交
1629
			if ( object instanceof THREE.Light ) {
M
Mr.doob 已提交
1630

M
Mr.doob 已提交
1631
				lights.push( object );
M
Mr.doob 已提交
1632

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

M
Mr.doob 已提交
1635
				sprites.push( object );
M
Mr.doob 已提交
1636

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

M
Mr.doob 已提交
1639
				lensFlares.push( object );
1640

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

M
Mr.doob 已提交
1643
				var material = object.material;
1644

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

M
Mr.doob 已提交
1647
					transparentImmediateObjects.push( object );
1648

M
Mr.doob 已提交
1649
				} else {
1650

M
Mr.doob 已提交
1651
					opaqueImmediateObjects.push( object );
1652

M
Mr.doob 已提交
1653
				}
M
Mr.doob 已提交
1654

M
Mr.doob 已提交
1655
			} else {
M
Mr.doob 已提交
1656

M
Mr.doob 已提交
1657
				var webglObject = objects.objects[ object.id ];
M
Mr.doob 已提交
1658

M
Mr.doob 已提交
1659
				if ( webglObject && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {
1660

M
Mr.doob 已提交
1661
					var material = object.material;
1662

1663
					if ( material !== null && material.visible === true ) {
1664

1665
						if ( properties.get( material ) ) {
1666

1667
							material.program = properties.get( material ).program;
1668

1669
						}
1670

1671
						if ( material.transparent ) {
1672

1673
							transparentObjects.push( webglObject );
M
Mr.doob 已提交
1674

1675
						} else {
1676

1677 1678 1679
							opaqueObjects.push( webglObject );

						}
M
Mr.doob 已提交
1680

1681
						if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1682

1683 1684
							_vector3.setFromMatrixPosition( object.matrixWorld );
							_vector3.applyProjection( _projScreenMatrix );
M
Mr.doob 已提交
1685

1686 1687 1688
							webglObject.z = _vector3.z;

						}
O
OpenShift guest 已提交
1689

1690
					}
M
Mr.doob 已提交
1691

1692
				}
M
Mr.doob 已提交
1693

1694
			}
M
Mr.doob 已提交
1695

M
Mr.doob 已提交
1696
		}
M
Mr.doob 已提交
1697

M
Mr.doob 已提交
1698
		var children = object.children;
M
Mr.doob 已提交
1699

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

			projectObject( children[ i ] );
M
Mr.doob 已提交
1703

1704
		}
1705

1706
	}
M
Mr.doob 已提交
1707

1708
	function renderObjects( renderList, camera, lights, fog, overrideMaterial ) {
M
Mr.doob 已提交
1709

M
Mr.doob 已提交
1710
		var material = overrideMaterial;
M
Mr.doob 已提交
1711

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

M
Mr.doob 已提交
1714 1715
			var webglObject = renderList[ i ];
			var object = webglObject.object;
1716
			var geometry = objects.update( object );
M
Mr.doob 已提交
1717

1718
			setupMatrices( object, camera );
M
Mr.doob 已提交
1719

1720
			if ( overrideMaterial === undefined ) material = object.material;
M
Mr.doob 已提交
1721

1722 1723 1724 1725 1726 1727 1728 1729
			if ( material instanceof THREE.MeshFaceMaterial ) {

				var materials = material.materials;

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

					material = materials[ j ];

1730
					if ( material.visible ) {
1731

1732 1733 1734
						_this.renderBufferDirect( camera, lights, fog, geometry, material, object );

					}
1735 1736 1737

				}

1738
			} else {
1739

1740 1741 1742
				_this.renderBufferDirect( camera, lights, fog, geometry, material, object );

			}
M
Mr.doob 已提交
1743 1744 1745

		}

1746
	}
M
Mr.doob 已提交
1747

1748
	function renderObjectsImmediate( renderList, camera, lights, fog, overrideMaterial ) {
M
Mr.doob 已提交
1749

M
Mr.doob 已提交
1750
		var material = overrideMaterial;
M
Mr.doob 已提交
1751

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

1754
			var object = renderList[ i ];
M
Mr.doob 已提交
1755

1756
			setupMatrices( object, camera );
M
Mr.doob 已提交
1757

1758
			if ( overrideMaterial === undefined ) material = object.material;
M
Mr.doob 已提交
1759

1760
			setMaterial( material );
1761

1762
			var program = setProgram( camera, lights, fog, material, object );
M
Mr.doob 已提交
1763

1764
			_currentGeometryProgram = '';
M
Mr.doob 已提交
1765

1766
			object.render( function ( object ) {
M
Mr.doob 已提交
1767

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

1770
			} );
M
Mr.doob 已提交
1771

1772
		}
M
Mr.doob 已提交
1773

1774
	}
M
Mr.doob 已提交
1775 1776 1777

	// Materials

1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788
	var shaderIDs = {
		MeshDepthMaterial: 'depth',
		MeshNormalMaterial: 'normal',
		MeshBasicMaterial: 'basic',
		MeshLambertMaterial: 'lambert',
		MeshPhongMaterial: 'phong',
		LineBasicMaterial: 'basic',
		LineDashedMaterial: 'dashed',
		PointCloudMaterial: 'particle_basic'
	};

1789
	function initMaterial( material, lights, fog, object ) {
M
Mr.doob 已提交
1790

1791
		var materialProperties = properties.get( material );
F
Fordy 已提交
1792

1793
		var shaderID = shaderIDs[ material.type ];
M
Mr.doob 已提交
1794 1795 1796 1797

		// heuristics to create shader parameters according to lights in the scene
		// (not to blow over maxLights budget)

1798 1799 1800
		var maxLightCount = allocateLights( lights );
		var maxShadows = allocateShadows( lights );
		var maxBones = allocateBones( object );
1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813
		var precision = _precision;

		if ( material.precision !== null ) {

			precision = state.getMaxPrecision( material.precision );

			if ( precision !== material.precision ) {

				console.warn( 'THREE.WebGLRenderer.initMaterial:', material.precision, 'not supported, using', precision, 'instead.' );

			}

		}
M
Mr.doob 已提交
1814

1815
		var parameters = {
M
Mr.doob 已提交
1816

1817
			precision: precision,
1818 1819
			supportsVertexTextures: _supportsVertexTextures,

1820 1821
			map: !! material.map,
			envMap: !! material.envMap,
M
Mr.doob 已提交
1822
			envMapMode: material.envMap && material.envMap.mapping,
1823
			lightMap: !! material.lightMap,
1824
			aoMap: !! material.aoMap,
1825
			emissiveMap: !! material.emissiveMap,
1826 1827 1828
			bumpMap: !! material.bumpMap,
			normalMap: !! material.normalMap,
			specularMap: !! material.specularMap,
1829
			alphaMap: !! material.alphaMap,
M
Mr.doob 已提交
1830

1831 1832
			combine: material.combine,

M
Mr.doob 已提交
1833 1834 1835 1836 1837 1838
			vertexColors: material.vertexColors,

			fog: fog,
			useFog: material.fog,
			fogExp: fog instanceof THREE.FogExp2,

1839 1840
			flatShading: material.shading === THREE.FlatShading,

M
Mr.doob 已提交
1841
			sizeAttenuation: material.sizeAttenuation,
1842
			logarithmicDepthBuffer: _logarithmicDepthBuffer,
M
Mr.doob 已提交
1843 1844 1845

			skinning: material.skinning,
			maxBones: maxBones,
1846
			useVertexTexture: _supportsBoneTextures && object && object.skeleton && object.skeleton.useVertexTexture,
M
Mr.doob 已提交
1847 1848 1849

			morphTargets: material.morphTargets,
			morphNormals: material.morphNormals,
1850 1851
			maxMorphTargets: _this.maxMorphTargets,
			maxMorphNormals: _this.maxMorphNormals,
M
Mr.doob 已提交
1852 1853 1854 1855 1856 1857 1858

			maxDirLights: maxLightCount.directional,
			maxPointLights: maxLightCount.point,
			maxSpotLights: maxLightCount.spot,
			maxHemiLights: maxLightCount.hemi,

			maxShadows: maxShadows,
1859 1860 1861
			shadowMapEnabled: shadowMap.enabled && object.receiveShadow && maxShadows > 0,
			shadowMapType: shadowMap.type,
			shadowMapDebug: shadowMap.debug,
M
Mr.doob 已提交
1862 1863 1864 1865 1866 1867 1868 1869

			alphaTest: material.alphaTest,
			metal: material.metal,
			doubleSided: material.side === THREE.DoubleSide,
			flipSided: material.side === THREE.BackSide

		};

1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884
		// Generate code

		var chunks = [];

		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

			chunks.push( material.fragmentShader );
			chunks.push( material.vertexShader );

		}

1885 1886
		if ( material.defines !== undefined ) {

1887
			for ( var name in material.defines ) {
1888

1889 1890
				chunks.push( name );
				chunks.push( material.defines[ name ] );
1891 1892

			}
1893 1894 1895

		}

1896
		for ( var name in parameters ) {
1897

1898 1899
			chunks.push( name );
			chunks.push( parameters[ name ] );
1900 1901 1902 1903

		}

		var code = chunks.join();
T
tschw 已提交
1904
		var programChange = true;
1905

G
gero3 已提交
1906
		if ( ! materialProperties.program ) {
B
Ben Adams 已提交
1907

M
Mr.doob 已提交
1908 1909
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1910

1911
		} else if ( materialProperties.program.code !== code ) {
B
Ben Adams 已提交
1912

M
Mr.doob 已提交
1913
			// changed glsl or parameters
1914
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1915

T
tschw 已提交
1916
		} else if ( shaderID !== undefined ) {
B
Ben Adams 已提交
1917

T
tschw 已提交
1918
			// same glsl and uniform list
T
tschw 已提交
1919 1920
			return;

T
tschw 已提交
1921
		} else {
B
Ben Adams 已提交
1922

T
tschw 已提交
1923 1924
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1925 1926 1927 1928 1929 1930 1931

		}

		if ( shaderID ) {

			var shader = THREE.ShaderLib[ shaderID ];

1932
			materialProperties.__webglShader = {
1933
				name: material.type,
B
Ben Adams 已提交
1934 1935 1936
				uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
				vertexShader: shader.vertexShader,
				fragmentShader: shader.fragmentShader
D
dubejf 已提交
1937
			};
B
Ben Adams 已提交
1938 1939 1940

		} else {

1941
			materialProperties.__webglShader = {
1942
				name: material.type,
B
Ben Adams 已提交
1943 1944 1945
				uniforms: material.uniforms,
				vertexShader: material.vertexShader,
				fragmentShader: material.fragmentShader
D
dubejf 已提交
1946
			};
B
Ben Adams 已提交
1947 1948 1949

		}

1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960
		var program;

		// Check if code has been already compiled

		for ( var p = 0, pl = _programs.length; p < pl; p ++ ) {

			var programInfo = _programs[ p ];

			if ( programInfo.code === code ) {

				program = programInfo;
T
tschw 已提交
1961 1962 1963 1964 1965 1966

				if ( programChange ) {

					program.usedTimes ++;

				}
1967 1968 1969 1970 1971 1972 1973 1974 1975

				break;

			}

		}

		if ( program === undefined ) {

1976
			material.__webglShader = materialProperties.__webglShader;
1977
			program = new THREE.WebGLProgram( _this, code, material, parameters );
1978 1979
			_programs.push( program );

1980
			_infoMemory.programs = _programs.length;
1981 1982 1983

		}

1984
		materialProperties.program = program;
M
Mr.doob 已提交
1985

1986
		var attributes = program.getAttributes();
M
Mr.doob 已提交
1987 1988 1989 1990 1991

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

M
Mr.doob 已提交
1994
				if ( attributes[ 'morphTarget' + i ] >= 0 ) {
M
Mr.doob 已提交
1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

M
Mr.doob 已提交
2010
				if ( attributes[ 'morphNormal' + i ] >= 0 ) {
M
Mr.doob 已提交
2011 2012 2013 2014 2015 2016 2017 2018 2019

					material.numSupportedMorphNormals ++;

				}

			}

		}

2020
		materialProperties.uniformsList = [];
M
Mr.doob 已提交
2021

2022 2023
		var uniformLocations = materialProperties.program.getUniforms();
		for ( var u in materialProperties.__webglShader.uniforms ) {
M
Mr.doob 已提交
2024

2025
			var location = uniformLocations[ u ];
2026 2027

			if ( location ) {
G
gero3 已提交
2028

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

2031
			}
M
Mr.doob 已提交
2032 2033 2034

		}

M
Mr.doob 已提交
2035
	}
M
Mr.doob 已提交
2036

2037 2038
	function setMaterial( material ) {

M
Mr.doob 已提交
2039 2040
		setMaterialFaces( material );

2041 2042
		if ( material.transparent === true ) {

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

2045 2046 2047 2048
		} else {

			state.setBlending( THREE.NoBlending );

2049 2050
		}

B
Ben Adams 已提交
2051
		state.setDepthFunc( material.depthFunc );
M
Mr.doob 已提交
2052 2053
		state.setDepthTest( material.depthTest );
		state.setDepthWrite( material.depthWrite );
2054
		state.setColorWrite( material.colorWrite );
M
Mr.doob 已提交
2055
		state.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
2056 2057 2058

	}

M
Mr.doob 已提交
2059 2060
	function setMaterialFaces( material ) {

2061
		material.side !== THREE.DoubleSide ? state.enable( _gl.CULL_FACE ) : state.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
2062 2063 2064 2065
		state.setFlipSided( material.side === THREE.BackSide );

	}

M
Mr.doob 已提交
2066 2067 2068 2069
	function setProgram( camera, lights, fog, material, object ) {

		_usedTextureUnits = 0;

2070
		var materialProperties = properties.get( material );
2071

2072
		if ( material.needsUpdate || ! materialProperties.program ) {
M
Mr.doob 已提交
2073

2074
			initMaterial( material, lights, fog, object );
M
Mr.doob 已提交
2075 2076 2077 2078
			material.needsUpdate = false;

		}

2079
		var refreshProgram = false;
M
Mr.doob 已提交
2080
		var refreshMaterial = false;
2081
		var refreshLights = false;
M
Mr.doob 已提交
2082

2083
		var program = materialProperties.program,
2084
			p_uniforms = program.getUniforms(),
2085
			m_uniforms = materialProperties.__webglShader.uniforms;
M
Mr.doob 已提交
2086

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

2089 2090
			_gl.useProgram( program.program );
			_currentProgram = program.id;
M
Mr.doob 已提交
2091

2092
			refreshProgram = true;
M
Mr.doob 已提交
2093
			refreshMaterial = true;
2094
			refreshLights = true;
M
Mr.doob 已提交
2095 2096 2097 2098 2099

		}

		if ( material.id !== _currentMaterialId ) {

G
gero3 已提交
2100
			if ( _currentMaterialId === - 1 ) refreshLights = true;
M
Mr.doob 已提交
2101
			_currentMaterialId = material.id;
2102

M
Mr.doob 已提交
2103 2104 2105 2106
			refreshMaterial = true;

		}

2107
		if ( refreshProgram || camera !== _currentCamera ) {
M
Mr.doob 已提交
2108 2109 2110

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

2111 2112
			if ( _logarithmicDepthBuffer ) {

2113
				_gl.uniform1f( p_uniforms.logDepthBufFC, 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
2114 2115 2116 2117

			}


M
Mr.doob 已提交
2118 2119
			if ( camera !== _currentCamera ) _currentCamera = camera;

2120 2121 2122 2123 2124 2125 2126
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
				 material.envMap ) {

2127
				if ( p_uniforms.cameraPosition !== undefined ) {
2128 2129 2130 2131 2132 2133 2134 2135 2136 2137

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

				}

			}

			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
2138
				 material instanceof THREE.MeshBasicMaterial ||
2139 2140 2141
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {

2142
				if ( p_uniforms.viewMatrix !== undefined ) {
2143 2144

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

2146 2147 2148 2149
				}

			}

M
Mr.doob 已提交
2150 2151 2152 2153 2154 2155 2156 2157
		}

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

2158
			if ( object.bindMatrix && p_uniforms.bindMatrix !== undefined ) {
2159 2160 2161 2162 2163

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

			}

2164
			if ( object.bindMatrixInverse && p_uniforms.bindMatrixInverse !== undefined ) {
2165 2166 2167 2168 2169 2170

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

			}

			if ( _supportsBoneTextures && object.skeleton && object.skeleton.useVertexTexture ) {
M
Mr.doob 已提交
2171

2172
				if ( p_uniforms.boneTexture !== undefined ) {
M
Mr.doob 已提交
2173 2174 2175 2176

					var textureUnit = getTextureUnit();

					_gl.uniform1i( p_uniforms.boneTexture, textureUnit );
2177
					_this.setTexture( object.skeleton.boneTexture, textureUnit );
M
Mr.doob 已提交
2178 2179 2180

				}

2181
				if ( p_uniforms.boneTextureWidth !== undefined ) {
2182

2183
					_gl.uniform1i( p_uniforms.boneTextureWidth, object.skeleton.boneTextureWidth );
2184 2185 2186

				}

2187
				if ( p_uniforms.boneTextureHeight !== undefined ) {
2188

2189
					_gl.uniform1i( p_uniforms.boneTextureHeight, object.skeleton.boneTextureHeight );
2190 2191 2192

				}

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

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

2197
					_gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.skeleton.boneMatrices );
M
Mr.doob 已提交
2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220

				}

			}

		}

		if ( refreshMaterial ) {

			// refresh uniforms common to several materials

			if ( fog && material.fog ) {

				refreshUniformsFog( m_uniforms, fog );

			}

			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material.lights ) {

				if ( _lightsNeedUpdate ) {

2221
					refreshLights = true;
2222
					setupLights( lights );
M
Mr.doob 已提交
2223
					_lightsNeedUpdate = false;
G
gero3 已提交
2224

M
Mr.doob 已提交
2225 2226
				}

2227
				if ( refreshLights ) {
G
gero3 已提交
2228

2229
					refreshUniformsLights( m_uniforms, _lights );
2230
					markUniformsLightsNeedsUpdate( m_uniforms, true );
G
gero3 已提交
2231

2232
				} else {
G
gero3 已提交
2233

2234
					markUniformsLightsNeedsUpdate( m_uniforms, false );
G
gero3 已提交
2235

2236
				}
M
Mr.doob 已提交
2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258

			}

			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.MeshPhongMaterial ) {

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

2259
			} else if ( material instanceof THREE.PointCloudMaterial ) {
M
Mr.doob 已提交
2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270

				refreshUniformsParticle( m_uniforms, material );

			} else if ( material instanceof THREE.MeshPhongMaterial ) {

				refreshUniformsPhong( m_uniforms, material );

			} else if ( material instanceof THREE.MeshLambertMaterial ) {

				refreshUniformsLambert( m_uniforms, material );

2271 2272 2273 2274
			} else if ( material instanceof THREE.MeshBasicMaterial ) {

				refreshUniformsBasic( m_uniforms, material );

M
Mr.doob 已提交
2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294
			} 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;

			}

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

				refreshUniformsShadow( m_uniforms, lights );

			}

			// load common uniforms

2295
			loadUniformsGeneric( materialProperties.uniformsList );
M
Mr.doob 已提交
2296 2297 2298 2299 2300

		}

		loadUniformsMatrices( p_uniforms, object );

2301
		if ( p_uniforms.modelMatrix !== undefined ) {
M
Mr.doob 已提交
2302 2303

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

M
Mr.doob 已提交
2305 2306 2307 2308
		}

		return program;

M
Mr.doob 已提交
2309
	}
M
Mr.doob 已提交
2310 2311 2312 2313 2314 2315 2316

	// Uniforms (refresh uniforms objects)

	function refreshUniformsCommon ( uniforms, material ) {

		uniforms.opacity.value = material.opacity;

2317
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
2318 2319 2320

		uniforms.map.value = material.map;
		uniforms.specularMap.value = material.specularMap;
2321
		uniforms.alphaMap.value = material.alphaMap;
M
Mr.doob 已提交
2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337

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

		}

		// uv repeat and offset setting priorities
M
Mr.doob 已提交
2338 2339 2340 2341 2342
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
2343
		// 6. emissive map
M
Mr.doob 已提交
2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

2363 2364 2365 2366
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

2367 2368 2369 2370
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382
		}

		if ( uvScaleMap !== undefined ) {

			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;
2383
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : - 1;
M
Mr.doob 已提交
2384

2385
		uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
2386 2387
		uniforms.refractionRatio.value = material.refractionRatio;

M
Mr.doob 已提交
2388
	}
M
Mr.doob 已提交
2389 2390 2391 2392 2393 2394

	function refreshUniformsLine ( uniforms, material ) {

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

M
Mr.doob 已提交
2395
	}
M
Mr.doob 已提交
2396 2397 2398 2399 2400 2401 2402

	function refreshUniformsDash ( uniforms, material ) {

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

M
Mr.doob 已提交
2403
	}
M
Mr.doob 已提交
2404 2405 2406 2407 2408 2409 2410 2411 2412 2413

	function refreshUniformsParticle ( uniforms, material ) {

		uniforms.psColor.value = material.color;
		uniforms.opacity.value = material.opacity;
		uniforms.size.value = material.size;
		uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.

		uniforms.map.value = material.map;

2414 2415 2416 2417 2418 2419 2420 2421 2422
		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 已提交
2423
	}
M
Mr.doob 已提交
2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439

	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 已提交
2440
	}
M
Mr.doob 已提交
2441 2442 2443 2444 2445

	function refreshUniformsPhong ( uniforms, material ) {

		uniforms.shininess.value = material.shininess;

2446 2447
		uniforms.emissive.value = material.emissive;
		uniforms.specular.value = material.specular;
M
Mr.doob 已提交
2448

2449 2450 2451 2452 2453 2454
		uniforms.lightMap.value = material.lightMap;
		uniforms.lightMapIntensity.value = material.lightMapIntensity;

		uniforms.aoMap.value = material.aoMap;
		uniforms.aoMapIntensity.value = material.aoMapIntensity;

2455 2456
		uniforms.emissiveMap.value = material.emissiveMap;

M
Mr.doob 已提交
2457
	}
M
Mr.doob 已提交
2458 2459 2460

	function refreshUniformsLambert ( uniforms, material ) {

2461
		uniforms.emissive.value = material.emissive;
M
Mr.doob 已提交
2462

M
Mr.doob 已提交
2463
	}
M
Mr.doob 已提交
2464

2465 2466 2467 2468 2469 2470 2471
	function refreshUniformsBasic ( uniforms, material ) {

		uniforms.aoMap.value = material.aoMap;
		uniforms.aoMapIntensity.value = material.aoMapIntensity;

	}

M
Mr.doob 已提交
2472 2473 2474 2475 2476 2477 2478 2479 2480 2481
	function refreshUniformsLights ( uniforms, lights ) {

		uniforms.ambientLightColor.value = lights.ambient;

		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;

		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
		uniforms.pointLightDistance.value = lights.point.distances;
M
Mr.doob 已提交
2482
		uniforms.pointLightDecay.value = lights.point.decays;
M
Mr.doob 已提交
2483 2484 2485 2486 2487 2488 2489

		uniforms.spotLightColor.value = lights.spot.colors;
		uniforms.spotLightPosition.value = lights.spot.positions;
		uniforms.spotLightDistance.value = lights.spot.distances;
		uniforms.spotLightDirection.value = lights.spot.directions;
		uniforms.spotLightAngleCos.value = lights.spot.anglesCos;
		uniforms.spotLightExponent.value = lights.spot.exponents;
M
Mr.doob 已提交
2490
		uniforms.spotLightDecay.value = lights.spot.decays;
M
Mr.doob 已提交
2491 2492 2493 2494 2495

		uniforms.hemisphereLightSkyColor.value = lights.hemi.skyColors;
		uniforms.hemisphereLightGroundColor.value = lights.hemi.groundColors;
		uniforms.hemisphereLightDirection.value = lights.hemi.positions;

M
Mr.doob 已提交
2496
	}
M
Mr.doob 已提交
2497

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

M
Mr.doob 已提交
2500
	function markUniformsLightsNeedsUpdate ( uniforms, value ) {
2501

M
Mr.doob 已提交
2502
		uniforms.ambientLightColor.needsUpdate = value;
2503

M
Mr.doob 已提交
2504 2505
		uniforms.directionalLightColor.needsUpdate = value;
		uniforms.directionalLightDirection.needsUpdate = value;
2506

M
Mr.doob 已提交
2507 2508 2509 2510
		uniforms.pointLightColor.needsUpdate = value;
		uniforms.pointLightPosition.needsUpdate = value;
		uniforms.pointLightDistance.needsUpdate = value;
		uniforms.pointLightDecay.needsUpdate = value;
2511

M
Mr.doob 已提交
2512 2513 2514 2515 2516 2517 2518
		uniforms.spotLightColor.needsUpdate = value;
		uniforms.spotLightPosition.needsUpdate = value;
		uniforms.spotLightDistance.needsUpdate = value;
		uniforms.spotLightDirection.needsUpdate = value;
		uniforms.spotLightAngleCos.needsUpdate = value;
		uniforms.spotLightExponent.needsUpdate = value;
		uniforms.spotLightDecay.needsUpdate = value;
2519

M
Mr.doob 已提交
2520 2521 2522
		uniforms.hemisphereLightSkyColor.needsUpdate = value;
		uniforms.hemisphereLightGroundColor.needsUpdate = value;
		uniforms.hemisphereLightDirection.needsUpdate = value;
2523

M
Mr.doob 已提交
2524
	}
2525

M
Mr.doob 已提交
2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537
	function refreshUniformsShadow ( uniforms, lights ) {

		if ( uniforms.shadowMatrix ) {

			var j = 0;

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

				var light = lights[ i ];

				if ( ! light.castShadow ) continue;

2538
				if ( light instanceof THREE.SpotLight || ( light instanceof THREE.DirectionalLight ) ) {
M
Mr.doob 已提交
2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555

					uniforms.shadowMap.value[ j ] = light.shadowMap;
					uniforms.shadowMapSize.value[ j ] = light.shadowMapSize;

					uniforms.shadowMatrix.value[ j ] = light.shadowMatrix;

					uniforms.shadowDarkness.value[ j ] = light.shadowDarkness;
					uniforms.shadowBias.value[ j ] = light.shadowBias;

					j ++;

				}

			}

		}

M
Mr.doob 已提交
2556
	}
M
Mr.doob 已提交
2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569

	// Uniforms (load to GPU)

	function loadUniformsMatrices ( uniforms, object ) {

		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrix.elements );

		if ( uniforms.normalMatrix ) {

			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrix.elements );

		}

M
Mr.doob 已提交
2570
	}
M
Mr.doob 已提交
2571 2572 2573 2574 2575 2576 2577

	function getTextureUnit() {

		var textureUnit = _usedTextureUnits;

		if ( textureUnit >= _maxTextures ) {

2578
			console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + _maxTextures );
M
Mr.doob 已提交
2579 2580 2581 2582 2583 2584 2585

		}

		_usedTextureUnits += 1;

		return textureUnit;

M
Mr.doob 已提交
2586
	}
M
Mr.doob 已提交
2587

2588
	function loadUniformsGeneric ( uniforms ) {
M
Mr.doob 已提交
2589

M
Mr.doob 已提交
2590
		var texture, textureUnit, offset;
M
Mr.doob 已提交
2591

M
Mr.doob 已提交
2592 2593 2594
		for ( var j = 0, jl = uniforms.length; j < jl; j ++ ) {

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

2596 2597
			// needsUpdate property is not added to all uniforms.
			if ( uniform.needsUpdate === false ) continue;
2598

M
Mr.doob 已提交
2599 2600
			var type = uniform.type;
			var value = uniform.value;
2601
			var location = uniforms[ j ][ 1 ];
M
Mr.doob 已提交
2602

2603
			switch ( type ) {
M
Mr.doob 已提交
2604

2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658
				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;

				case 'Matrix3fv':
					_gl.uniformMatrix3fv( location, false, value );
					break;

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

				//

M
Mr.doob 已提交
2659
				case 'i':
M
Mr.doob 已提交
2660

2661 2662
					// single integer
					_gl.uniform1i( location, value );
M
Mr.doob 已提交
2663

2664
					break;
M
Mr.doob 已提交
2665

2666
				case 'f':
M
Mr.doob 已提交
2667

2668 2669
					// single float
					_gl.uniform1f( location, value );
M
Mr.doob 已提交
2670

2671
					break;
M
Mr.doob 已提交
2672

2673
				case 'v2':
M
Mr.doob 已提交
2674

2675 2676
					// single THREE.Vector2
					_gl.uniform2f( location, value.x, value.y );
M
Mr.doob 已提交
2677

2678
					break;
M
Mr.doob 已提交
2679

2680
				case 'v3':
M
Mr.doob 已提交
2681

2682 2683
					// single THREE.Vector3
					_gl.uniform3f( location, value.x, value.y, value.z );
M
Mr.doob 已提交
2684

2685
					break;
M
Mr.doob 已提交
2686

M
Mr.doob 已提交
2687
				case 'v4':
M
Mr.doob 已提交
2688

2689 2690
					// single THREE.Vector4
					_gl.uniform4f( location, value.x, value.y, value.z, value.w );
M
Mr.doob 已提交
2691

2692
					break;
M
Mr.doob 已提交
2693

2694
				case 'c':
M
Mr.doob 已提交
2695

2696 2697
					// single THREE.Color
					_gl.uniform3f( location, value.r, value.g, value.b );
M
Mr.doob 已提交
2698

2699
					break;
M
Mr.doob 已提交
2700

2701
				case 'iv1':
M
Mr.doob 已提交
2702

2703 2704
					// flat array of integers (JS or typed array)
					_gl.uniform1iv( location, value );
M
Mr.doob 已提交
2705

2706
					break;
M
Mr.doob 已提交
2707

2708
				case 'iv':
M
Mr.doob 已提交
2709

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

2713
					break;
M
Mr.doob 已提交
2714

2715
				case 'fv1':
M
Mr.doob 已提交
2716

2717 2718
					// flat array of floats (JS or typed array)
					_gl.uniform1fv( location, value );
M
Mr.doob 已提交
2719

2720
					break;
M
Mr.doob 已提交
2721

2722
				case 'fv':
M
Mr.doob 已提交
2723

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

2727
					break;
M
Mr.doob 已提交
2728

2729
				case 'v2v':
M
Mr.doob 已提交
2730

2731
					// array of THREE.Vector2
M
Mr.doob 已提交
2732

2733
					if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2734

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

2737
					}
M
Mr.doob 已提交
2738

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

2741
						offset = i * 2;
M
Mr.doob 已提交
2742

M
Mr.doob 已提交
2743
						uniform._array[ offset + 0 ] = value[ i ].x;
2744
						uniform._array[ offset + 1 ] = value[ i ].y;
M
Mr.doob 已提交
2745

2746
					}
M
Mr.doob 已提交
2747

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

2750
					break;
M
Mr.doob 已提交
2751

2752
				case 'v3v':
M
Mr.doob 已提交
2753

2754
					// array of THREE.Vector3
M
Mr.doob 已提交
2755

2756
					if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2757

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

2760
					}
M
Mr.doob 已提交
2761

2762
					for ( var i = 0, il = value.length; i < il; i ++ ) {
R
Ryan Tsao 已提交
2763

2764
						offset = i * 3;
R
Ryan Tsao 已提交
2765

M
Mr.doob 已提交
2766
						uniform._array[ offset + 0 ] = value[ i ].x;
2767 2768
						uniform._array[ offset + 1 ] = value[ i ].y;
						uniform._array[ offset + 2 ] = value[ i ].z;
R
Ryan Tsao 已提交
2769

2770
					}
R
Ryan Tsao 已提交
2771

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

2774
					break;
R
Ryan Tsao 已提交
2775

2776
				case 'v4v':
R
Ryan Tsao 已提交
2777

2778
					// array of THREE.Vector4
R
Ryan Tsao 已提交
2779

2780
					if ( uniform._array === undefined ) {
R
Ryan Tsao 已提交
2781

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

2784
					}
M
Mr.doob 已提交
2785

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

2788
						offset = i * 4;
M
Mr.doob 已提交
2789

M
Mr.doob 已提交
2790
						uniform._array[ offset + 0 ] = value[ i ].x;
2791 2792 2793
						uniform._array[ offset + 1 ] = value[ i ].y;
						uniform._array[ offset + 2 ] = value[ i ].z;
						uniform._array[ offset + 3 ] = value[ i ].w;
M
Mr.doob 已提交
2794

2795
					}
M
Mr.doob 已提交
2796

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

2799
					break;
M
Mr.doob 已提交
2800

2801
				case 'm3':
M
Mr.doob 已提交
2802

2803 2804
					// single THREE.Matrix3
					_gl.uniformMatrix3fv( location, false, value.elements );
M
Mr.doob 已提交
2805

2806
					break;
M
Mr.doob 已提交
2807

2808
				case 'm3v':
M
Mr.doob 已提交
2809

2810
					// array of THREE.Matrix3
M
Mr.doob 已提交
2811

2812
					if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2813

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

2816
					}
M
Mr.doob 已提交
2817

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

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

2822
					}
M
Mr.doob 已提交
2823

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

2826
					break;
M
Mr.doob 已提交
2827

2828
				case 'm4':
M
Mr.doob 已提交
2829

2830 2831
					// single THREE.Matrix4
					_gl.uniformMatrix4fv( location, false, value.elements );
M
Mr.doob 已提交
2832

2833
					break;
M
Mr.doob 已提交
2834

2835
				case 'm4v':
M
Mr.doob 已提交
2836

2837
					// array of THREE.Matrix4
M
Mr.doob 已提交
2838

2839
					if ( uniform._array === undefined ) {
M
Mr.doob 已提交
2840

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

2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853
					}

					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 已提交
2854

2855
				case 't':
M
Mr.doob 已提交
2856

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

2859 2860 2861 2862
					texture = value;
					textureUnit = getTextureUnit();

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

2864
					if ( ! texture ) continue;
M
Mr.doob 已提交
2865

2866
					if ( texture instanceof THREE.CubeTexture ||
G
gero3 已提交
2867 2868 2869
						 ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {

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

2871
						setCubeTexture( texture, textureUnit );
M
Mr.doob 已提交
2872

2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916
					} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {

						setCubeTextureDynamic( texture, textureUnit );

					} else {

						_this.setTexture( texture, textureUnit );

					}

					break;

				case 'tv':

					// array of THREE.Texture (2d)

					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;

						_this.setTexture( texture, textureUnit );

					}

					break;

				default:
2917

2918
					console.warn( 'THREE.WebGLRenderer: Unknown uniform type: ' + type );
2919

M
Mr.doob 已提交
2920 2921 2922 2923
			}

		}

M
Mr.doob 已提交
2924
	}
M
Mr.doob 已提交
2925

2926
	function setupMatrices( object, camera ) {
M
Mr.doob 已提交
2927 2928

		object._modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
2929
		object._normalMatrix.getNormalMatrix( object._modelViewMatrix );
M
Mr.doob 已提交
2930

M
Mr.doob 已提交
2931
	}
M
Mr.doob 已提交
2932 2933 2934

	function setColorLinear( array, offset, color, intensity ) {

M
Mr.doob 已提交
2935
		array[ offset + 0 ] = color.r * intensity;
M
Mr.doob 已提交
2936 2937 2938
		array[ offset + 1 ] = color.g * intensity;
		array[ offset + 2 ] = color.b * intensity;

M
Mr.doob 已提交
2939
	}
M
Mr.doob 已提交
2940

2941
	function setupLights ( lights ) {
M
Mr.doob 已提交
2942

B
brason 已提交
2943
		var l, ll, light,
M
Mr.doob 已提交
2944 2945
		r = 0, g = 0, b = 0,
		color, skyColor, groundColor,
B
brason 已提交
2946
		intensity,
M
Mr.doob 已提交
2947 2948 2949 2950 2951 2952 2953 2954 2955 2956
		distance,

		zlights = _lights,

		dirColors = zlights.directional.colors,
		dirPositions = zlights.directional.positions,

		pointColors = zlights.point.colors,
		pointPositions = zlights.point.positions,
		pointDistances = zlights.point.distances,
M
Mr.doob 已提交
2957
		pointDecays = zlights.point.decays,
M
Mr.doob 已提交
2958 2959 2960 2961 2962 2963 2964

		spotColors = zlights.spot.colors,
		spotPositions = zlights.spot.positions,
		spotDistances = zlights.spot.distances,
		spotDirections = zlights.spot.directions,
		spotAnglesCos = zlights.spot.anglesCos,
		spotExponents = zlights.spot.exponents,
M
Mr.doob 已提交
2965
		spotDecays = zlights.spot.decays,
M
Mr.doob 已提交
2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999

		hemiSkyColors = zlights.hemi.skyColors,
		hemiGroundColors = zlights.hemi.groundColors,
		hemiPositions = zlights.hemi.positions,

		dirLength = 0,
		pointLength = 0,
		spotLength = 0,
		hemiLength = 0,

		dirCount = 0,
		pointCount = 0,
		spotCount = 0,
		hemiCount = 0,

		dirOffset = 0,
		pointOffset = 0,
		spotOffset = 0,
		hemiOffset = 0;

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

			light = lights[ l ];

			if ( light.onlyShadow ) continue;

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

			if ( light instanceof THREE.AmbientLight ) {

				if ( ! light.visible ) continue;

3000 3001 3002
				r += color.r;
				g += color.g;
				b += color.b;
M
Mr.doob 已提交
3003 3004 3005 3006 3007 3008 3009

			} else if ( light instanceof THREE.DirectionalLight ) {

				dirCount += 1;

				if ( ! light.visible ) continue;

3010 3011
				_direction.setFromMatrixPosition( light.matrixWorld );
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
M
Mr.doob 已提交
3012 3013 3014 3015 3016
				_direction.sub( _vector3 );
				_direction.normalize();

				dirOffset = dirLength * 3;

M
Mr.doob 已提交
3017
				dirPositions[ dirOffset + 0 ] = _direction.x;
M
Mr.doob 已提交
3018 3019 3020
				dirPositions[ dirOffset + 1 ] = _direction.y;
				dirPositions[ dirOffset + 2 ] = _direction.z;

3021
				setColorLinear( dirColors, dirOffset, color, intensity );
M
Mr.doob 已提交
3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032

				dirLength += 1;

			} else if ( light instanceof THREE.PointLight ) {

				pointCount += 1;

				if ( ! light.visible ) continue;

				pointOffset = pointLength * 3;

3033
				setColorLinear( pointColors, pointOffset, color, intensity );
M
Mr.doob 已提交
3034

3035
				_vector3.setFromMatrixPosition( light.matrixWorld );
M
Mr.doob 已提交
3036

M
Mr.doob 已提交
3037
				pointPositions[ pointOffset + 0 ] = _vector3.x;
M
Mr.doob 已提交
3038 3039 3040
				pointPositions[ pointOffset + 1 ] = _vector3.y;
				pointPositions[ pointOffset + 2 ] = _vector3.z;

M
Mr.doob 已提交
3041
				// distance is 0 if decay is 0, because there is no attenuation at all.
M
Mr.doob 已提交
3042
				pointDistances[ pointLength ] = distance;
M
Mr.doob 已提交
3043
				pointDecays[ pointLength ] = ( light.distance === 0 ) ? 0.0 : light.decay;
M
Mr.doob 已提交
3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054

				pointLength += 1;

			} else if ( light instanceof THREE.SpotLight ) {

				spotCount += 1;

				if ( ! light.visible ) continue;

				spotOffset = spotLength * 3;

3055
				setColorLinear( spotColors, spotOffset, color, intensity );
M
Mr.doob 已提交
3056

G
gero3 已提交
3057
				_direction.setFromMatrixPosition( light.matrixWorld );
M
Mr.doob 已提交
3058

M
Mr.doob 已提交
3059
				spotPositions[ spotOffset + 0 ] = _direction.x;
G
gero3 已提交
3060 3061
				spotPositions[ spotOffset + 1 ] = _direction.y;
				spotPositions[ spotOffset + 2 ] = _direction.z;
M
Mr.doob 已提交
3062 3063 3064

				spotDistances[ spotLength ] = distance;

3065
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
M
Mr.doob 已提交
3066 3067 3068
				_direction.sub( _vector3 );
				_direction.normalize();

M
Mr.doob 已提交
3069
				spotDirections[ spotOffset + 0 ] = _direction.x;
M
Mr.doob 已提交
3070 3071 3072 3073 3074
				spotDirections[ spotOffset + 1 ] = _direction.y;
				spotDirections[ spotOffset + 2 ] = _direction.z;

				spotAnglesCos[ spotLength ] = Math.cos( light.angle );
				spotExponents[ spotLength ] = light.exponent;
M
Mr.doob 已提交
3075
				spotDecays[ spotLength ] = ( light.distance === 0 ) ? 0.0 : light.decay;
M
Mr.doob 已提交
3076 3077 3078 3079 3080 3081 3082 3083 3084

				spotLength += 1;

			} else if ( light instanceof THREE.HemisphereLight ) {

				hemiCount += 1;

				if ( ! light.visible ) continue;

3085
				_direction.setFromMatrixPosition( light.matrixWorld );
M
Mr.doob 已提交
3086 3087 3088 3089
				_direction.normalize();

				hemiOffset = hemiLength * 3;

M
Mr.doob 已提交
3090
				hemiPositions[ hemiOffset + 0 ] = _direction.x;
M
Mr.doob 已提交
3091 3092 3093 3094 3095 3096
				hemiPositions[ hemiOffset + 1 ] = _direction.y;
				hemiPositions[ hemiOffset + 2 ] = _direction.z;

				skyColor = light.color;
				groundColor = light.groundColor;

3097 3098
				setColorLinear( hemiSkyColors, hemiOffset, skyColor, intensity );
				setColorLinear( hemiGroundColors, hemiOffset, groundColor, intensity );
M
Mr.doob 已提交
3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123

				hemiLength += 1;

			}

		}

		// null eventual remains from removed lights
		// (this is to avoid if in shader)

		for ( l = dirLength * 3, ll = Math.max( dirColors.length, dirCount * 3 ); l < ll; l ++ ) dirColors[ l ] = 0.0;
		for ( l = pointLength * 3, ll = Math.max( pointColors.length, pointCount * 3 ); l < ll; l ++ ) pointColors[ l ] = 0.0;
		for ( l = spotLength * 3, ll = Math.max( spotColors.length, spotCount * 3 ); l < ll; l ++ ) spotColors[ l ] = 0.0;
		for ( l = hemiLength * 3, ll = Math.max( hemiSkyColors.length, hemiCount * 3 ); l < ll; l ++ ) hemiSkyColors[ l ] = 0.0;
		for ( l = hemiLength * 3, ll = Math.max( hemiGroundColors.length, hemiCount * 3 ); l < ll; l ++ ) hemiGroundColors[ l ] = 0.0;

		zlights.directional.length = dirLength;
		zlights.point.length = pointLength;
		zlights.spot.length = spotLength;
		zlights.hemi.length = hemiLength;

		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;

M
Mr.doob 已提交
3124
	}
M
Mr.doob 已提交
3125 3126 3127 3128 3129 3130 3131

	// GL state setting

	this.setFaceCulling = function ( cullFace, frontFaceDirection ) {

		if ( cullFace === THREE.CullFaceNone ) {

3132
			state.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159

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

			}

3160
			state.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
3161 3162 3163 3164 3165 3166 3167 3168 3169

		}

	};

	// Textures

	function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {

3170 3171
		var extension;

M
Mr.doob 已提交
3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183
		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 已提交
3184 3185 3186

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

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

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

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

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

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

3198
			}
M
Mr.doob 已提交
3199

M
Mr.doob 已提交
3200 3201
		}

3202 3203
		extension = extensions.get( 'EXT_texture_filter_anisotropic' );

3204
		if ( extension && texture.type !== THREE.FloatType && texture.type !== THREE.HalfFloatType ) {
M
Mr.doob 已提交
3205

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

3208
				_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _this.getMaxAnisotropy() ) );
3209
				properties.get( texture ).__currentAnisotropy = texture.anisotropy;
M
Mr.doob 已提交
3210 3211 3212 3213 3214

			}

		}

M
Mr.doob 已提交
3215
	}
M
Mr.doob 已提交
3216

3217
	function uploadTexture( textureProperties, texture, slot ) {
3218

3219
		if ( textureProperties.__webglInit === undefined ) {
3220

3221
			textureProperties.__webglInit = true;
3222 3223 3224 3225 3226

			texture.__webglInit = true;

			texture.addEventListener( 'dispose', onTextureDispose );

3227
			textureProperties.__webglTexture = _gl.createTexture();
3228

3229
			_infoMemory.textures ++;
3230 3231

		}
M
Mr.doob 已提交
3232

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

H
Henri Astre 已提交
3236 3237 3238 3239
		_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 );

3240 3241
		texture.image = clampToMaxSize( texture.image, _maxTextureSize );

H
Henri Astre 已提交
3242 3243 3244 3245
		var image = texture.image,
		isImagePowerOfTwo = THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ),
		glFormat = paramThreeToGL( texture.format ),
		glType = paramThreeToGL( texture.type );
M
Mr.doob 已提交
3246

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

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

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

H
Henri Astre 已提交
3253 3254 3255
			// 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 已提交
3256

H
Henri Astre 已提交
3257 3258 3259
			if ( mipmaps.length > 0 && isImagePowerOfTwo ) {

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

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

H
Henri Astre 已提交
3264
				}
M
Mr.doob 已提交
3265

H
Henri Astre 已提交
3266
				texture.generateMipmaps = false;
M
Mr.doob 已提交
3267

H
Henri Astre 已提交
3268
			} else {
M
Mr.doob 已提交
3269

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

H
Henri Astre 已提交
3272
			}
M
Mr.doob 已提交
3273

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

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

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

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

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

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

3286
					} else {
M
Mr.doob 已提交
3287

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

3290
					}
M
Mr.doob 已提交
3291

H
Henri Astre 已提交
3292
				} else {
M
Mr.doob 已提交
3293

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

M
Mr.doob 已提交
3296 3297
				}

H
Henri Astre 已提交
3298 3299
			}

G
gero3 已提交
3300 3301 3302
		} else {

			// regular Texture (image, video, canvas)
H
Henri Astre 已提交
3303 3304 3305 3306 3307 3308

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

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

					mipmap = mipmaps[ i ];
3313
					state.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );
M
Mr.doob 已提交
3314 3315 3316

				}

H
Henri Astre 已提交
3317
				texture.generateMipmaps = false;
M
Mr.doob 已提交
3318

H
Henri Astre 已提交
3319
			} else {
M
Mr.doob 已提交
3320

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

H
Henri Astre 已提交
3323
			}
M
Mr.doob 已提交
3324

H
Henri Astre 已提交
3325
		}
M
Mr.doob 已提交
3326

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

3329
		textureProperties.__version = texture.version;
M
Mr.doob 已提交
3330

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

3333
	}
M
Mr.doob 已提交
3334

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

3337 3338 3339
		var textureProperties = properties.get( texture );

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

3341
			var image = texture.image;
M
Mr.doob 已提交
3342

3343 3344
			if ( image === undefined ) {

3345
				console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );
3346 3347 3348 3349
				return;

			}

3350
			if ( image.complete === false ) {
M
Mr.doob 已提交
3351

3352
				console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );
3353 3354 3355 3356
				return;

			}

3357
			uploadTexture( textureProperties, texture, slot );
3358
			return;
M
Mr.doob 已提交
3359 3360 3361

		}

B
Ben Adams 已提交
3362
		state.activeTexture( _gl.TEXTURE0 + slot );
3363
		state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
3364

M
Mr.doob 已提交
3365 3366 3367 3368
	};

	function clampToMaxSize ( image, maxSize ) {

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

3371 3372
			// Warning: Scaling through the canvas will only work with images that use
			// premultiplied alpha.
M
Mr.doob 已提交
3373

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

3376 3377 3378
			var canvas = document.createElement( 'canvas' );
			canvas.width = Math.floor( image.width * scale );
			canvas.height = Math.floor( image.height * scale );
M
Mr.doob 已提交
3379

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

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

3385 3386 3387
			return canvas;

		}
M
Mr.doob 已提交
3388

3389
		return image;
M
Mr.doob 已提交
3390 3391 3392 3393 3394

	}

	function setCubeTexture ( texture, slot ) {

3395
		var textureProperties = properties.get( texture );
3396

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

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

3401
				if ( ! textureProperties.__image__webglTextureCube ) {
M
Mr.doob 已提交
3402

3403 3404
					texture.addEventListener( 'dispose', onTextureDispose );

3405
					textureProperties.__image__webglTextureCube = _gl.createTexture();
M
Mr.doob 已提交
3406

3407
					_infoMemory.textures ++;
M
Mr.doob 已提交
3408 3409 3410

				}

B
Ben Adams 已提交
3411
				state.activeTexture( _gl.TEXTURE0 + slot );
3412
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
3413 3414 3415

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

M
Mr.doob 已提交
3416 3417
				var isCompressed = texture instanceof THREE.CompressedTexture;
				var isDataTexture = texture.image[ 0 ] instanceof THREE.DataTexture;
M
Mr.doob 已提交
3418 3419 3420 3421 3422

				var cubeImage = [];

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

3423
					if ( _this.autoScaleCubemaps && ! isCompressed && ! isDataTexture ) {
M
Mr.doob 已提交
3424 3425 3426 3427 3428

						cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize );

					} else {

3429
						cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];
M
Mr.doob 已提交
3430 3431 3432 3433 3434 3435

					}

				}

				var image = cubeImage[ 0 ],
3436
				isImagePowerOfTwo = THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ),
M
Mr.doob 已提交
3437 3438 3439 3440 3441 3442 3443
				glFormat = paramThreeToGL( texture.format ),
				glType = paramThreeToGL( texture.type );

				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo );

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

3444
					if ( ! isCompressed ) {
M
Mr.doob 已提交
3445

M
Mr.doob 已提交
3446
						if ( isDataTexture ) {
3447

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

M
Mr.doob 已提交
3450
						} else {
3451

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

M
Mr.doob 已提交
3454 3455
						}

3456
					} else {
3457

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

3460
						for ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {
M
Mr.doob 已提交
3461 3462

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

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

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

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

3470
								} else {
M
Mr.doob 已提交
3471

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

3474
								}
M
Mr.doob 已提交
3475

3476
							} else {
M
Mr.doob 已提交
3477

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

3480
							}
M
Mr.doob 已提交
3481

3482
						}
M
Mr.doob 已提交
3483

M
Mr.doob 已提交
3484
					}
M
Mr.doob 已提交
3485

M
Mr.doob 已提交
3486 3487 3488 3489 3490 3491 3492 3493
				}

				if ( texture.generateMipmaps && isImagePowerOfTwo ) {

					_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

				}

3494
				textureProperties.__version = texture.version;
M
Mr.doob 已提交
3495

B
Ben Adams 已提交
3496
				if ( texture.onUpdate ) texture.onUpdate( texture );
M
Mr.doob 已提交
3497 3498 3499

			} else {

B
Ben Adams 已提交
3500
				state.activeTexture( _gl.TEXTURE0 + slot );
3501
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
M
Mr.doob 已提交
3502 3503 3504 3505 3506

			}

		}

M
Mr.doob 已提交
3507
	}
M
Mr.doob 已提交
3508 3509 3510

	function setCubeTextureDynamic ( texture, slot ) {

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

M
Mr.doob 已提交
3514
	}
M
Mr.doob 已提交
3515 3516 3517 3518 3519 3520

	// Render targets

	function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {

		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
3521
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, properties.get( renderTarget ).__webglTexture, 0 );
M
Mr.doob 已提交
3522

M
Mr.doob 已提交
3523
	}
M
Mr.doob 已提交
3524

M
Mr.doob 已提交
3525
	function setupRenderBuffer ( renderbuffer, renderTarget ) {
M
Mr.doob 已提交
3526 3527 3528 3529 3530 3531 3532 3533 3534

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

		/* For some reason this is not working. Defaulting to RGBA4.
3535
		} else if ( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
M
Mr.doob 已提交
3536 3537 3538 3539

			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.STENCIL_INDEX8, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
		*/
G
gero3 已提交
3540

M
Mr.doob 已提交
3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551
		} 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 {

			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );

		}

M
Mr.doob 已提交
3552
	}
M
Mr.doob 已提交
3553 3554 3555 3556 3557

	this.setRenderTarget = function ( renderTarget ) {

		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );

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

3560
			var renderTargetProperties = properties.get( renderTarget );
M
Mr.doob 已提交
3561 3562 3563 3564 3565 3566

			if ( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
			if ( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;

			renderTarget.addEventListener( 'dispose', onRenderTargetDispose );

3567
			renderTargetProperties.__webglTexture = _gl.createTexture();
M
Mr.doob 已提交
3568

3569
			_infoMemory.textures ++;
M
Mr.doob 已提交
3570 3571 3572

			// Setup texture, create render and frame buffers

3573
			var isTargetPowerOfTwo = THREE.Math.isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height ),
M
Mr.doob 已提交
3574 3575 3576 3577 3578
				glFormat = paramThreeToGL( renderTarget.format ),
				glType = paramThreeToGL( renderTarget.type );

			if ( isCube ) {

3579 3580
				renderTargetProperties.__webglFramebuffer = [];
				renderTargetProperties.__webglRenderbuffer = [];
M
Mr.doob 已提交
3581

3582
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTargetProperties.__webglTexture );
B
Ben Adams 已提交
3583

M
Mr.doob 已提交
3584 3585 3586 3587
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, isTargetPowerOfTwo );

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

3588 3589
					renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();
					renderTargetProperties.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
M
Mr.doob 已提交
3590

3591
					state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
M
Mr.doob 已提交
3592

3593 3594
					setupFrameBuffer( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
					setupRenderBuffer( renderTargetProperties.__webglRenderbuffer[ i ], renderTarget );
M
Mr.doob 已提交
3595 3596 3597

				}

3598
				if ( renderTarget.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
M
Mr.doob 已提交
3599 3600 3601

			} else {

3602
				renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
M
Mr.doob 已提交
3603 3604 3605

				if ( renderTarget.shareDepthFrom ) {

3606
					renderTargetProperties.__webglRenderbuffer = renderTarget.shareDepthFrom.__webglRenderbuffer;
M
Mr.doob 已提交
3607 3608 3609

				} else {

3610
					renderTargetProperties.__webglRenderbuffer = _gl.createRenderbuffer();
M
Mr.doob 已提交
3611 3612 3613

				}

3614
				state.bindTexture( _gl.TEXTURE_2D, renderTargetProperties.__webglTexture );
M
Mr.doob 已提交
3615 3616
				setTextureParameters( _gl.TEXTURE_2D, renderTarget, isTargetPowerOfTwo );

3617
				state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
M
Mr.doob 已提交
3618

3619
				setupFrameBuffer( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
M
Mr.doob 已提交
3620 3621 3622 3623 3624

				if ( renderTarget.shareDepthFrom ) {

					if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {

3625
						_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTargetProperties.__webglRenderbuffer );
M
Mr.doob 已提交
3626 3627 3628

					} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {

3629
						_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderTargetProperties.__webglRenderbuffer );
M
Mr.doob 已提交
3630 3631 3632 3633 3634

					}

				} else {

3635
					setupRenderBuffer( renderTargetProperties.__webglRenderbuffer, renderTarget );
M
Mr.doob 已提交
3636 3637 3638

				}

3639
				if ( renderTarget.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
M
Mr.doob 已提交
3640 3641 3642 3643 3644 3645 3646

			}

			// Release everything

			if ( isCube ) {

B
Ben Adams 已提交
3647
				state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
M
Mr.doob 已提交
3648 3649 3650

			} else {

B
Ben Adams 已提交
3651
				state.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663

			}

			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );

		}

		var framebuffer, width, height, vx, vy;

		if ( renderTarget ) {

3664
			var renderTargetProperties = properties.get( renderTarget );
F
Fordy 已提交
3665

M
Mr.doob 已提交
3666 3667
			if ( isCube ) {

3668
				framebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
3669 3670 3671

			} else {

3672
				framebuffer = renderTargetProperties.__webglFramebuffer;
M
Mr.doob 已提交
3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707

			}

			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;

		}

		_currentWidth = width;
		_currentHeight = height;

	};

3708
	this.readRenderTargetPixels = function( renderTarget, x, y, width, height, buffer ) {
3709

G
gero3 已提交
3710
		if ( ! ( renderTarget instanceof THREE.WebGLRenderTarget ) ) {
3711

3712
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
3713
			return;
3714

G
gero3 已提交
3715
		}
3716

3717
		if ( properties.get( renderTarget ).__webglFramebuffer ) {
3718

G
gero3 已提交
3719
			if ( renderTarget.format !== THREE.RGBAFormat ) {
3720

3721
				console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.' );
G
gero3 已提交
3722
				return;
3723

G
gero3 已提交
3724
			}
3725

G
gero3 已提交
3726
			var restore = false;
3727

3728
			if ( properties.get( renderTarget ).__webglFramebuffer !== _currentFramebuffer ) {
3729

3730
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, properties.get( renderTarget ).__webglFramebuffer );
3731

G
gero3 已提交
3732
				restore = true;
3733

G
gero3 已提交
3734
			}
3735

G
gero3 已提交
3736
			if ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {
3737

G
gero3 已提交
3738
				_gl.readPixels( x, y, width, height, _gl.RGBA, _gl.UNSIGNED_BYTE, buffer );
3739

G
gero3 已提交
3740
			} else {
3741

3742
				console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );
3743

G
gero3 已提交
3744
			}
3745

G
gero3 已提交
3746
			if ( restore ) {
3747

G
gero3 已提交
3748
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );
3749

G
gero3 已提交
3750
			}
3751

G
gero3 已提交
3752
		}
3753 3754 3755

	};

M
Mr.doob 已提交
3756 3757 3758 3759
	function updateRenderTargetMipmap ( renderTarget ) {

		if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {

3760
			state.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( renderTarget ).__webglTexture );
M
Mr.doob 已提交
3761
			_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
B
Ben Adams 已提交
3762
			state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
M
Mr.doob 已提交
3763 3764 3765

		} else {

3766
			state.bindTexture( _gl.TEXTURE_2D, properties.get( renderTarget ).__webglTexture );
M
Mr.doob 已提交
3767
			_gl.generateMipmap( _gl.TEXTURE_2D );
B
Ben Adams 已提交
3768
			state.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
3769 3770 3771

		}

M
Mr.doob 已提交
3772
	}
M
Mr.doob 已提交
3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785

	// 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 已提交
3786
	}
M
Mr.doob 已提交
3787 3788 3789 3790 3791

	// Map three.js constants to WebGL constants

	function paramThreeToGL ( p ) {

3792 3793
		var extension;

M
Mr.doob 已提交
3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817
		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;

3818 3819 3820 3821 3822 3823 3824 3825
		extension = extensions.get( 'OES_texture_half_float' );

		if ( extension !== null ) {

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

		}

M
Mr.doob 已提交
3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848
		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;

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

3851 3852 3853 3854 3855 3856
		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 已提交
3857 3858 3859

		}

3860 3861 3862
		extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );

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

3864 3865 3866 3867
			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 已提交
3868 3869 3870

		}

3871 3872 3873
		extension = extensions.get( 'EXT_blend_minmax' );

		if ( extension !== null ) {
3874

3875 3876
			if ( p === THREE.MinEquation ) return extension.MIN_EXT;
			if ( p === THREE.MaxEquation ) return extension.MAX_EXT;
3877 3878 3879

		}

M
Mr.doob 已提交
3880 3881
		return 0;

M
Mr.doob 已提交
3882
	}
M
Mr.doob 已提交
3883 3884 3885 3886 3887

	// Allocations

	function allocateBones ( object ) {

3888
		if ( _supportsBoneTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {
M
Mr.doob 已提交
3889 3890 3891 3892 3893 3894

			return 1024;

		} else {

			// default for when object is not specified
M
Mr.doob 已提交
3895
			// ( for example when prebuilding shader to be used with multiple objects )
M
Mr.doob 已提交
3896
			//
3897
			//  - leave some extra space for other uniforms
M
Mr.doob 已提交
3898 3899 3900 3901 3902 3903 3904 3905 3906 3907
			//  - limit here is ANGLE's 254 max uniform vectors
			//    (up to 54 should be safe)

			var nVertexUniforms = _gl.getParameter( _gl.MAX_VERTEX_UNIFORM_VECTORS );
			var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );

			var maxBones = nVertexMatrices;

			if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {

3908
				maxBones = Math.min( object.skeleton.bones.length, maxBones );
M
Mr.doob 已提交
3909

3910
				if ( maxBones < object.skeleton.bones.length ) {
M
Mr.doob 已提交
3911

3912
					console.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' );
M
Mr.doob 已提交
3913 3914 3915 3916 3917 3918 3919 3920 3921

				}

			}

			return maxBones;

		}

M
Mr.doob 已提交
3922
	}
M
Mr.doob 已提交
3923

M
Mr.doob 已提交
3924
	function allocateLights( lights ) {
M
Mr.doob 已提交
3925

M
Mr.doob 已提交
3926 3927 3928 3929
		var dirLights = 0;
		var pointLights = 0;
		var spotLights = 0;
		var hemiLights = 0;
M
Mr.doob 已提交
3930

M
Mr.doob 已提交
3931
		for ( var l = 0, ll = lights.length; l < ll; l ++ ) {
M
Mr.doob 已提交
3932

M
Mr.doob 已提交
3933
			var light = lights[ l ];
M
Mr.doob 已提交
3934

3935
			if ( light.onlyShadow || light.visible === false ) continue;
M
Mr.doob 已提交
3936 3937 3938 3939 3940 3941 3942 3943

			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
			if ( light instanceof THREE.PointLight ) pointLights ++;
			if ( light instanceof THREE.SpotLight ) spotLights ++;
			if ( light instanceof THREE.HemisphereLight ) hemiLights ++;

		}

3944
		return { 'directional': dirLights, 'point': pointLights, 'spot': spotLights, 'hemi': hemiLights };
M
Mr.doob 已提交
3945

M
Mr.doob 已提交
3946
	}
M
Mr.doob 已提交
3947

M
Mr.doob 已提交
3948
	function allocateShadows( lights ) {
M
Mr.doob 已提交
3949

M
Mr.doob 已提交
3950
		var maxShadows = 0;
M
Mr.doob 已提交
3951

3952
		for ( var l = 0, ll = lights.length; l < ll; l ++ ) {
M
Mr.doob 已提交
3953

M
Mr.doob 已提交
3954
			var light = lights[ l ];
M
Mr.doob 已提交
3955 3956 3957 3958

			if ( ! light.castShadow ) continue;

			if ( light instanceof THREE.SpotLight ) maxShadows ++;
3959
			if ( light instanceof THREE.DirectionalLight ) maxShadows ++;
M
Mr.doob 已提交
3960 3961 3962 3963 3964

		}

		return maxShadows;

3965
	}
M
Mr.doob 已提交
3966

M
Mr.doob 已提交
3967
	// DEPRECATED
3968

3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010
	this.supportsFloatTextures = function () {

		console.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \'OES_texture_float\' ).' );
		return extensions.get( 'OES_texture_float' );

	};

	this.supportsHalfFloatTextures = function () {

		console.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \'OES_texture_half_float\' ).' );
		return extensions.get( 'OES_texture_half_float' );

	};

	this.supportsStandardDerivatives = function () {

		console.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \'OES_standard_derivatives\' ).' );
		return extensions.get( 'OES_standard_derivatives' );

	};

	this.supportsCompressedTextureS3TC = function () {

		console.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \'WEBGL_compressed_texture_s3tc\' ).' );
		return extensions.get( 'WEBGL_compressed_texture_s3tc' );

	};

	this.supportsCompressedTexturePVRTC = function () {

		console.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \'WEBGL_compressed_texture_pvrtc\' ).' );
		return extensions.get( 'WEBGL_compressed_texture_pvrtc' );

	};

	this.supportsBlendMinMax = function () {

		console.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \'EXT_blend_minmax\' ).' );
		return extensions.get( 'EXT_blend_minmax' );

	};

M
Mr.doob 已提交
4011 4012
	this.initMaterial = function () {

4013
		console.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );
M
Mr.doob 已提交
4014 4015

	};
M
Mr.doob 已提交
4016

M
Mr.doob 已提交
4017
	this.addPrePlugin = function () {
M
Mr.doob 已提交
4018

4019
		console.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );
M
Mr.doob 已提交
4020 4021 4022 4023 4024

	};

	this.addPostPlugin = function () {

4025
		console.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );
M
Mr.doob 已提交
4026 4027

	};
M
Mr.doob 已提交
4028

M
Mr.doob 已提交
4029 4030
	this.updateShadowMap = function () {

4031
		console.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );
M
Mr.doob 已提交
4032 4033 4034

	};

4035 4036 4037
	Object.defineProperties( this, {
		shadowMapEnabled: {
			get: function () {
G
gero3 已提交
4038

M
Mr.doob 已提交
4039
				return shadowMap.enabled;
G
gero3 已提交
4040

4041 4042
			},
			set: function ( value ) {
G
gero3 已提交
4043

4044
				console.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );
M
Mr.doob 已提交
4045
				shadowMap.enabled = value;
G
gero3 已提交
4046

4047 4048 4049 4050
			}
		},
		shadowMapType: {
			get: function () {
G
gero3 已提交
4051

M
Mr.doob 已提交
4052
				return shadowMap.type;
G
gero3 已提交
4053

4054 4055
			},
			set: function ( value ) {
G
gero3 已提交
4056

4057
				console.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );
M
Mr.doob 已提交
4058
				shadowMap.type = value;
G
gero3 已提交
4059

4060 4061 4062 4063
			}
		},
		shadowMapCullFace: {
			get: function () {
G
gero3 已提交
4064

M
Mr.doob 已提交
4065
				return shadowMap.cullFace;
G
gero3 已提交
4066

4067 4068
			},
			set: function ( value ) {
G
gero3 已提交
4069

4070
				console.warn( 'THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.' );
M
Mr.doob 已提交
4071
				shadowMap.cullFace = value;
G
gero3 已提交
4072

4073 4074 4075 4076
			}
		},
		shadowMapDebug: {
			get: function () {
G
gero3 已提交
4077

M
Mr.doob 已提交
4078
				return shadowMap.debug;
G
gero3 已提交
4079

4080 4081
			},
			set: function ( value ) {
G
gero3 已提交
4082

4083
				console.warn( 'THREE.WebGLRenderer: .shadowMapDebug is now .shadowMap.debug.' );
M
Mr.doob 已提交
4084
				shadowMap.debug = value;
G
gero3 已提交
4085

4086 4087 4088 4089
			}
		}
	} );

M
Mr.doob 已提交
4090
};