WebGLRenderer.js 162.6 KB
Newer Older
N
Nicolas Garcia Belmonte 已提交
1 2 3
/**
 * @author supereggbert / http://www.paulbrunt.co.uk/
 * @author mrdoob / http://mrdoob.com/
4
 * @author alteredq / http://alteredqualia.com/
5
 * @author szimek / https://github.com/szimek/
N
Nicolas Garcia Belmonte 已提交
6 7
 */

8
THREE.WebGLRenderer = function ( parameters ) {
M
Mr.doob 已提交
9

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

12
	parameters = parameters || {};
M
Mr.doob 已提交
13

14
	var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElement( 'canvas' ),
15

16
	_precision = parameters.precision !== undefined ? parameters.precision : 'highp',
17

18
	_alpha = parameters.alpha !== undefined ? parameters.alpha : true,
19
	_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
20
	_antialias = parameters.antialias !== undefined ? parameters.antialias : false,
21
	_stencil = parameters.stencil !== undefined ? parameters.stencil : true,
22 23
	_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,

24
	_clearColor = parameters.clearColor !== undefined ? new THREE.Color( parameters.clearColor ) : new THREE.Color( 0x000000 ),
M
Mr.doob 已提交
25 26
	_clearAlpha = parameters.clearAlpha !== undefined ? parameters.clearAlpha : 0,

27
	_maxLights = parameters.maxLights !== undefined ? parameters.maxLights : 4;
28

29
	// public properties
M
Mr.doob 已提交
30

N
Nicolas Garcia Belmonte 已提交
31
	this.domElement = _canvas;
32 33 34
	this.context = null;

	// clearing
M
Mr.doob 已提交
35

N
Nicolas Garcia Belmonte 已提交
36
	this.autoClear = true;
M
Mr.doob 已提交
37 38 39 40
	this.autoClearColor = true;
	this.autoClearDepth = true;
	this.autoClearStencil = true;

41 42
	// scene graph

43
	this.sortObjects = true;
N
Nicolas Garcia Belmonte 已提交
44

45
	this.autoUpdateObjects = true;
46
	this.autoUpdateScene = true;
47 48 49 50 51 52 53

	// physically based shading

	this.gammaInput = false;
	this.gammaOutput = false;
	this.physicallyBasedShading = false;

54 55 56
	// shadow map

	this.shadowMapEnabled = false;
57
	this.shadowMapAutoUpdate = true;
58
	this.shadowMapSoft = true;
A
alteredq 已提交
59
	this.shadowMapCullFrontFaces = true;
A
alteredq 已提交
60 61
	this.shadowMapDebug = false;
	this.shadowMapCascade = false;
62

63
	// morphs
64

65
	this.maxMorphTargets = 8;
A
alteredq 已提交
66
	this.maxMorphNormals = 4;
67

68 69 70 71
	// flags

	this.autoScaleCubemaps = true;

72 73
	// custom render plugins

A
alteredq 已提交
74 75
	this.renderPluginsPre = [];
	this.renderPluginsPost = [];
76

77
	// info
78

79
	this.info = {
80

81
		memory: {
82

83 84 85
			programs: 0,
			geometries: 0,
			textures: 0
86

87
		},
88

89
		render: {
90

91 92
			calls: 0,
			vertices: 0,
93 94
			faces: 0,
			points: 0
95 96 97

		}

98
	};
M
Mr.doob 已提交
99

100
	// internal properties
101

102
	var _this = this,
103

104
	_programs = [],
A
alteredq 已提交
105
	_programs_counter = 0,
106

107
	// internal state cache
108

109 110 111 112
	_currentProgram = null,
	_currentFramebuffer = null,
	_currentMaterialId = -1,
	_currentGeometryGroupHash = null,
113
	_currentCamera = null,
114
	_geometryGroupCounter = 0,
115

116 117
	_usedTextureUnits = 0,

118
	// GL state cache
119

120 121
	_oldDoubleSided = -1,
	_oldFlipSided = -1,
122

123
	_oldBlending = -1,
124

125 126 127
	_oldBlendEquation = -1,
	_oldBlendSrc = -1,
	_oldBlendDst = -1,
128

129 130
	_oldDepthTest = -1,
	_oldDepthWrite = -1,
131

132 133 134
	_oldPolygonOffset = null,
	_oldPolygonOffsetFactor = null,
	_oldPolygonOffsetUnits = null,
135

136
	_oldLineWidth = null,
137

138 139 140 141
	_viewportX = 0,
	_viewportY = 0,
	_viewportWidth = 0,
	_viewportHeight = 0,
A
alteredq 已提交
142 143
	_currentWidth = 0,
	_currentHeight = 0,
144

A
alteredq 已提交
145
	// frustum
M
Mr.doob 已提交
146

A
alteredq 已提交
147
	_frustum = new THREE.Frustum(),
148

149
	 // camera matrices cache
M
Mikael Emtinger 已提交
150

151
	_projScreenMatrix = new THREE.Matrix4(),
A
alteredq 已提交
152
	_projScreenMatrixPS = new THREE.Matrix4(),
M
Mr.doob 已提交
153

154
	_vector3 = new THREE.Vector4(),
M
Mikael Emtinger 已提交
155

156
	// light arrays cache
M
Mikael Emtinger 已提交
157

158 159
	_direction = new THREE.Vector3(),

160 161
	_lightsNeedUpdate = true,

162
	_lights = {
M
Mr.doob 已提交
163

164 165
		ambient: [ 0, 0, 0 ],
		directional: { length: 0, colors: new Array(), positions: new Array() },
A
alteredq 已提交
166
		point: { length: 0, colors: new Array(), positions: new Array(), distances: new Array() },
A
alteredq 已提交
167 168
		spot: { length: 0, colors: new Array(), positions: new Array(), distances: new Array(), directions: new Array(), angles: new Array(), exponents: new Array() },
		hemi: { length: 0, skyColors: new Array(), groundColors: new Array(), positions: new Array() }
M
Mr.doob 已提交
169

170
	};
M
Mr.doob 已提交
171

172
	// initialize
M
Mikael Emtinger 已提交
173

174
	var _gl;
A
alteredq 已提交
175

176
	var _glExtensionTextureFloat;
A
alteredq 已提交
177
	var _glExtensionStandardDerivatives;
178
	var _glExtensionTextureFilterAnisotropic;
179
	var _glExtensionCompressedTextureS3TC;
180 181

	initGL();
M
Mikael Emtinger 已提交
182

183
	setDefaultGLState();
M
Mikael Emtinger 已提交
184

185
	this.context = _gl;
M
Mikael Emtinger 已提交
186

187 188
	// GPU capabilities

189 190 191 192
	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 );
M
Mr.doob 已提交
193

194 195
	var _maxAnisotropy = _glExtensionTextureFilterAnisotropic ? _gl.getParameter( _glExtensionTextureFilterAnisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT ) : 0;

196 197 198
	var _supportsVertexTextures = ( _maxVertexTextures > 0 );
	var _supportsBoneTextures = _supportsVertexTextures && _glExtensionTextureFloat;

199 200
	var _compressedTextureFormats = _glExtensionCompressedTextureS3TC ? _gl.getParameter( _gl.COMPRESSED_TEXTURE_FORMATS ) : [];

201
	// API
M
Mr.doob 已提交
202

203
	this.getContext = function () {
M
Mr.doob 已提交
204

205
		return _gl;
M
Mr.doob 已提交
206

207
	};
M
Mr.doob 已提交
208

209
	this.supportsVertexTextures = function () {
M
Mikael Emtinger 已提交
210

211
		return _supportsVertexTextures;
M
Mikael Emtinger 已提交
212

213
	};
M
Mikael Emtinger 已提交
214

215 216 217 218 219 220
	this.getMaxAnisotropy  = function () {

		return _maxAnisotropy;

	};

N
Nicolas Garcia Belmonte 已提交
221 222 223 224
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
225

226 227 228
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
229

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

232 233
		_viewportX = x !== undefined ? x : 0;
		_viewportY = y !== undefined ? y : 0;
234

235 236
		_viewportWidth = width !== undefined ? width : _canvas.width;
		_viewportHeight = height !== undefined ? height : _canvas.height;
237

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

N
Nicolas Garcia Belmonte 已提交
240
	};
241

242
	this.setScissor = function ( x, y, width, height ) {
N
Nicolas Garcia Belmonte 已提交
243

244
		_gl.scissor( x, y, width, height );
245

246
	};
247

248
	this.enableScissorTest = function ( enable ) {
249

M
Mr.doob 已提交
250
		enable ? _gl.enable( _gl.SCISSOR_TEST ) : _gl.disable( _gl.SCISSOR_TEST );
251 252

	};
253

254 255
	// Clearing

256
	this.setClearColorHex = function ( hex, alpha ) {
257

258 259 260 261
		_clearColor.setHex( hex );
		_clearAlpha = alpha;

		_gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
262

263
	};
A
alteredq 已提交
264

265
	this.setClearColor = function ( color, alpha ) {
A
alteredq 已提交
266

267 268 269 270
		_clearColor.copy( color );
		_clearAlpha = alpha;

		_gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
A
alteredq 已提交
271 272

	};
273

M
Mr.doob 已提交
274 275 276 277 278 279 280
	this.getClearColor = function () {

		return _clearColor;

	};

	this.getClearAlpha = function () {
N
Nicolas Garcia Belmonte 已提交
281

M
Mr.doob 已提交
282 283 284 285 286 287 288 289
		return _clearAlpha;

	};

	this.clear = function ( color, depth, stencil ) {

		var bits = 0;

290 291 292
		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;
M
Mr.doob 已提交
293 294

		_gl.clear( bits );
N
Nicolas Garcia Belmonte 已提交
295 296 297

	};

298
	this.clearTarget = function ( renderTarget, color, depth, stencil ) {
M
Mr.doob 已提交
299

A
alteredq 已提交
300
		this.setRenderTarget( renderTarget );
301
		this.clear( color, depth, stencil );
M
Mr.doob 已提交
302 303 304

	};

305 306
	// Plugins

A
alteredq 已提交
307
	this.addPostPlugin = function ( plugin ) {
308 309

		plugin.init( this );
A
alteredq 已提交
310
		this.renderPluginsPost.push( plugin );
311 312 313

	};

A
alteredq 已提交
314 315 316 317 318 319
	this.addPrePlugin = function ( plugin ) {

		plugin.init( this );
		this.renderPluginsPre.push( plugin );

	};
320

321 322
	// Deallocation

323 324 325 326 327 328 329
	this.deallocateObject = function ( object ) {

		if ( ! object.__webglInit ) return;

		object.__webglInit = false;

		delete object._modelViewMatrix;
330
		delete object._normalMatrix;
331 332 333

		delete object._normalMatrixArray;
		delete object._modelViewMatrixArray;
334
		delete object._modelMatrixArray;
335 336 337

		if ( object instanceof THREE.Mesh ) {

338
			for ( var g in object.geometry.geometryGroups ) {
339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366

				deleteMeshBuffers( object.geometry.geometryGroups[ g ] );

			}

		} else if ( object instanceof THREE.Ribbon ) {

			deleteRibbonBuffers( object.geometry );

		} else if ( object instanceof THREE.Line ) {

			deleteLineBuffers( object.geometry );

		} else if ( object instanceof THREE.ParticleSystem ) {

			deleteParticleBuffers( object.geometry );

		}

	};

	this.deallocateTexture = function ( texture ) {

		if ( ! texture.__webglInit ) return;

		texture.__webglInit = false;
		_gl.deleteTexture( texture.__webglTexture );

M
Mr.doob 已提交
367 368
		_this.info.memory.textures --;

369 370
	};

371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394
	this.deallocateRenderTarget = function ( renderTarget ) {

		if ( !renderTarget || ! renderTarget.__webglTexture ) return;

		_gl.deleteTexture( renderTarget.__webglTexture );

		if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {

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

				_gl.deleteFramebuffer( renderTarget.__webglFramebuffer[ i ] );
				_gl.deleteRenderbuffer( renderTarget.__webglRenderbuffer[ i ] );

			}

		} else {

			_gl.deleteFramebuffer( renderTarget.__webglFramebuffer );
			_gl.deleteRenderbuffer( renderTarget.__webglRenderbuffer );

		}

	};

A
alteredq 已提交
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
	this.deallocateMaterial = function ( material ) {

		var program = material.program;

		if ( ! program ) return;

		material.program = undefined;

		// only deallocate GL program if this was the last use of shared program
		// assumed there is only single copy of any program in the _programs list
		// (that's how it's constructed)

		var i, il, programInfo;
		var deleteProgram = false;

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

			programInfo = _programs[ i ];

			if ( programInfo.program === program ) {

				programInfo.usedTimes --;

				if ( programInfo.usedTimes === 0 ) {

					deleteProgram = true;

				}

				break;

			}

		}

		if ( deleteProgram ) {

			// avoid using array.splice, this is costlier than creating new array from scratch

			var newPrograms = [];

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

				programInfo = _programs[ i ];

				if ( programInfo.program !== program ) {

					newPrograms.push( programInfo );

				}

			}

			_programs = newPrograms;

			_gl.deleteProgram( program );

			_this.info.memory.programs --;

		}

	};

458
	// Rendering
459

460
	this.updateShadowMap = function ( scene, camera ) {
461

A
alteredq 已提交
462 463 464 465 466 467
		_currentProgram = null;
		_oldBlending = -1;
		_oldDepthTest = -1;
		_oldDepthWrite = -1;
		_currentGeometryGroupHash = -1;
		_currentMaterialId = -1;
468 469 470
		_lightsNeedUpdate = true;
		_oldDoubleSided = -1;
		_oldFlipSided = -1;
A
alteredq 已提交
471 472

		this.shadowMapPlugin.update( scene, camera );
M
Mr.doob 已提交
473

474
	};
M
Mr.doob 已提交
475

476
	// Internal functions
477

478
	// Buffer allocation
479

480
	function createParticleBuffers ( geometry ) {
481

482 483
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
484

485
		_this.info.geometries ++;
486

487
	};
488

489
	function createLineBuffers ( geometry ) {
490

491 492
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
493

494
		_this.info.memory.geometries ++;
495

496
	};
497

498
	function createRibbonBuffers ( geometry ) {
499

500 501
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
502

503
		_this.info.memory.geometries ++;
M
Mr.doob 已提交
504

505
	};
506

507
	function createMeshBuffers ( geometryGroup ) {
508

509 510 511 512 513 514
		geometryGroup.__webglVertexBuffer = _gl.createBuffer();
		geometryGroup.__webglNormalBuffer = _gl.createBuffer();
		geometryGroup.__webglTangentBuffer = _gl.createBuffer();
		geometryGroup.__webglColorBuffer = _gl.createBuffer();
		geometryGroup.__webglUVBuffer = _gl.createBuffer();
		geometryGroup.__webglUV2Buffer = _gl.createBuffer();
515

516 517
		geometryGroup.__webglSkinIndicesBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinWeightsBuffer = _gl.createBuffer();
518

519 520
		geometryGroup.__webglFaceBuffer = _gl.createBuffer();
		geometryGroup.__webglLineBuffer = _gl.createBuffer();
521

522
		var m, ml;
523

524
		if ( geometryGroup.numMorphTargets ) {
525

526
			geometryGroup.__webglMorphTargetsBuffers = [];
527

528
			for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
M
Mr.doob 已提交
529

530
				geometryGroup.__webglMorphTargetsBuffers.push( _gl.createBuffer() );
531 532 533 534 535 536 537 538 539 540 541

			}

		}

		if ( geometryGroup.numMorphNormals ) {

			geometryGroup.__webglMorphNormalsBuffers = [];

			for ( m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {

A
alteredq 已提交
542
				geometryGroup.__webglMorphNormalsBuffers.push( _gl.createBuffer() );
543

544
			}
545

546
		}
547

548
		_this.info.memory.geometries ++;
549

550
	};
551

552
	// Buffer deallocation
553

554
	function deleteParticleBuffers ( geometry ) {
555

556 557
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
558

559
		_this.info.memory.geometries --;
560

561
	};
562

563
	function deleteLineBuffers ( geometry ) {
564

565 566
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
567

M
Mr.doob 已提交
568 569
		_this.info.memory.geometries --;

570 571
	};

572
	function deleteRibbonBuffers ( geometry ) {
573 574 575 576

		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );

M
Mr.doob 已提交
577 578
		_this.info.memory.geometries --;

579 580
	};

581
	function deleteMeshBuffers ( geometryGroup ) {
582 583 584 585 586 587 588 589 590 591 592 593 594 595

		_gl.deleteBuffer( geometryGroup.__webglVertexBuffer );
		_gl.deleteBuffer( geometryGroup.__webglNormalBuffer );
		_gl.deleteBuffer( geometryGroup.__webglTangentBuffer );
		_gl.deleteBuffer( geometryGroup.__webglColorBuffer );
		_gl.deleteBuffer( geometryGroup.__webglUVBuffer );
		_gl.deleteBuffer( geometryGroup.__webglUV2Buffer );

		_gl.deleteBuffer( geometryGroup.__webglSkinIndicesBuffer );
		_gl.deleteBuffer( geometryGroup.__webglSkinWeightsBuffer );

		_gl.deleteBuffer( geometryGroup.__webglFaceBuffer );
		_gl.deleteBuffer( geometryGroup.__webglLineBuffer );

596 597
		var m, ml;

598 599
		if ( geometryGroup.numMorphTargets ) {

600
			for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
601 602

				_gl.deleteBuffer( geometryGroup.__webglMorphTargetsBuffers[ m ] );
603 604 605 606 607 608 609 610 611

			}

		}

		if ( geometryGroup.numMorphNormals ) {

			for ( m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {

A
alteredq 已提交
612
				_gl.deleteBuffer( geometryGroup.__webglMorphNormalsBuffers[ m ] );
613 614 615 616 617

			}

		}

618 619 620 621 622 623 624 625 626 627 628

		if ( geometryGroup.__webglCustomAttributesList ) {

			for ( var id in geometryGroup.__webglCustomAttributesList ) {

				_gl.deleteBuffer( geometryGroup.__webglCustomAttributesList[ id ].buffer );

			}

		}

M
Mr.doob 已提交
629 630
		_this.info.memory.geometries --;

631 632
	};

633
	// Buffer initialization
634

A
alteredq 已提交
635
	function initCustomAttributes ( geometry, object ) {
M
Mr.doob 已提交
636

637 638
		var nvertices = geometry.vertices.length;

639
		var material = object.material;
640

641
		if ( material.attributes ) {
642

643
			if ( geometry.__webglCustomAttributesList === undefined ) {
644

645
				geometry.__webglCustomAttributesList = [];
646

647
			}
648

649
			for ( var a in material.attributes ) {
650

651
				var attribute = material.attributes[ a ];
652

653
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
654

655
					attribute.__webglInitialized = true;
656

A
alteredq 已提交
657
					var size = 1;		// "f" and "i"
658

659 660 661 662
					if ( attribute.type === "v2" ) size = 2;
					else if ( attribute.type === "v3" ) size = 3;
					else if ( attribute.type === "v4" ) size = 4;
					else if ( attribute.type === "c"  ) size = 3;
663

664
					attribute.size = size;
A
alteredq 已提交
665

666
					attribute.array = new Float32Array( nvertices * size );
A
alteredq 已提交
667

668 669
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
670

671
					attribute.needsUpdate = true;
672

673
				}
674

675
				geometry.__webglCustomAttributesList.push( attribute );
676

677
			}
678

679
		}
680

681
	};
682

683
	function initParticleBuffers ( geometry, object ) {
A
alteredq 已提交
684 685 686 687 688 689

		var nvertices = geometry.vertices.length;

		geometry.__vertexArray = new Float32Array( nvertices * 3 );
		geometry.__colorArray = new Float32Array( nvertices * 3 );

690 691 692
		geometry.__sortArray = [];

		geometry.__webglParticleCount = nvertices;
A
alteredq 已提交
693 694 695 696 697

		initCustomAttributes ( geometry, object );

	};

698
	function initLineBuffers ( geometry, object ) {
A
alteredq 已提交
699 700 701 702 703 704

		var nvertices = geometry.vertices.length;

		geometry.__vertexArray = new Float32Array( nvertices * 3 );
		geometry.__colorArray = new Float32Array( nvertices * 3 );

705
		geometry.__webglLineCount = nvertices;
A
alteredq 已提交
706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721

		initCustomAttributes ( geometry, object );

	};

	function initRibbonBuffers ( geometry ) {

		var nvertices = geometry.vertices.length;

		geometry.__vertexArray = new Float32Array( nvertices * 3 );
		geometry.__colorArray = new Float32Array( nvertices * 3 );

		geometry.__webglVertexCount = nvertices;

	};

M
Mr.doob 已提交
722
	function initMeshBuffers ( geometryGroup, object ) {
M
Mr.doob 已提交
723

724 725 726
		var geometry = object.geometry,
			faces3 = geometryGroup.faces3,
			faces4 = geometryGroup.faces4,
M
Mr.doob 已提交
727

728 729 730
			nvertices = faces3.length * 3 + faces4.length * 4,
			ntris     = faces3.length * 1 + faces4.length * 2,
			nlines    = faces3.length * 3 + faces4.length * 4,
731

732
			material = getBufferMaterial( object, geometryGroup ),
733

734 735 736
			uvType = bufferGuessUVType( material ),
			normalType = bufferGuessNormalType( material ),
			vertexColorType = bufferGuessVertexColorType( material );
A
alteredq 已提交
737

738
		//console.log( "uvType", uvType, "normalType", normalType, "vertexColorType", vertexColorType, object, geometryGroup, material );
M
Mr.doob 已提交
739

740
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
741

742
		if ( normalType ) {
M
Mr.doob 已提交
743

744
			geometryGroup.__normalArray = new Float32Array( nvertices * 3 );
M
Mr.doob 已提交
745

746
		}
747

748
		if ( geometry.hasTangents ) {
749

750
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
751

752
		}
753

754
		if ( vertexColorType ) {
755

756
			geometryGroup.__colorArray = new Float32Array( nvertices * 3 );
M
Mr.doob 已提交
757

758
		}
M
Mr.doob 已提交
759

760
		if ( uvType ) {
761

762
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
763

764 765 766 767 768
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

			if ( geometry.faceUvs.length > 1 || geometry.faceVertexUvs.length > 1 ) {
769

770 771 772 773 774 775 776 777 778 779 780 781 782
				geometryGroup.__uv2Array = new Float32Array( nvertices * 2 );

			}

		}

		if ( object.geometry.skinWeights.length && object.geometry.skinIndices.length ) {

			geometryGroup.__skinIndexArray = new Float32Array( nvertices * 4 );
			geometryGroup.__skinWeightArray = new Float32Array( nvertices * 4 );

		}

783
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
784
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
785

786 787
		var m, ml;

788 789
		if ( geometryGroup.numMorphTargets ) {

M
Mr.doob 已提交
790
			geometryGroup.__morphTargetsArrays = [];
791

792
			for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
793

794
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );
795 796 797 798 799 800 801 802 803 804 805

			}

		}

		if ( geometryGroup.numMorphNormals ) {

			geometryGroup.__morphNormalsArrays = [];

			for ( m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {

A
alteredq 已提交
806
				geometryGroup.__morphNormalsArrays.push( new Float32Array( nvertices * 3 ) );
807

808 809 810
			}

		}
811

812
		geometryGroup.__webglFaceCount = ntris * 3;
813
		geometryGroup.__webglLineCount = nlines * 2;
814

M
Mr.doob 已提交
815

816
		// custom attributes
M
Mr.doob 已提交
817

818
		if ( material.attributes ) {
819

820
			if ( geometryGroup.__webglCustomAttributesList === undefined ) {
821

822
				geometryGroup.__webglCustomAttributesList = [];
823

824
			}
825

826
			for ( var a in material.attributes ) {
M
Mr.doob 已提交
827

828 829
				// Do a shallow copy of the attribute object so different geometryGroup chunks use different
				// attribute buffers which are correctly indexed in the setMeshBuffers function
830

831
				var originalAttribute = material.attributes[ a ];
832

833
				var attribute = {};
834

835
				for ( var property in originalAttribute ) {
M
Mr.doob 已提交
836

837
					attribute[ property ] = originalAttribute[ property ];
838

839
				}
840

841
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
842

843
					attribute.__webglInitialized = true;
844

845
					var size = 1;		// "f" and "i"
M
Mr.doob 已提交
846

847 848 849 850
					if( attribute.type === "v2" ) size = 2;
					else if( attribute.type === "v3" ) size = 3;
					else if( attribute.type === "v4" ) size = 4;
					else if( attribute.type === "c"  ) size = 3;
851

852
					attribute.size = size;
A
alteredq 已提交
853

854
					attribute.array = new Float32Array( nvertices * size );
A
alteredq 已提交
855

856 857
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
858

859 860
					originalAttribute.needsUpdate = true;
					attribute.__original = originalAttribute;
861 862 863

				}

864 865
				geometryGroup.__webglCustomAttributesList.push( attribute );

866
			}
M
Mr.doob 已提交
867

868
		}
869

870 871
		geometryGroup.__inittedArrays = true;

872
	};
M
Mr.doob 已提交
873

874
	function getBufferMaterial( object, geometryGroup ) {
875

876
		if ( object.material && ! ( object.material instanceof THREE.MeshFaceMaterial ) ) {
877

878
			return object.material;
879

880
		} else if ( geometryGroup.materialIndex >= 0 ) {
881

882
			return object.geometry.materials[ geometryGroup.materialIndex ];
M
Mr.doob 已提交
883

884
		}
885

886
	};
M
Mr.doob 已提交
887

888
	function materialNeedsSmoothNormals ( material ) {
889

890
		return material && material.shading !== undefined && material.shading === THREE.SmoothShading;
891

892
	};
M
Mr.doob 已提交
893

894
	function bufferGuessNormalType ( material ) {
895

896
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
897

898
		if ( ( material instanceof THREE.MeshBasicMaterial && !material.envMap ) || material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
899

900
			return false;
901

902
		}
903

904
		if ( materialNeedsSmoothNormals( material ) ) {
905

906
			return THREE.SmoothShading;
M
Mr.doob 已提交
907

908
		} else {
909

910
			return THREE.FlatShading;
911

912
		}
913

914
	};
915

916
	function bufferGuessVertexColorType ( material ) {
917

918
		if ( material.vertexColors ) {
919

920
			return material.vertexColors;
921

922
		}
M
Mr.doob 已提交
923

924
		return false;
M
Mr.doob 已提交
925

926
	};
M
Mr.doob 已提交
927

928
	function bufferGuessUVType ( material ) {
929

930 931
		// material must use some texture to require uvs

932
		if ( material.map || material.lightMap || material.bumpMap || material.normalMap || material.specularMap || material instanceof THREE.ShaderMaterial ) {
933 934 935 936 937 938 939 940 941

			return true;

		}

		return false;

	};

942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970
	//

	function initDirectBuffers( geometry ) {

		var a, attribute, type;

		for ( a in geometry.attributes ) {

			if ( a === "index" ) {

				type = _gl.ELEMENT_ARRAY_BUFFER;

			} else {

				type = _gl.ARRAY_BUFFER;

			}

			attribute = geometry.attributes[ a ];

			attribute.buffer = _gl.createBuffer();

			_gl.bindBuffer( type, attribute.buffer );
			_gl.bufferData( type, attribute.array, _gl.STATIC_DRAW );

		}

	};

971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987
	// Buffer setting

	function setParticleBuffers ( geometry, hint, object ) {

		var v, c, vertex, offset, index, color,

		vertices = geometry.vertices,
		vl = vertices.length,

		colors = geometry.colors,
		cl = colors.length,

		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,

		sortArray = geometry.__sortArray,

988
		dirtyVertices = geometry.verticesNeedUpdate,
M
Mr.doob 已提交
989
		dirtyElements = geometry.elementsNeedUpdate,
M
Mr.doob 已提交
990
		dirtyColors = geometry.colorsNeedUpdate,
991 992 993 994 995 996 997 998

		customAttributes = geometry.__webglCustomAttributesList,
		i, il,
		a, ca, cal, value,
		customAttribute;

		if ( object.sortParticles ) {

A
alteredq 已提交
999 1000
			_projScreenMatrixPS.copy( _projScreenMatrix );
			_projScreenMatrixPS.multiplySelf( object.matrixWorld );
1001 1002 1003

			for ( v = 0; v < vl; v ++ ) {

1004
				vertex = vertices[ v ];
1005 1006

				_vector3.copy( vertex );
A
alteredq 已提交
1007
				_projScreenMatrixPS.multiplyVector3( _vector3 );
1008 1009 1010 1011 1012 1013 1014 1015 1016

				sortArray[ v ] = [ _vector3.z, v ];

			}

			sortArray.sort( function( a, b ) { return b[ 0 ] - a[ 0 ]; } );

			for ( v = 0; v < vl; v ++ ) {

1017
				vertex = vertices[ sortArray[v][1] ];
1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140

				offset = v * 3;

				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;

			}

			for ( c = 0; c < cl; c ++ ) {

				offset = c * 3;

				color = colors[ sortArray[c][1] ];

				colorArray[ offset ]     = color.r;
				colorArray[ offset + 1 ] = color.g;
				colorArray[ offset + 2 ] = color.b;

			}

			if ( customAttributes ) {

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

					customAttribute = customAttributes[ i ];

					if ( ! ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) ) continue;

					offset = 0;

					cal = customAttribute.value.length;

					if ( customAttribute.size === 1 ) {

						for ( ca = 0; ca < cal; ca ++ ) {

							index = sortArray[ ca ][ 1 ];

							customAttribute.array[ ca ] = customAttribute.value[ index ];

						}

					} else if ( customAttribute.size === 2 ) {

						for ( ca = 0; ca < cal; ca ++ ) {

							index = sortArray[ ca ][ 1 ];

							value = customAttribute.value[ index ];

							customAttribute.array[ offset ] 	= value.x;
							customAttribute.array[ offset + 1 ] = value.y;

							offset += 2;

						}

					} else if ( customAttribute.size === 3 ) {

						if ( customAttribute.type === "c" ) {

							for ( ca = 0; ca < cal; ca ++ ) {

								index = sortArray[ ca ][ 1 ];

								value = customAttribute.value[ index ];

								customAttribute.array[ offset ]     = value.r;
								customAttribute.array[ offset + 1 ] = value.g;
								customAttribute.array[ offset + 2 ] = value.b;

								offset += 3;

							}

						} else {

							for ( ca = 0; ca < cal; ca ++ ) {

								index = sortArray[ ca ][ 1 ];

								value = customAttribute.value[ index ];

								customAttribute.array[ offset ] 	= value.x;
								customAttribute.array[ offset + 1 ] = value.y;
								customAttribute.array[ offset + 2 ] = value.z;

								offset += 3;

							}

						}

					} else if ( customAttribute.size === 4 ) {

						for ( ca = 0; ca < cal; ca ++ ) {

							index = sortArray[ ca ][ 1 ];

							value = customAttribute.value[ index ];

							customAttribute.array[ offset ]      = value.x;
							customAttribute.array[ offset + 1  ] = value.y;
							customAttribute.array[ offset + 2  ] = value.z;
							customAttribute.array[ offset + 3  ] = value.w;

							offset += 4;

						}

					}

				}

			}

		} else {

			if ( dirtyVertices ) {

				for ( v = 0; v < vl; v ++ ) {

1141
					vertex = vertices[ v ];
1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175

					offset = v * 3;

					vertexArray[ offset ]     = vertex.x;
					vertexArray[ offset + 1 ] = vertex.y;
					vertexArray[ offset + 2 ] = vertex.z;

				}

			}

			if ( dirtyColors ) {

				for ( c = 0; c < cl; c ++ ) {

					color = colors[ c ];

					offset = c * 3;

					colorArray[ offset ]     = color.r;
					colorArray[ offset + 1 ] = color.g;
					colorArray[ offset + 2 ] = color.b;

				}

			}

			if ( customAttributes ) {

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

					customAttribute = customAttributes[ i ];

					if ( customAttribute.needsUpdate &&
1176
						 ( customAttribute.boundTo === undefined ||
1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306
						   customAttribute.boundTo === "vertices") ) {

						cal = customAttribute.value.length;

						offset = 0;

						if ( customAttribute.size === 1 ) {

							for ( ca = 0; ca < cal; ca ++ ) {

								customAttribute.array[ ca ] = customAttribute.value[ ca ];

							}

						} else if ( customAttribute.size === 2 ) {

							for ( ca = 0; ca < cal; ca ++ ) {

								value = customAttribute.value[ ca ];

								customAttribute.array[ offset ] 	= value.x;
								customAttribute.array[ offset + 1 ] = value.y;

								offset += 2;

							}

						} else if ( customAttribute.size === 3 ) {

							if ( customAttribute.type === "c" ) {

								for ( ca = 0; ca < cal; ca ++ ) {

									value = customAttribute.value[ ca ];

									customAttribute.array[ offset ] 	= value.r;
									customAttribute.array[ offset + 1 ] = value.g;
									customAttribute.array[ offset + 2 ] = value.b;

									offset += 3;

								}

							} else {

								for ( ca = 0; ca < cal; ca ++ ) {

									value = customAttribute.value[ ca ];

									customAttribute.array[ offset ] 	= value.x;
									customAttribute.array[ offset + 1 ] = value.y;
									customAttribute.array[ offset + 2 ] = value.z;

									offset += 3;

								}

							}

						} else if ( customAttribute.size === 4 ) {

							for ( ca = 0; ca < cal; ca ++ ) {

								value = customAttribute.value[ ca ];

								customAttribute.array[ offset ]      = value.x;
								customAttribute.array[ offset + 1  ] = value.y;
								customAttribute.array[ offset + 2  ] = value.z;
								customAttribute.array[ offset + 3  ] = value.w;

								offset += 4;

							}

						}

					}

				}

			}

		}

		if ( dirtyVertices || object.sortParticles ) {

			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

		}

		if ( dirtyColors || object.sortParticles ) {

			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

		if ( customAttributes ) {

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

				customAttribute = customAttributes[ i ];

				if ( customAttribute.needsUpdate || object.sortParticles ) {

					_gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
					_gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );

				}

			}

		}


	};

	function setLineBuffers ( geometry, hint ) {

		var v, c, vertex, offset, color,

		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,

		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,

1307
		dirtyVertices = geometry.verticesNeedUpdate,
M
Mr.doob 已提交
1308
		dirtyColors = geometry.colorsNeedUpdate,
1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319

		customAttributes = geometry.__webglCustomAttributesList,

		i, il,
		a, ca, cal, value,
		customAttribute;

		if ( dirtyVertices ) {

			for ( v = 0; v < vl; v ++ ) {

1320
				vertex = vertices[ v ];
1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460

				offset = v * 3;

				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;

			}

			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

		}

		if ( dirtyColors ) {

			for ( c = 0; c < cl; c ++ ) {

				color = colors[ c ];

				offset = c * 3;

				colorArray[ offset ]     = color.r;
				colorArray[ offset + 1 ] = color.g;
				colorArray[ offset + 2 ] = color.b;

			}

			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

		if ( customAttributes ) {

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

				customAttribute = customAttributes[ i ];

				if ( customAttribute.needsUpdate &&
					 ( customAttribute.boundTo === undefined ||
					   customAttribute.boundTo === "vertices" ) ) {

					offset = 0;

					cal = customAttribute.value.length;

					if ( customAttribute.size === 1 ) {

						for ( ca = 0; ca < cal; ca ++ ) {

							customAttribute.array[ ca ] = customAttribute.value[ ca ];

						}

					} else if ( customAttribute.size === 2 ) {

						for ( ca = 0; ca < cal; ca ++ ) {

							value = customAttribute.value[ ca ];

							customAttribute.array[ offset ] 	= value.x;
							customAttribute.array[ offset + 1 ] = value.y;

							offset += 2;

						}

					} else if ( customAttribute.size === 3 ) {

						if ( customAttribute.type === "c" ) {

							for ( ca = 0; ca < cal; ca ++ ) {

								value = customAttribute.value[ ca ];

								customAttribute.array[ offset ] 	= value.r;
								customAttribute.array[ offset + 1 ] = value.g;
								customAttribute.array[ offset + 2 ] = value.b;

								offset += 3;

							}

						} else {

							for ( ca = 0; ca < cal; ca ++ ) {

								value = customAttribute.value[ ca ];

								customAttribute.array[ offset ] 	= value.x;
								customAttribute.array[ offset + 1 ] = value.y;
								customAttribute.array[ offset + 2 ] = value.z;

								offset += 3;

							}

						}

					} else if ( customAttribute.size === 4 ) {

						for ( ca = 0; ca < cal; ca ++ ) {

							value = customAttribute.value[ ca ];

							customAttribute.array[ offset ] 	 = value.x;
							customAttribute.array[ offset + 1  ] = value.y;
							customAttribute.array[ offset + 2  ] = value.z;
							customAttribute.array[ offset + 3  ] = value.w;

							offset += 4;

						}

					}

					_gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
					_gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );

				}

			}

		}

	};

	function setRibbonBuffers ( geometry, hint ) {

		var v, c, vertex, offset, color,

		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,

		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,

1461
		dirtyVertices = geometry.verticesNeedUpdate,
M
Mr.doob 已提交
1462
		dirtyColors = geometry.colorsNeedUpdate;
1463 1464 1465 1466 1467

		if ( dirtyVertices ) {

			for ( v = 0; v < vl; v ++ ) {

1468
				vertex = vertices[ v ];
1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503

				offset = v * 3;

				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;

			}

			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

		}

		if ( dirtyColors ) {

			for ( c = 0; c < cl; c ++ ) {

				color = colors[ c ];

				offset = c * 3;

				colorArray[ offset ]     = color.r;
				colorArray[ offset + 1 ] = color.g;
				colorArray[ offset + 2 ] = color.b;

			}

			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

	};

1504
	function setMeshBuffers( geometryGroup, object, hint, dispose, material ) {
1505 1506 1507 1508 1509 1510 1511 1512

		if ( ! geometryGroup.__inittedArrays ) {

			// console.log( object );
			return;

		}

1513 1514 1515 1516 1517 1518
		var normalType = bufferGuessNormalType( material ),
		vertexColorType = bufferGuessVertexColorType( material ),
		uvType = bufferGuessUVType( material ),

		needsSmoothNormals = ( normalType === THREE.SmoothShading );

1519 1520 1521 1522
		var f, fl, fi, face,
		vertexNormals, faceNormal, normal,
		vertexColors, faceColor,
		vertexTangents,
A
alteredq 已提交
1523
		uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4, n1, n2, n3, n4,
1524 1525 1526 1527 1528 1529 1530 1531
		c1, c2, c3, c4,
		sw1, sw2, sw3, sw4,
		si1, si2, si3, si4,
		sa1, sa2, sa3, sa4,
		sb1, sb2, sb3, sb4,
		m, ml, i, il,
		vn, uvi, uv2i,
		vk, vkl, vka,
A
alteredq 已提交
1532
		nka, chf, faceVertexNormals,
1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562
		a,

		vertexIndex = 0,

		offset = 0,
		offset_uv = 0,
		offset_uv2 = 0,
		offset_face = 0,
		offset_normal = 0,
		offset_tangent = 0,
		offset_line = 0,
		offset_color = 0,
		offset_skin = 0,
		offset_morphTarget = 0,
		offset_custom = 0,
		offset_customSrc = 0,

		value,

		vertexArray = geometryGroup.__vertexArray,
		uvArray = geometryGroup.__uvArray,
		uv2Array = geometryGroup.__uv2Array,
		normalArray = geometryGroup.__normalArray,
		tangentArray = geometryGroup.__tangentArray,
		colorArray = geometryGroup.__colorArray,

		skinIndexArray = geometryGroup.__skinIndexArray,
		skinWeightArray = geometryGroup.__skinWeightArray,

		morphTargetsArrays = geometryGroup.__morphTargetsArrays,
A
alteredq 已提交
1563
		morphNormalsArrays = geometryGroup.__morphNormalsArrays,
1564 1565 1566 1567 1568 1569 1570 1571 1572

		customAttributes = geometryGroup.__webglCustomAttributesList,
		customAttribute,

		faceArray = geometryGroup.__faceArray,
		lineArray = geometryGroup.__lineArray,

		geometry = object.geometry, // this is shared for all chunks

1573
		dirtyVertices = geometry.verticesNeedUpdate,
M
Mr.doob 已提交
1574
		dirtyElements = geometry.elementsNeedUpdate,
M
Mr.doob 已提交
1575
		dirtyUvs = geometry.uvsNeedUpdate,
M
Mr.doob 已提交
1576
		dirtyNormals = geometry.normalsNeedUpdate,
1577
		dirtyTangents = geometry.tangentsNeedUpdate,
M
Mr.doob 已提交
1578
		dirtyColors = geometry.colorsNeedUpdate,
1579
		dirtyMorphTargets = geometry.morphTargetsNeedUpdate,
1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593

		vertices = geometry.vertices,
		chunk_faces3 = geometryGroup.faces3,
		chunk_faces4 = geometryGroup.faces4,
		obj_faces = geometry.faces,

		obj_uvs  = geometry.faceVertexUvs[ 0 ],
		obj_uvs2 = geometry.faceVertexUvs[ 1 ],

		obj_colors = geometry.colors,

		obj_skinIndices = geometry.skinIndices,
		obj_skinWeights = geometry.skinWeights,

A
alteredq 已提交
1594 1595
		morphTargets = geometry.morphTargets,
		morphNormals = geometry.morphNormals;
1596 1597 1598 1599 1600 1601 1602

		if ( dirtyVertices ) {

			for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {

				face = obj_faces[ chunk_faces3[ f ] ];

1603 1604 1605
				v1 = vertices[ face.a ];
				v2 = vertices[ face.b ];
				v3 = vertices[ face.c ];
1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617

				vertexArray[ offset ]     = v1.x;
				vertexArray[ offset + 1 ] = v1.y;
				vertexArray[ offset + 2 ] = v1.z;

				vertexArray[ offset + 3 ] = v2.x;
				vertexArray[ offset + 4 ] = v2.y;
				vertexArray[ offset + 5 ] = v2.z;

				vertexArray[ offset + 6 ] = v3.x;
				vertexArray[ offset + 7 ] = v3.y;
				vertexArray[ offset + 8 ] = v3.z;
M
Mr.doob 已提交
1618

1619
				offset += 9;
M
Mr.doob 已提交
1620

1621
			}
1622

A
alteredq 已提交
1623
			for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
M
Mr.doob 已提交
1624

A
alteredq 已提交
1625
				face = obj_faces[ chunk_faces4[ f ] ];
M
Mr.doob 已提交
1626

1627 1628 1629 1630
				v1 = vertices[ face.a ];
				v2 = vertices[ face.b ];
				v3 = vertices[ face.c ];
				v4 = vertices[ face.d ];
1631

A
alteredq 已提交
1632 1633 1634
				vertexArray[ offset ]     = v1.x;
				vertexArray[ offset + 1 ] = v1.y;
				vertexArray[ offset + 2 ] = v1.z;
1635

A
alteredq 已提交
1636 1637 1638
				vertexArray[ offset + 3 ] = v2.x;
				vertexArray[ offset + 4 ] = v2.y;
				vertexArray[ offset + 5 ] = v2.z;
1639

A
alteredq 已提交
1640 1641 1642
				vertexArray[ offset + 6 ] = v3.x;
				vertexArray[ offset + 7 ] = v3.y;
				vertexArray[ offset + 8 ] = v3.z;
1643

A
alteredq 已提交
1644 1645 1646
				vertexArray[ offset + 9 ]  = v4.x;
				vertexArray[ offset + 10 ] = v4.y;
				vertexArray[ offset + 11 ] = v4.z;
1647

A
alteredq 已提交
1648
				offset += 12;
1649

A
alteredq 已提交
1650
			}
1651

A
alteredq 已提交
1652 1653
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1654

A
alteredq 已提交
1655
		}
M
Mr.doob 已提交
1656

A
alteredq 已提交
1657
		if ( dirtyMorphTargets ) {
M
Mr.doob 已提交
1658

1659
			for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {
1660

1661
				offset_morphTarget = 0;
1662

1663 1664
				for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {

A
alteredq 已提交
1665 1666 1667 1668
					chf = chunk_faces3[ f ];
					face = obj_faces[ chf ];

					// morph positions
M
Mr.doob 已提交
1669

1670 1671 1672
					v1 = morphTargets[ vk ].vertices[ face.a ];
					v2 = morphTargets[ vk ].vertices[ face.b ];
					v3 = morphTargets[ vk ].vertices[ face.c ];
M
Mr.doob 已提交
1673

A
alteredq 已提交
1674
					vka = morphTargetsArrays[ vk ];
M
Mr.doob 已提交
1675

A
alteredq 已提交
1676 1677 1678
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
M
Mr.doob 已提交
1679

A
alteredq 已提交
1680 1681 1682
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
M
Mr.doob 已提交
1683

A
alteredq 已提交
1684 1685 1686
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
M
Mr.doob 已提交
1687

A
alteredq 已提交
1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725
					// morph normals

					if ( material.morphNormals ) {

						if ( needsSmoothNormals ) {

							faceVertexNormals = morphNormals[ vk ].vertexNormals[ chf ];

							n1 = faceVertexNormals.a;
							n2 = faceVertexNormals.b;
							n3 = faceVertexNormals.c;

						} else {

							n1 = morphNormals[ vk ].faceNormals[ chf ];
							n2 = n1;
							n3 = n1;

						}

						nka = morphNormalsArrays[ vk ];

						nka[ offset_morphTarget ] 	  = n1.x;
						nka[ offset_morphTarget + 1 ] = n1.y;
						nka[ offset_morphTarget + 2 ] = n1.z;

						nka[ offset_morphTarget + 3 ] = n2.x;
						nka[ offset_morphTarget + 4 ] = n2.y;
						nka[ offset_morphTarget + 5 ] = n2.z;

						nka[ offset_morphTarget + 6 ] = n3.x;
						nka[ offset_morphTarget + 7 ] = n3.y;
						nka[ offset_morphTarget + 8 ] = n3.z;

					}

					//

1726
					offset_morphTarget += 9;
1727

1728
				}
1729

1730
				for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
1731

A
alteredq 已提交
1732 1733 1734 1735
					chf = chunk_faces4[ f ];
					face = obj_faces[ chf ];

					// morph positions
1736

1737 1738 1739 1740
					v1 = morphTargets[ vk ].vertices[ face.a ];
					v2 = morphTargets[ vk ].vertices[ face.b ];
					v3 = morphTargets[ vk ].vertices[ face.c ];
					v4 = morphTargets[ vk ].vertices[ face.d ];
1741

1742
					vka = morphTargetsArrays[ vk ];
1743

1744 1745 1746
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
1747

1748 1749 1750
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
1751

1752 1753 1754
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
1755

A
alteredq 已提交
1756 1757 1758 1759
					vka[ offset_morphTarget + 9 ]  = v4.x;
					vka[ offset_morphTarget + 10 ] = v4.y;
					vka[ offset_morphTarget + 11 ] = v4.z;

A
alteredq 已提交
1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803
					// morph normals

					if ( material.morphNormals ) {

						if ( needsSmoothNormals ) {

							faceVertexNormals = morphNormals[ vk ].vertexNormals[ chf ];

							n1 = faceVertexNormals.a;
							n2 = faceVertexNormals.b;
							n3 = faceVertexNormals.c;
							n4 = faceVertexNormals.d;

						} else {

							n1 = morphNormals[ vk ].faceNormals[ chf ];
							n2 = n1;
							n3 = n1;
							n4 = n1;

						}

						nka = morphNormalsArrays[ vk ];

						nka[ offset_morphTarget ] 	  = n1.x;
						nka[ offset_morphTarget + 1 ] = n1.y;
						nka[ offset_morphTarget + 2 ] = n1.z;

						nka[ offset_morphTarget + 3 ] = n2.x;
						nka[ offset_morphTarget + 4 ] = n2.y;
						nka[ offset_morphTarget + 5 ] = n2.z;

						nka[ offset_morphTarget + 6 ] = n3.x;
						nka[ offset_morphTarget + 7 ] = n3.y;
						nka[ offset_morphTarget + 8 ] = n3.z;

						nka[ offset_morphTarget + 9 ]  = n4.x;
						nka[ offset_morphTarget + 10 ] = n4.y;
						nka[ offset_morphTarget + 11 ] = n4.z;

					}

					//

1804
					offset_morphTarget += 12;
A
alteredq 已提交
1805

1806
				}
A
alteredq 已提交
1807 1808 1809

				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ vk ] );
				_gl.bufferData( _gl.ARRAY_BUFFER, morphTargetsArrays[ vk ], hint );
A
alteredq 已提交
1810

A
alteredq 已提交
1811 1812 1813 1814 1815 1816 1817
				if ( material.morphNormals ) {

					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ vk ] );
					_gl.bufferData( _gl.ARRAY_BUFFER, morphNormalsArrays[ vk ], hint );

				}

1818
			}
1819

A
alteredq 已提交
1820 1821 1822 1823 1824 1825 1826
		}

		if ( obj_skinWeights.length ) {

			for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {

				face = obj_faces[ chunk_faces3[ f ]	];
1827

1828
				// weights
A
alteredq 已提交
1829

1830 1831 1832
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
A
alteredq 已提交
1833

1834 1835 1836 1837
				skinWeightArray[ offset_skin ]     = sw1.x;
				skinWeightArray[ offset_skin + 1 ] = sw1.y;
				skinWeightArray[ offset_skin + 2 ] = sw1.z;
				skinWeightArray[ offset_skin + 3 ] = sw1.w;
A
alteredq 已提交
1838

1839 1840 1841 1842
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1843

1844 1845 1846 1847
				skinWeightArray[ offset_skin + 8 ]  = sw3.x;
				skinWeightArray[ offset_skin + 9 ]  = sw3.y;
				skinWeightArray[ offset_skin + 10 ] = sw3.z;
				skinWeightArray[ offset_skin + 11 ] = sw3.w;
A
alteredq 已提交
1848

1849
				// indices
A
alteredq 已提交
1850

1851 1852 1853
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
A
alteredq 已提交
1854

1855 1856 1857 1858
				skinIndexArray[ offset_skin ]     = si1.x;
				skinIndexArray[ offset_skin + 1 ] = si1.y;
				skinIndexArray[ offset_skin + 2 ] = si1.z;
				skinIndexArray[ offset_skin + 3 ] = si1.w;
A
alteredq 已提交
1859

1860 1861 1862 1863
				skinIndexArray[ offset_skin + 4 ] = si2.x;
				skinIndexArray[ offset_skin + 5 ] = si2.y;
				skinIndexArray[ offset_skin + 6 ] = si2.z;
				skinIndexArray[ offset_skin + 7 ] = si2.w;
1864

1865 1866 1867 1868
				skinIndexArray[ offset_skin + 8 ]  = si3.x;
				skinIndexArray[ offset_skin + 9 ]  = si3.y;
				skinIndexArray[ offset_skin + 10 ] = si3.z;
				skinIndexArray[ offset_skin + 11 ] = si3.w;
A
alteredq 已提交
1869

1870
				offset_skin += 12;
1871

1872
			}
1873

A
alteredq 已提交
1874
			for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
1875

A
alteredq 已提交
1876
				face = obj_faces[ chunk_faces4[ f ] ];
1877

A
alteredq 已提交
1878
				// weights
1879

A
alteredq 已提交
1880 1881 1882 1883
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
				sw4 = obj_skinWeights[ face.d ];
1884

A
alteredq 已提交
1885 1886 1887 1888
				skinWeightArray[ offset_skin ]     = sw1.x;
				skinWeightArray[ offset_skin + 1 ] = sw1.y;
				skinWeightArray[ offset_skin + 2 ] = sw1.z;
				skinWeightArray[ offset_skin + 3 ] = sw1.w;
1889

A
alteredq 已提交
1890 1891 1892 1893
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1894

A
alteredq 已提交
1895 1896 1897 1898
				skinWeightArray[ offset_skin + 8 ]  = sw3.x;
				skinWeightArray[ offset_skin + 9 ]  = sw3.y;
				skinWeightArray[ offset_skin + 10 ] = sw3.z;
				skinWeightArray[ offset_skin + 11 ] = sw3.w;
1899

A
alteredq 已提交
1900 1901 1902 1903
				skinWeightArray[ offset_skin + 12 ] = sw4.x;
				skinWeightArray[ offset_skin + 13 ] = sw4.y;
				skinWeightArray[ offset_skin + 14 ] = sw4.z;
				skinWeightArray[ offset_skin + 15 ] = sw4.w;
1904

A
alteredq 已提交
1905
				// indices
1906

A
alteredq 已提交
1907 1908 1909 1910
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
				si4 = obj_skinIndices[ face.d ];
1911

A
alteredq 已提交
1912 1913 1914 1915
				skinIndexArray[ offset_skin ]     = si1.x;
				skinIndexArray[ offset_skin + 1 ] = si1.y;
				skinIndexArray[ offset_skin + 2 ] = si1.z;
				skinIndexArray[ offset_skin + 3 ] = si1.w;
1916

A
alteredq 已提交
1917 1918 1919 1920
				skinIndexArray[ offset_skin + 4 ] = si2.x;
				skinIndexArray[ offset_skin + 5 ] = si2.y;
				skinIndexArray[ offset_skin + 6 ] = si2.z;
				skinIndexArray[ offset_skin + 7 ] = si2.w;
M
Mr.doob 已提交
1921

A
alteredq 已提交
1922 1923 1924 1925
				skinIndexArray[ offset_skin + 8 ]  = si3.x;
				skinIndexArray[ offset_skin + 9 ]  = si3.y;
				skinIndexArray[ offset_skin + 10 ] = si3.z;
				skinIndexArray[ offset_skin + 11 ] = si3.w;
M
Mr.doob 已提交
1926

A
alteredq 已提交
1927 1928 1929 1930
				skinIndexArray[ offset_skin + 12 ] = si4.x;
				skinIndexArray[ offset_skin + 13 ] = si4.y;
				skinIndexArray[ offset_skin + 14 ] = si4.z;
				skinIndexArray[ offset_skin + 15 ] = si4.w;
M
Mr.doob 已提交
1931

A
alteredq 已提交
1932
				offset_skin += 16;
M
Mr.doob 已提交
1933

A
alteredq 已提交
1934
			}
M
Mr.doob 已提交
1935

A
alteredq 已提交
1936
			if ( offset_skin > 0 ) {
M
Mr.doob 已提交
1937

A
alteredq 已提交
1938 1939 1940 1941 1942
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );

				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
1943

1944
			}
1945

A
alteredq 已提交
1946
		}
M
Mr.doob 已提交
1947

A
alteredq 已提交
1948
		if ( dirtyColors && vertexColorType ) {
M
Mr.doob 已提交
1949

A
alteredq 已提交
1950
			for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
M
Mr.doob 已提交
1951

A
alteredq 已提交
1952
				face = obj_faces[ chunk_faces3[ f ]	];
M
Mr.doob 已提交
1953

A
alteredq 已提交
1954 1955
				vertexColors = face.vertexColors;
				faceColor = face.color;
1956

A
alteredq 已提交
1957
				if ( vertexColors.length === 3 && vertexColorType === THREE.VertexColors ) {
1958

A
alteredq 已提交
1959 1960 1961
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
1962

A
alteredq 已提交
1963
				} else {
1964

A
alteredq 已提交
1965 1966 1967
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
1968

A
alteredq 已提交
1969
				}
1970

A
alteredq 已提交
1971 1972 1973
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
1974

A
alteredq 已提交
1975 1976 1977
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
1978

A
alteredq 已提交
1979 1980 1981
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
1982

A
alteredq 已提交
1983
				offset_color += 9;
M
Mr.doob 已提交
1984

A
alteredq 已提交
1985
			}
M
Mr.doob 已提交
1986

A
alteredq 已提交
1987
			for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
M
Mr.doob 已提交
1988

A
alteredq 已提交
1989
				face = obj_faces[ chunk_faces4[ f ] ];
M
Mr.doob 已提交
1990

A
alteredq 已提交
1991 1992
				vertexColors = face.vertexColors;
				faceColor = face.color;
M
Mr.doob 已提交
1993

A
alteredq 已提交
1994
				if ( vertexColors.length === 4 && vertexColorType === THREE.VertexColors ) {
M
Mr.doob 已提交
1995

A
alteredq 已提交
1996 1997 1998 1999
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
					c4 = vertexColors[ 3 ];
2000

A
alteredq 已提交
2001
				} else {
M
Mr.doob 已提交
2002

A
alteredq 已提交
2003 2004 2005 2006
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
					c4 = faceColor;
M
Mr.doob 已提交
2007

A
alteredq 已提交
2008
				}
2009

A
alteredq 已提交
2010 2011 2012
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
2013

A
alteredq 已提交
2014 2015 2016
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
M
Mr.doob 已提交
2017

A
alteredq 已提交
2018 2019 2020
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
M
Mr.doob 已提交
2021

A
alteredq 已提交
2022 2023 2024
				colorArray[ offset_color + 9 ]  = c4.r;
				colorArray[ offset_color + 10 ] = c4.g;
				colorArray[ offset_color + 11 ] = c4.b;
M
Mr.doob 已提交
2025

A
alteredq 已提交
2026
				offset_color += 12;
2027

2028
			}
2029

A
alteredq 已提交
2030
			if ( offset_color > 0 ) {
M
Mr.doob 已提交
2031

A
alteredq 已提交
2032 2033
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
M
Mr.doob 已提交
2034

2035
			}
2036

A
alteredq 已提交
2037
		}
M
Mr.doob 已提交
2038

A
alteredq 已提交
2039
		if ( dirtyTangents && geometry.hasTangents ) {
M
Mr.doob 已提交
2040

A
alteredq 已提交
2041
			for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
2042

A
alteredq 已提交
2043
				face = obj_faces[ chunk_faces3[ f ]	];
2044

A
alteredq 已提交
2045
				vertexTangents = face.vertexTangents;
M
Mr.doob 已提交
2046

A
alteredq 已提交
2047 2048 2049
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
2050

A
alteredq 已提交
2051 2052 2053 2054
				tangentArray[ offset_tangent ]     = t1.x;
				tangentArray[ offset_tangent + 1 ] = t1.y;
				tangentArray[ offset_tangent + 2 ] = t1.z;
				tangentArray[ offset_tangent + 3 ] = t1.w;
M
Mr.doob 已提交
2055

A
alteredq 已提交
2056 2057 2058 2059
				tangentArray[ offset_tangent + 4 ] = t2.x;
				tangentArray[ offset_tangent + 5 ] = t2.y;
				tangentArray[ offset_tangent + 6 ] = t2.z;
				tangentArray[ offset_tangent + 7 ] = t2.w;
2060

A
alteredq 已提交
2061 2062 2063 2064
				tangentArray[ offset_tangent + 8 ]  = t3.x;
				tangentArray[ offset_tangent + 9 ]  = t3.y;
				tangentArray[ offset_tangent + 10 ] = t3.z;
				tangentArray[ offset_tangent + 11 ] = t3.w;
2065

A
alteredq 已提交
2066
				offset_tangent += 12;
2067

2068
			}
2069

A
alteredq 已提交
2070
			for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
2071

A
alteredq 已提交
2072
				face = obj_faces[ chunk_faces4[ f ] ];
2073

A
alteredq 已提交
2074
				vertexTangents = face.vertexTangents;
2075

A
alteredq 已提交
2076 2077 2078 2079
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
				t4 = vertexTangents[ 3 ];
2080

A
alteredq 已提交
2081 2082 2083 2084
				tangentArray[ offset_tangent ]     = t1.x;
				tangentArray[ offset_tangent + 1 ] = t1.y;
				tangentArray[ offset_tangent + 2 ] = t1.z;
				tangentArray[ offset_tangent + 3 ] = t1.w;
M
Mr.doob 已提交
2085

A
alteredq 已提交
2086 2087 2088 2089
				tangentArray[ offset_tangent + 4 ] = t2.x;
				tangentArray[ offset_tangent + 5 ] = t2.y;
				tangentArray[ offset_tangent + 6 ] = t2.z;
				tangentArray[ offset_tangent + 7 ] = t2.w;
M
Mr.doob 已提交
2090

A
alteredq 已提交
2091 2092 2093 2094
				tangentArray[ offset_tangent + 8 ]  = t3.x;
				tangentArray[ offset_tangent + 9 ]  = t3.y;
				tangentArray[ offset_tangent + 10 ] = t3.z;
				tangentArray[ offset_tangent + 11 ] = t3.w;
M
Mr.doob 已提交
2095

A
alteredq 已提交
2096 2097 2098 2099
				tangentArray[ offset_tangent + 12 ] = t4.x;
				tangentArray[ offset_tangent + 13 ] = t4.y;
				tangentArray[ offset_tangent + 14 ] = t4.z;
				tangentArray[ offset_tangent + 15 ] = t4.w;
2100

A
alteredq 已提交
2101
				offset_tangent += 16;
2102

A
alteredq 已提交
2103
			}
2104

A
alteredq 已提交
2105 2106
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
2107

A
alteredq 已提交
2108
		}
2109

A
alteredq 已提交
2110
		if ( dirtyNormals && normalType ) {
2111

A
alteredq 已提交
2112
			for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
2113

A
alteredq 已提交
2114
				face = obj_faces[ chunk_faces3[ f ]	];
2115

A
alteredq 已提交
2116 2117
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
2118

A
alteredq 已提交
2119
				if ( vertexNormals.length === 3 && needsSmoothNormals ) {
2120

A
alteredq 已提交
2121
					for ( i = 0; i < 3; i ++ ) {
M
Mr.doob 已提交
2122

A
alteredq 已提交
2123
						vn = vertexNormals[ i ];
M
Mr.doob 已提交
2124

A
alteredq 已提交
2125 2126 2127
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
2128

A
alteredq 已提交
2129
						offset_normal += 3;
2130

A
alteredq 已提交
2131
					}
2132

A
alteredq 已提交
2133
				} else {
M
Mr.doob 已提交
2134

A
alteredq 已提交
2135
					for ( i = 0; i < 3; i ++ ) {
M
Mr.doob 已提交
2136

A
alteredq 已提交
2137 2138 2139
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
2140

A
alteredq 已提交
2141
						offset_normal += 3;
M
Mr.doob 已提交
2142

A
alteredq 已提交
2143
					}
2144

A
alteredq 已提交
2145
				}
2146

A
alteredq 已提交
2147
			}
2148

A
alteredq 已提交
2149
			for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
2150

A
alteredq 已提交
2151
				face = obj_faces[ chunk_faces4[ f ] ];
2152

A
alteredq 已提交
2153 2154
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
2155

A
alteredq 已提交
2156
				if ( vertexNormals.length === 4 && needsSmoothNormals ) {
2157

A
alteredq 已提交
2158
					for ( i = 0; i < 4; i ++ ) {
2159

A
alteredq 已提交
2160
						vn = vertexNormals[ i ];
2161

A
alteredq 已提交
2162 2163 2164
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
2165

A
alteredq 已提交
2166
						offset_normal += 3;
2167

A
alteredq 已提交
2168
					}
M
Mr.doob 已提交
2169

A
alteredq 已提交
2170
				} else {
2171

A
alteredq 已提交
2172
					for ( i = 0; i < 4; i ++ ) {
2173

A
alteredq 已提交
2174 2175 2176
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
2177

A
alteredq 已提交
2178
						offset_normal += 3;
M
Mr.doob 已提交
2179

A
alteredq 已提交
2180
					}
2181

A
alteredq 已提交
2182
				}
2183

A
alteredq 已提交
2184
			}
M
Mr.doob 已提交
2185

A
alteredq 已提交
2186 2187
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
2188

A
alteredq 已提交
2189
		}
M
Mr.doob 已提交
2190

A
alteredq 已提交
2191
		if ( dirtyUvs && obj_uvs && uvType ) {
2192

A
alteredq 已提交
2193
			for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
2194

A
alteredq 已提交
2195
				fi = chunk_faces3[ f ];
2196

A
alteredq 已提交
2197 2198
				face = obj_faces[ fi ];
				uv = obj_uvs[ fi ];
2199

A
alteredq 已提交
2200
				if ( uv === undefined ) continue;
2201

A
alteredq 已提交
2202
				for ( i = 0; i < 3; i ++ ) {
2203

A
alteredq 已提交
2204
					uvi = uv[ i ];
2205

A
alteredq 已提交
2206 2207
					uvArray[ offset_uv ]     = uvi.u;
					uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
2208

A
alteredq 已提交
2209
					offset_uv += 2;
M
Mr.doob 已提交
2210

A
alteredq 已提交
2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231
				}

			}

			for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {

				fi = chunk_faces4[ f ];

				face = obj_faces[ fi ];
				uv = obj_uvs[ fi ];

				if ( uv === undefined ) continue;

				for ( i = 0; i < 4; i ++ ) {

					uvi = uv[ i ];

					uvArray[ offset_uv ]     = uvi.u;
					uvArray[ offset_uv + 1 ] = uvi.v;

					offset_uv += 2;
M
Mr.doob 已提交
2232

2233 2234
				}

2235
			}
2236

A
alteredq 已提交
2237
			if ( offset_uv > 0 ) {
2238

A
alteredq 已提交
2239 2240
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
2241

A
alteredq 已提交
2242
			}
2243

A
alteredq 已提交
2244
		}
2245

A
alteredq 已提交
2246
		if ( dirtyUvs && obj_uvs2 && uvType ) {
2247

A
alteredq 已提交
2248
			for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
2249

A
alteredq 已提交
2250
				fi = chunk_faces3[ f ];
2251

A
alteredq 已提交
2252 2253
				face = obj_faces[ fi ];
				uv2 = obj_uvs2[ fi ];
2254

A
alteredq 已提交
2255 2256 2257 2258 2259 2260 2261 2262 2263 2264
				if ( uv2 === undefined ) continue;

				for ( i = 0; i < 3; i ++ ) {

					uv2i = uv2[ i ];

					uv2Array[ offset_uv2 ]     = uv2i.u;
					uv2Array[ offset_uv2 + 1 ] = uv2i.v;

					offset_uv2 += 2;
2265

2266 2267
				}

A
alteredq 已提交
2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288
			}

			for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {

				fi = chunk_faces4[ f ];

				face = obj_faces[ fi ];
				uv2 = obj_uvs2[ fi ];

				if ( uv2 === undefined ) continue;

				for ( i = 0; i < 4; i ++ ) {

					uv2i = uv2[ i ];

					uv2Array[ offset_uv2 ]     = uv2i.u;
					uv2Array[ offset_uv2 + 1 ] = uv2i.v;

					offset_uv2 += 2;

				}
2289

2290
			}
2291

A
alteredq 已提交
2292
			if ( offset_uv2 > 0 ) {
2293

A
alteredq 已提交
2294 2295
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );
2296

A
alteredq 已提交
2297
			}
2298

A
alteredq 已提交
2299
		}
2300

A
alteredq 已提交
2301
		if ( dirtyElements ) {
2302

A
alteredq 已提交
2303
			for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
2304

A
alteredq 已提交
2305
				face = obj_faces[ chunk_faces3[ f ]	];
2306

A
alteredq 已提交
2307 2308 2309
				faceArray[ offset_face ] 	 = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 2;
2310

A
alteredq 已提交
2311
				offset_face += 3;
2312

A
alteredq 已提交
2313 2314
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2315

A
alteredq 已提交
2316 2317
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 2;
2318

A
alteredq 已提交
2319 2320
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
2321

A
alteredq 已提交
2322
				offset_line += 6;
2323

A
alteredq 已提交
2324
				vertexIndex += 3;
2325

A
alteredq 已提交
2326
			}
2327

A
alteredq 已提交
2328
			for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
2329

A
alteredq 已提交
2330
				face = obj_faces[ chunk_faces4[ f ] ];
2331

A
alteredq 已提交
2332 2333 2334
				faceArray[ offset_face ]     = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 3;
2335

A
alteredq 已提交
2336 2337 2338
				faceArray[ offset_face + 3 ] = vertexIndex + 1;
				faceArray[ offset_face + 4 ] = vertexIndex + 2;
				faceArray[ offset_face + 5 ] = vertexIndex + 3;
2339

A
alteredq 已提交
2340
				offset_face += 6;
2341

A
alteredq 已提交
2342 2343
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2344

A
alteredq 已提交
2345 2346
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 3;
2347

A
alteredq 已提交
2348 2349
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
2350

A
alteredq 已提交
2351 2352
				lineArray[ offset_line + 6 ] = vertexIndex + 2;
				lineArray[ offset_line + 7 ] = vertexIndex + 3;
2353

A
alteredq 已提交
2354
				offset_line += 8;
2355

A
alteredq 已提交
2356
				vertexIndex += 4;
2357

2358
			}
2359

A
alteredq 已提交
2360 2361
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
2362

A
alteredq 已提交
2363 2364
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
2365

A
alteredq 已提交
2366
		}
2367

A
alteredq 已提交
2368
		if ( customAttributes ) {
2369

A
alteredq 已提交
2370
			for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
2371

2372
				customAttribute = customAttributes[ i ];
2373

2374
				if ( ! customAttribute.__original.needsUpdate ) continue;
2375

2376 2377
				offset_custom = 0;
				offset_customSrc = 0;
2378

2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411
				if ( customAttribute.size === 1 ) {

					if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {

						for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {

							face = obj_faces[ chunk_faces3[ f ]	];

							customAttribute.array[ offset_custom ] 	   = customAttribute.value[ face.a ];
							customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];
							customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];

							offset_custom += 3;

						}

						for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {

							face = obj_faces[ chunk_faces4[ f ] ];

							customAttribute.array[ offset_custom ] 	   = customAttribute.value[ face.a ];
							customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];
							customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];
							customAttribute.array[ offset_custom + 3 ] = customAttribute.value[ face.d ];

							offset_custom += 4;

						}

					} else if ( customAttribute.boundTo === "faces" ) {

						for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {

2412
							value = customAttribute.value[ chunk_faces3[ f ] ];
2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423

							customAttribute.array[ offset_custom ] 	   = value;
							customAttribute.array[ offset_custom + 1 ] = value;
							customAttribute.array[ offset_custom + 2 ] = value;

							offset_custom += 3;

						}

						for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {

2424
							value = customAttribute.value[ chunk_faces4[ f ] ];
2425 2426 2427 2428 2429 2430 2431 2432 2433

							customAttribute.array[ offset_custom ] 	   = value;
							customAttribute.array[ offset_custom + 1 ] = value;
							customAttribute.array[ offset_custom + 2 ] = value;
							customAttribute.array[ offset_custom + 3 ] = value;

							offset_custom += 4;

						}
2434

2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453
					}

				} else if ( customAttribute.size === 2 ) {

					if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {

						for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {

							face = obj_faces[ chunk_faces3[ f ]	];

							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];

							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;

							customAttribute.array[ offset_custom + 2 ] = v2.x;
							customAttribute.array[ offset_custom + 3 ] = v2.y;
A
alteredq 已提交
2454

2455 2456
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2457

2458
							offset_custom += 6;
A
alteredq 已提交
2459

2460
						}
A
alteredq 已提交
2461

2462
						for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
A
alteredq 已提交
2463

2464
							face = obj_faces[ chunk_faces4[ f ] ];
A
alteredq 已提交
2465

2466 2467 2468 2469
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
A
alteredq 已提交
2470

2471 2472
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2473

2474 2475
							customAttribute.array[ offset_custom + 2 ] = v2.x;
							customAttribute.array[ offset_custom + 3 ] = v2.y;
A
alteredq 已提交
2476

2477 2478
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2479

2480 2481
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
A
alteredq 已提交
2482

2483
							offset_custom += 8;
A
alteredq 已提交
2484

2485
						}
A
alteredq 已提交
2486

2487
					} else if ( customAttribute.boundTo === "faces" ) {
A
alteredq 已提交
2488

2489
						for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
A
alteredq 已提交
2490

2491
							value = customAttribute.value[ chunk_faces3[ f ] ];
A
alteredq 已提交
2492

2493 2494 2495
							v1 = value;
							v2 = value;
							v3 = value;
A
alteredq 已提交
2496

2497 2498
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2499

2500 2501
							customAttribute.array[ offset_custom + 2 ] = v2.x;
							customAttribute.array[ offset_custom + 3 ] = v2.y;
A
alteredq 已提交
2502

2503 2504
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2505

2506
							offset_custom += 6;
A
alteredq 已提交
2507

2508
						}
A
alteredq 已提交
2509

2510
						for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
A
alteredq 已提交
2511

2512
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2513

2514 2515 2516 2517
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2518

2519 2520
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2521

2522 2523
							customAttribute.array[ offset_custom + 2 ] = v2.x;
							customAttribute.array[ offset_custom + 3 ] = v2.y;
A
alteredq 已提交
2524

2525 2526
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2527

2528 2529
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
2530

2531
							offset_custom += 8;
M
Mr.doob 已提交
2532

2533
						}
M
Mr.doob 已提交
2534

M
Mr.doob 已提交
2535
					}
M
Mr.doob 已提交
2536

2537
				} else if ( customAttribute.size === 3 ) {
2538

2539
					var pp;
2540

2541
					if ( customAttribute.type === "c" ) {
M
Mr.doob 已提交
2542

2543
						pp = [ "r", "g", "b" ];
M
Mr.doob 已提交
2544

2545
					} else {
M
Mr.doob 已提交
2546

2547
						pp = [ "x", "y", "z" ];
2548

2549
					}
2550

2551
					if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
2552

2553
						for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
2554

2555
							face = obj_faces[ chunk_faces3[ f ]	];
2556

2557 2558 2559
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
2560

2561 2562 2563
							customAttribute.array[ offset_custom ] 	   = v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
2564

2565 2566 2567
							customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
2568

2569 2570 2571
							customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
M
Mr.doob 已提交
2572

2573
							offset_custom += 9;
M
Mr.doob 已提交
2574

2575
						}
M
Mr.doob 已提交
2576

2577
						for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
M
Mr.doob 已提交
2578

2579
							face = obj_faces[ chunk_faces4[ f ] ];
M
Mr.doob 已提交
2580

2581 2582 2583 2584
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
M
Mr.doob 已提交
2585

2586 2587 2588
							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
M
Mr.doob 已提交
2589

2590 2591 2592
							customAttribute.array[ offset_custom + 3  ] = v2[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 4  ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5  ] = v2[ pp[ 2 ] ];
M
Mr.doob 已提交
2593

2594 2595 2596
							customAttribute.array[ offset_custom + 6  ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7  ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8  ] = v3[ pp[ 2 ] ];
M
Mr.doob 已提交
2597

2598 2599 2600
							customAttribute.array[ offset_custom + 9  ] = v4[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];
M
Mr.doob 已提交
2601

2602
							offset_custom += 12;
M
Mr.doob 已提交
2603

2604
						}
M
Mr.doob 已提交
2605

2606
					} else if ( customAttribute.boundTo === "faces" ) {
M
Mr.doob 已提交
2607

2608
						for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
2609

2610
							value = customAttribute.value[ chunk_faces3[ f ] ];
2611

2612 2613 2614
							v1 = value;
							v2 = value;
							v3 = value;
M
Mr.doob 已提交
2615

2616 2617 2618
							customAttribute.array[ offset_custom ] 	   = v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
M
Mr.doob 已提交
2619

2620 2621 2622
							customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
M
Mr.doob 已提交
2623

2624 2625 2626
							customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
M
Mr.doob 已提交
2627

2628
							offset_custom += 9;
M
Mr.doob 已提交
2629

2630
						}
2631

2632
						for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
2633

2634
							value = customAttribute.value[ chunk_faces4[ f ] ];
2635

2636 2637 2638 2639
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
2640

2641 2642 2643
							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
2644

2645
							customAttribute.array[ offset_custom + 3  ] = v2[ pp[ 0 ] ];
2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700
							customAttribute.array[ offset_custom + 4  ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5  ] = v2[ pp[ 2 ] ];

							customAttribute.array[ offset_custom + 6  ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7  ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8  ] = v3[ pp[ 2 ] ];

							customAttribute.array[ offset_custom + 9  ] = v4[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];

							offset_custom += 12;

						}

					} else if ( customAttribute.boundTo === "faceVertices" ) {

						for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {

							value = customAttribute.value[ chunk_faces3[ f ] ];

							v1 = value[ 0 ];
							v2 = value[ 1 ];
							v3 = value[ 2 ];

							customAttribute.array[ offset_custom ] 	   = v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];

							customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];

							customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];

							offset_custom += 9;

						}

						for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {

							value = customAttribute.value[ chunk_faces4[ f ] ];

							v1 = value[ 0 ];
							v2 = value[ 1 ];
							v3 = value[ 2 ];
							v4 = value[ 3 ];

							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];

							customAttribute.array[ offset_custom + 3  ] = v2[ pp[ 0 ] ];
2701 2702
							customAttribute.array[ offset_custom + 4  ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5  ] = v2[ pp[ 2 ] ];
2703

2704 2705 2706
							customAttribute.array[ offset_custom + 6  ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7  ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8  ] = v3[ pp[ 2 ] ];
2707

2708 2709 2710
							customAttribute.array[ offset_custom + 9  ] = v4[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];
2711

2712
							offset_custom += 12;
2713

2714
						}
2715

A
alteredq 已提交
2716
					}
M
Mr.doob 已提交
2717

2718
				} else if ( customAttribute.size === 4 ) {
2719

2720
					if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
M
Mr.doob 已提交
2721

2722
						for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
2723

2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785
							face = obj_faces[ chunk_faces3[ f ]	];

							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];

							customAttribute.array[ offset_custom  ] 	= v1.x;
							customAttribute.array[ offset_custom + 1  ] = v1.y;
							customAttribute.array[ offset_custom + 2  ] = v1.z;
							customAttribute.array[ offset_custom + 3  ] = v1.w;

							customAttribute.array[ offset_custom + 4  ] = v2.x;
							customAttribute.array[ offset_custom + 5  ] = v2.y;
							customAttribute.array[ offset_custom + 6  ] = v2.z;
							customAttribute.array[ offset_custom + 7  ] = v2.w;

							customAttribute.array[ offset_custom + 8  ] = v3.x;
							customAttribute.array[ offset_custom + 9  ] = v3.y;
							customAttribute.array[ offset_custom + 10 ] = v3.z;
							customAttribute.array[ offset_custom + 11 ] = v3.w;

							offset_custom += 12;

						}

						for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {

							face = obj_faces[ chunk_faces4[ f ] ];

							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];

							customAttribute.array[ offset_custom  ] 	= v1.x;
							customAttribute.array[ offset_custom + 1  ] = v1.y;
							customAttribute.array[ offset_custom + 2  ] = v1.z;
							customAttribute.array[ offset_custom + 3  ] = v1.w;

							customAttribute.array[ offset_custom + 4  ] = v2.x;
							customAttribute.array[ offset_custom + 5  ] = v2.y;
							customAttribute.array[ offset_custom + 6  ] = v2.z;
							customAttribute.array[ offset_custom + 7  ] = v2.w;

							customAttribute.array[ offset_custom + 8  ] = v3.x;
							customAttribute.array[ offset_custom + 9  ] = v3.y;
							customAttribute.array[ offset_custom + 10 ] = v3.z;
							customAttribute.array[ offset_custom + 11 ] = v3.w;

							customAttribute.array[ offset_custom + 12 ] = v4.x;
							customAttribute.array[ offset_custom + 13 ] = v4.y;
							customAttribute.array[ offset_custom + 14 ] = v4.z;
							customAttribute.array[ offset_custom + 15 ] = v4.w;

							offset_custom += 16;

						}

					} else if ( customAttribute.boundTo === "faces" ) {

						for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {

2786
							value = customAttribute.value[ chunk_faces3[ f ] ];
2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803

							v1 = value;
							v2 = value;
							v3 = value;

							customAttribute.array[ offset_custom  ] 	= v1.x;
							customAttribute.array[ offset_custom + 1  ] = v1.y;
							customAttribute.array[ offset_custom + 2  ] = v1.z;
							customAttribute.array[ offset_custom + 3  ] = v1.w;

							customAttribute.array[ offset_custom + 4  ] = v2.x;
							customAttribute.array[ offset_custom + 5  ] = v2.y;
							customAttribute.array[ offset_custom + 6  ] = v2.z;
							customAttribute.array[ offset_custom + 7  ] = v2.w;

							customAttribute.array[ offset_custom + 8  ] = v3.x;
							customAttribute.array[ offset_custom + 9  ] = v3.y;
2804 2805
							customAttribute.array[ offset_custom + 10 ] = v3.z;
							customAttribute.array[ offset_custom + 11 ] = v3.w;
A
alteredq 已提交
2806

2807
							offset_custom += 12;
A
alteredq 已提交
2808

2809 2810
						}

2811
						for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
A
alteredq 已提交
2812

2813
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2814

2815 2816 2817 2818
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2819

2820 2821 2822 2823
							customAttribute.array[ offset_custom  ] 	= v1.x;
							customAttribute.array[ offset_custom + 1  ] = v1.y;
							customAttribute.array[ offset_custom + 2  ] = v1.z;
							customAttribute.array[ offset_custom + 3  ] = v1.w;
2824

2825 2826 2827 2828
							customAttribute.array[ offset_custom + 4  ] = v2.x;
							customAttribute.array[ offset_custom + 5  ] = v2.y;
							customAttribute.array[ offset_custom + 6  ] = v2.z;
							customAttribute.array[ offset_custom + 7  ] = v2.w;
2829

2830 2831 2832 2833
							customAttribute.array[ offset_custom + 8  ] = v3.x;
							customAttribute.array[ offset_custom + 9  ] = v3.y;
							customAttribute.array[ offset_custom + 10 ] = v3.z;
							customAttribute.array[ offset_custom + 11 ] = v3.w;
2834

2835 2836 2837 2838
							customAttribute.array[ offset_custom + 12 ] = v4.x;
							customAttribute.array[ offset_custom + 13 ] = v4.y;
							customAttribute.array[ offset_custom + 14 ] = v4.z;
							customAttribute.array[ offset_custom + 15 ] = v4.w;
2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 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

							offset_custom += 16;

						}

					} else if ( customAttribute.boundTo === "faceVertices" ) {

						for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {

							value = customAttribute.value[ chunk_faces3[ f ] ];

							v1 = value[ 0 ];
							v2 = value[ 1 ];
							v3 = value[ 2 ];

							customAttribute.array[ offset_custom  ] 	= v1.x;
							customAttribute.array[ offset_custom + 1  ] = v1.y;
							customAttribute.array[ offset_custom + 2  ] = v1.z;
							customAttribute.array[ offset_custom + 3  ] = v1.w;

							customAttribute.array[ offset_custom + 4  ] = v2.x;
							customAttribute.array[ offset_custom + 5  ] = v2.y;
							customAttribute.array[ offset_custom + 6  ] = v2.z;
							customAttribute.array[ offset_custom + 7  ] = v2.w;

							customAttribute.array[ offset_custom + 8  ] = v3.x;
							customAttribute.array[ offset_custom + 9  ] = v3.y;
							customAttribute.array[ offset_custom + 10 ] = v3.z;
							customAttribute.array[ offset_custom + 11 ] = v3.w;

							offset_custom += 12;

						}

						for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {

							value = customAttribute.value[ chunk_faces4[ f ] ];

							v1 = value[ 0 ];
							v2 = value[ 1 ];
							v3 = value[ 2 ];
							v4 = value[ 3 ];

							customAttribute.array[ offset_custom  ] 	= v1.x;
							customAttribute.array[ offset_custom + 1  ] = v1.y;
							customAttribute.array[ offset_custom + 2  ] = v1.z;
							customAttribute.array[ offset_custom + 3  ] = v1.w;

							customAttribute.array[ offset_custom + 4  ] = v2.x;
							customAttribute.array[ offset_custom + 5  ] = v2.y;
							customAttribute.array[ offset_custom + 6  ] = v2.z;
							customAttribute.array[ offset_custom + 7  ] = v2.w;

							customAttribute.array[ offset_custom + 8  ] = v3.x;
							customAttribute.array[ offset_custom + 9  ] = v3.y;
							customAttribute.array[ offset_custom + 10 ] = v3.z;
							customAttribute.array[ offset_custom + 11 ] = v3.w;

							customAttribute.array[ offset_custom + 12 ] = v4.x;
							customAttribute.array[ offset_custom + 13 ] = v4.y;
							customAttribute.array[ offset_custom + 14 ] = v4.z;
							customAttribute.array[ offset_custom + 15 ] = v4.w;
2901

2902
							offset_custom += 16;
A
alteredq 已提交
2903

2904
						}
A
alteredq 已提交
2905 2906 2907 2908 2909

					}

				}

2910 2911 2912
				_gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );

A
alteredq 已提交
2913 2914 2915 2916
			}

		}

2917
		if ( dispose ) {
2918

2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929
			delete geometryGroup.__inittedArrays;
			delete geometryGroup.__colorArray;
			delete geometryGroup.__normalArray;
			delete geometryGroup.__tangentArray;
			delete geometryGroup.__uvArray;
			delete geometryGroup.__uv2Array;
			delete geometryGroup.__faceArray;
			delete geometryGroup.__vertexArray;
			delete geometryGroup.__lineArray;
			delete geometryGroup.__skinIndexArray;
			delete geometryGroup.__skinWeightArray;
A
alteredq 已提交
2930

2931
		}
A
alteredq 已提交
2932

2933
	};
A
alteredq 已提交
2934

2935 2936
	function setDirectBuffers ( geometry, hint, dispose ) {

2937
		var attributes = geometry.attributes;
2938

2939 2940 2941 2942 2943
		var index = attributes[ "index" ];
		var position = attributes[ "position" ];
		var normal = attributes[ "normal" ];
		var uv = attributes[ "uv" ];
		var color = attributes[ "color" ];
2944
		var tangent = attributes[ "tangent" ];
2945 2946 2947 2948 2949

		if ( geometry.elementsNeedUpdate && index !== undefined ) {

			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, index.array, hint );
2950 2951 2952

		}

2953
		if ( geometry.verticesNeedUpdate && position !== undefined ) {
2954

2955 2956
			_gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, position.array, hint );
2957 2958 2959

		}

2960
		if ( geometry.normalsNeedUpdate && normal !== undefined ) {
2961

2962 2963
			_gl.bindBuffer( _gl.ARRAY_BUFFER, normal.buffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, normal.array, hint );
2964 2965 2966

		}

2967
		if ( geometry.uvsNeedUpdate && uv !== undefined ) {
2968

2969 2970
			_gl.bindBuffer( _gl.ARRAY_BUFFER, uv.buffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, uv.array, hint );
2971 2972 2973

		}

2974
		if ( geometry.colorsNeedUpdate && color !== undefined ) {
2975

2976 2977
			_gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, color.array, hint );
2978 2979 2980

		}

2981 2982 2983 2984 2985 2986
		if ( geometry.tangentsNeedUpdate && tangent !== undefined ) {

			_gl.bindBuffer( _gl.ARRAY_BUFFER, tangent.buffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, tangent.array, hint );

		}
2987 2988 2989

		if ( dispose ) {

2990 2991 2992 2993 2994
			for ( var i in geometry.attributes ) {

				delete geometry.attributes[ i ].array;

			}
2995 2996 2997 2998 2999

		}

	};

3000
	// Buffer rendering
A
alteredq 已提交
3001

3002
	this.renderBufferImmediate = function ( object, program, material ) {
A
alteredq 已提交
3003

3004 3005 3006
		if ( object.hasPositions && ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( object.hasNormals && ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
		if ( object.hasUvs && ! object.__webglUvBuffer ) object.__webglUvBuffer = _gl.createBuffer();
3007
		if ( object.hasColors && ! object.__webglColorBuffer ) object.__webglColorBuffer = _gl.createBuffer();
A
alteredq 已提交
3008

3009
		if ( object.hasPositions ) {
A
alteredq 已提交
3010

3011 3012 3013 3014
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
			_gl.enableVertexAttribArray( program.attributes.position );
			_gl.vertexAttribPointer( program.attributes.position, 3, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3015 3016 3017

		}

3018
		if ( object.hasNormals ) {
A
alteredq 已提交
3019

3020
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
A
alteredq 已提交
3021

3022
			if ( material.shading === THREE.FlatShading ) {
3023

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

3029
				for( i = 0; i < il; i += 9 ) {
3030

3031
					normalArray = object.normalArray;
3032

3033 3034 3035
					nax  = normalArray[ i ];
					nay  = normalArray[ i + 1 ];
					naz  = normalArray[ i + 2 ];
3036

3037 3038 3039
					nbx  = normalArray[ i + 3 ];
					nby  = normalArray[ i + 4 ];
					nbz  = normalArray[ i + 5 ];
3040

3041 3042 3043
					ncx  = normalArray[ i + 6 ];
					ncy  = normalArray[ i + 7 ];
					ncz  = normalArray[ i + 8 ];
3044

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

3049 3050 3051
					normalArray[ i ] 	 = nx;
					normalArray[ i + 1 ] = ny;
					normalArray[ i + 2 ] = nz;
3052

3053 3054 3055
					normalArray[ i + 3 ] = nx;
					normalArray[ i + 4 ] = ny;
					normalArray[ i + 5 ] = nz;
3056

3057 3058 3059
					normalArray[ i + 6 ] = nx;
					normalArray[ i + 7 ] = ny;
					normalArray[ i + 8 ] = nz;
3060

3061
				}
3062

3063
			}
3064

3065 3066 3067
			_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );
			_gl.enableVertexAttribArray( program.attributes.normal );
			_gl.vertexAttribPointer( program.attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
3068

3069
		}
3070

3071
		if ( object.hasUvs && material.map ) {
3072 3073 3074 3075 3076 3077 3078 3079

			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglUvBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
			_gl.enableVertexAttribArray( program.attributes.uv );
			_gl.vertexAttribPointer( program.attributes.uv, 2, _gl.FLOAT, false, 0, 0 );

		}

3080 3081 3082 3083 3084 3085 3086 3087 3088
		if ( object.hasColors && material.vertexColors !== THREE.NoColors ) {

			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglColorBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
			_gl.enableVertexAttribArray( program.attributes.color );
			_gl.vertexAttribPointer( program.attributes.color, 3, _gl.FLOAT, false, 0, 0 );

		}

3089
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );
3090

3091
		object.count = 0;
3092

3093
	};
3094

3095
	this.renderBufferDirect = function ( camera, lights, fog, material, geometry, object ) {
3096

3097 3098
		if ( material.visible === false ) return;

3099
		var program, attributes, linewidth, primitives, a, attribute;
3100 3101 3102 3103 3104 3105 3106

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

		attributes = program.attributes;

		var updateBuffers = false,
			wireframeBit = material.wireframe ? 1 : 0,
3107
			geometryHash = ( geometry.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit;
3108

3109
		if ( geometryHash !== _currentGeometryGroupHash ) {
3110

3111
			_currentGeometryGroupHash = geometryHash;
3112 3113 3114 3115 3116 3117 3118 3119
			updateBuffers = true;

		}

		// render mesh

		if ( object instanceof THREE.Mesh ) {

3120
			var offsets = geometry.offsets;
3121

3122
			// if there is more than 1 chunk
3123
			// must set attribute pointers to use new offsets for each chunk
3124 3125 3126 3127
			// even if geometry and materials didn't change

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

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

3130 3131
				var startIndex = offsets[ i ].index;

3132 3133 3134 3135
				if ( updateBuffers ) {

					// vertices

3136 3137
					var position = geometry.attributes[ "position" ];
					var positionSize = position.itemSize;
3138

3139 3140
					_gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
					_gl.vertexAttribPointer( attributes.position, positionSize, _gl.FLOAT, false, 0, startIndex * positionSize * 4 ); // 4 bytes per Float32
3141 3142 3143

					// normals

3144
					var normal = geometry.attributes[ "normal" ];
3145

3146
					if ( attributes.normal >= 0 && normal ) {
3147

3148 3149 3150 3151
						var normalSize = normal.itemSize;

						_gl.bindBuffer( _gl.ARRAY_BUFFER, normal.buffer );
						_gl.vertexAttribPointer( attributes.normal, normalSize, _gl.FLOAT, false, 0, startIndex * normalSize * 4 );
3152 3153 3154 3155 3156

					}

					// uvs

3157 3158 3159
					var uv = geometry.attributes[ "uv" ];

					if ( attributes.uv >= 0 && uv ) {
3160

3161
						if ( uv.buffer ) {
3162

3163
							var uvSize = uv.itemSize;
3164

3165 3166
							_gl.bindBuffer( _gl.ARRAY_BUFFER, uv.buffer );
							_gl.vertexAttribPointer( attributes.uv, uvSize, _gl.FLOAT, false, 0, startIndex * uvSize * 4 );
3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179

							_gl.enableVertexAttribArray( attributes.uv );

						} else {

							_gl.disableVertexAttribArray( attributes.uv );

						}

					}

					// colors

3180 3181 3182
					var color = geometry.attributes[ "color" ];

					if ( attributes.color >= 0 && color ) {
3183

3184
						var colorSize = color.itemSize;
3185

3186 3187
						_gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
						_gl.vertexAttribPointer( attributes.color, colorSize, _gl.FLOAT, false, 0, startIndex * colorSize * 4 );
3188

3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200
					}

					// tangents

					var tangent = geometry.attributes[ "tangent" ];

					if ( attributes.tangent >= 0 && tangent ) {

						var tangentSize = tangent.itemSize;

						_gl.bindBuffer( _gl.ARRAY_BUFFER, tangent.buffer );
						_gl.vertexAttribPointer( attributes.tangent, tangentSize, _gl.FLOAT, false, 0, startIndex * tangentSize * 4 );
3201 3202 3203

					}

3204 3205 3206 3207 3208
					// indices

					var index = geometry.attributes[ "index" ];

					_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
3209 3210 3211 3212 3213

				}

				// render indexed triangles

3214
				_gl.drawElements( _gl.TRIANGLES, offsets[ i ].count, _gl.UNSIGNED_SHORT, offsets[ i ].start * 2 ); // 2 bytes per Uint16
3215 3216 3217 3218 3219 3220 3221

				_this.info.render.calls ++;
				_this.info.render.vertices += offsets[ i ].count; // not really true, here vertices can be shared
				_this.info.render.faces += offsets[ i ].count / 3;

			}

3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257
		// render particles

		} else if ( object instanceof THREE.ParticleSystem ) {

			if ( updateBuffers ) {

				// vertices

				var position = geometry.attributes[ "position" ];
				var positionSize = position.itemSize;

				_gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
				_gl.vertexAttribPointer( attributes.position, positionSize, _gl.FLOAT, false, 0, 0 );

				// colors

				var color = geometry.attributes[ "color" ];

				if ( attributes.color >= 0 && color ) {

					var colorSize = color.itemSize;

					_gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
					_gl.vertexAttribPointer( attributes.color, colorSize, _gl.FLOAT, false, 0, 0 );

				}

				// render particles

				_gl.drawArrays( _gl.POINTS, 0, position.numItems / 3 );

				_this.info.render.calls ++;
				_this.info.render.points += position.numItems / 3;

			}

3258 3259 3260 3261
		}

	};

A
alteredq 已提交
3262
	this.renderBuffer = function ( camera, lights, fog, material, geometryGroup, object ) {
3263

3264 3265
		if ( material.visible === false ) return;

3266
		var program, attributes, linewidth, primitives, a, attribute, i, il;
3267

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

3270
		attributes = program.attributes;
3271

3272 3273 3274
		var updateBuffers = false,
			wireframeBit = material.wireframe ? 1 : 0,
			geometryGroupHash = ( geometryGroup.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit;
3275

3276
		if ( geometryGroupHash !== _currentGeometryGroupHash ) {
A
alteredq 已提交
3277

3278 3279
			_currentGeometryGroupHash = geometryGroupHash;
			updateBuffers = true;
3280

3281
		}
3282

3283
		// vertices
3284

3285
		if ( !material.morphTargets && attributes.position >= 0 ) {
3286

3287
			if ( updateBuffers ) {
3288

3289 3290
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
				_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3291

3292
			}
3293

3294
		} else {
3295

3296
			if ( object.morphTargetBase ) {
3297

3298
				setupMorphTargets( material, geometryGroup, object );
3299

3300
			}
3301

3302
		}
3303

3304

3305
		if ( updateBuffers ) {
3306

3307
			// custom attributes
3308

3309
			// Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
3310

3311
			if ( geometryGroup.__webglCustomAttributesList ) {
3312

3313
				for ( i = 0, il = geometryGroup.__webglCustomAttributesList.length; i < il; i ++ ) {
3314

3315
					attribute = geometryGroup.__webglCustomAttributesList[ i ];
3316

3317
					if( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
3318

3319 3320
						_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
						_gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 );
3321

3322
					}
3323

3324
				}
3325

3326
			}
3327 3328


3329
			// colors
3330

3331
			if ( attributes.color >= 0 ) {
3332

3333 3334
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
3335

3336
			}
3337

3338
			// normals
3339

3340
			if ( attributes.normal >= 0 ) {
3341

3342 3343
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
				_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
3344

3345
			}
3346

3347
			// tangents
3348

3349
			if ( attributes.tangent >= 0 ) {
3350

3351 3352
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
				_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
3353

3354
			}
3355

3356
			// uvs
3357

3358
			if ( attributes.uv >= 0 ) {
3359

3360
				if ( geometryGroup.__webglUVBuffer ) {
3361

3362 3363
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
					_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
3364

3365
					_gl.enableVertexAttribArray( attributes.uv );
3366

3367
				} else {
3368

3369
					_gl.disableVertexAttribArray( attributes.uv );
3370 3371 3372 3373 3374

				}

			}

3375
			if ( attributes.uv2 >= 0 ) {
3376

3377
				if ( geometryGroup.__webglUV2Buffer ) {
3378

3379 3380
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
					_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
3381

3382
					_gl.enableVertexAttribArray( attributes.uv2 );
3383

3384
				} else {
3385

3386
					_gl.disableVertexAttribArray( attributes.uv2 );
3387 3388

				}
3389 3390

			}
3391

3392 3393
			if ( material.skinning &&
				 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
A
alteredq 已提交
3394

3395 3396
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
				_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3397

3398 3399
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
				_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
3400

A
alteredq 已提交
3401
			}
3402

3403
		}
3404

3405
		// render mesh
3406

3407
		if ( object instanceof THREE.Mesh ) {
3408

3409
			// wireframe
3410

3411
			if ( material.wireframe ) {
3412

3413
				setLineWidth( material.wireframeLinewidth );
3414

3415 3416
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
3417

3418
			// triangles
3419

3420
			} else {
3421

3422 3423
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3424

3425
			}
3426

3427 3428 3429
			_this.info.render.calls ++;
			_this.info.render.vertices += geometryGroup.__webglFaceCount;
			_this.info.render.faces += geometryGroup.__webglFaceCount / 3;
3430

3431
		// render lines
3432

3433
		} else if ( object instanceof THREE.Line ) {
3434

3435
			primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
3436

3437
			setLineWidth( material.linewidth );
3438

3439
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
3440

3441
			_this.info.render.calls ++;
3442

3443
		// render particles
3444

3445
		} else if ( object instanceof THREE.ParticleSystem ) {
3446

3447
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
3448

3449
			_this.info.render.calls ++;
3450
			_this.info.render.points += geometryGroup.__webglParticleCount;
3451

3452
		// render ribbon
3453

3454
		} else if ( object instanceof THREE.Ribbon ) {
3455

3456
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
3457

3458
			_this.info.render.calls ++;
3459

3460
		}
3461

3462
	};
3463

3464
	function setupMorphTargets ( material, geometryGroup, object ) {
3465

3466
		// set base
3467

3468
		var attributes = material.program.attributes;
3469

A
alteredq 已提交
3470
		if ( object.morphTargetBase !== -1 ) {
3471

3472 3473
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3474

3475
		} else if ( attributes.position >= 0 ) {
3476

3477 3478
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3479

3480
		}
3481

3482
		if ( object.morphTargetForcedOrder.length ) {
3483

3484
			// set forced order
3485

3486 3487 3488 3489 3490
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;

			while ( m < material.numSupportedMorphTargets && m < order.length ) {
3491

3492 3493 3494
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ order[ m ] ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );

A
alteredq 已提交
3495 3496 3497 3498 3499 3500 3501
				if ( material.morphNormals ) {

					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ order[ m ] ] );
					_gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 );

				}

3502 3503 3504
				object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ] ];

				m ++;
3505 3506
			}

3507 3508
		} else {

A
alteredq 已提交
3509
			// find the most influencing
3510

A
alteredq 已提交
3511
			var influence, activeInfluenceIndices = [];
3512 3513
			var influences = object.morphTargetInfluences;
			var i, il = influences.length;
3514

A
alteredq 已提交
3515
			for ( i = 0; i < il; i ++ ) {
3516

A
alteredq 已提交
3517 3518 3519 3520
				influence = influences[ i ];

				if ( influence > 0 ) {

3521
					activeInfluenceIndices.push( [ i, influence ] );
3522

I
ide user ide_gero3 已提交
3523
				}
A
alteredq 已提交
3524

I
ide user ide_gero3 已提交
3525
			}
A
alteredq 已提交
3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537

			if ( activeInfluenceIndices.length > material.numSupportedMorphTargets ) {

				activeInfluenceIndices.sort( numericalSort );
				activeInfluenceIndices.length = material.numSupportedMorphTargets;

			} else if ( activeInfluenceIndices.length > material.numSupportedMorphNormals ) {

				activeInfluenceIndices.sort( numericalSort );

			} else if ( activeInfluenceIndices.length === 0 ) {

3538
				activeInfluenceIndices.push( [ 0, 0 ] );
A
alteredq 已提交
3539 3540 3541 3542

			};

			var influenceIndex, m = 0;
3543

3544
			while ( m < material.numSupportedMorphTargets ) {
3545

3546
				if ( activeInfluenceIndices[ m ] ) {
3547 3548 3549

					influenceIndex = activeInfluenceIndices[ m ][ 0 ];

A
alteredq 已提交
3550 3551 3552
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ influenceIndex ] );

					_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
3553

A
alteredq 已提交
3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565
					if ( material.morphNormals ) {

						_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ influenceIndex ] );
						_gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 );

					}

					object.__webglMorphTargetInfluences[ m ] = influences[ influenceIndex ];

				} else {

					_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
3566

A
alteredq 已提交
3567
					if ( material.morphNormals ) {
3568

A
alteredq 已提交
3569
						_gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 );
3570

3571
					}
3572

A
alteredq 已提交
3573 3574
					object.__webglMorphTargetInfluences[ m ] = 0;

3575
				}
A
alteredq 已提交
3576

3577
				m ++;
3578 3579 3580 3581 3582

			}

		}

3583
		// load updated influences uniform
3584

3585
		if ( material.program.uniforms.morphTargetInfluences !== null ) {
M
Mr.doob 已提交
3586

3587
			_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
3588

3589
		}
3590

3591
	};
3592

A
alteredq 已提交
3593
	// Sorting
3594

3595
	function painterSort ( a, b ) {
3596

3597
		return b.z - a.z;
3598

3599
	};
3600

3601
	function numericalSort ( a, b ) {
A
alteredq 已提交
3602

3603
		return b[ 1 ] - a[ 1 ];
A
alteredq 已提交
3604 3605 3606 3607

	};


3608
	// Rendering
3609

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

M
Mr.doob 已提交
3612 3613 3614 3615 3616 3617 3618
		if ( camera instanceof THREE.Camera === false ) {

			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
			return;

		}

3619 3620 3621 3622 3623
		var i, il,

		webglObject, object,
		renderList,

3624
		lights = scene.__lights,
3625
		fog = scene.fog;
M
Mr.doob 已提交
3626

3627 3628
		// reset caching for this frame

3629
		_currentMaterialId = -1;
3630
		_lightsNeedUpdate = true;
3631

A
alteredq 已提交
3632
		// update scene graph
3633

3634
		if ( this.autoUpdateScene ) scene.updateMatrixWorld();
3635

A
alteredq 已提交
3636
		// update camera matrices and frustum
A
alteredq 已提交
3637

3638 3639
		if ( camera.parent === undefined ) camera.updateMatrixWorld();

A
alteredq 已提交
3640 3641
		if ( ! camera._viewMatrixArray ) camera._viewMatrixArray = new Float32Array( 16 );
		if ( ! camera._projectionMatrixArray ) camera._projectionMatrixArray = new Float32Array( 16 );
A
alteredq 已提交
3642

3643
		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
A
alteredq 已提交
3644 3645 3646

		camera.matrixWorldInverse.flattenToArray( camera._viewMatrixArray );
		camera.projectionMatrix.flattenToArray( camera._projectionMatrixArray );
3647

3648
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
A
alteredq 已提交
3649
		_frustum.setFromMatrix( _projScreenMatrix );
3650

A
alteredq 已提交
3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665
		// update WebGL objects

		if ( this.autoUpdateObjects ) this.initWebGLObjects( scene );

		// custom render plugins (pre pass)

		renderPlugins( this.renderPluginsPre, scene, camera );

		//

		_this.info.render.calls = 0;
		_this.info.render.vertices = 0;
		_this.info.render.faces = 0;
		_this.info.render.points = 0;

A
alteredq 已提交
3666
		this.setRenderTarget( renderTarget );
3667

3668
		if ( this.autoClear || forceClear ) {
3669

3670
			this.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );
M
Mr.doob 已提交
3671

3672
		}
M
Mr.doob 已提交
3673

3674
		// set matrices for regular objects (frustum culled)
3675

3676
		renderList = scene.__webglObjects;
3677

3678
		for ( i = 0, il = renderList.length; i < il; i ++ ) {
3679

3680
			webglObject = renderList[ i ];
3681
			object = webglObject.object;
3682

A
alteredq 已提交
3683 3684
			webglObject.render = false;

3685
			if ( object.visible ) {
3686

3687
				if ( ! ( object instanceof THREE.Mesh || object instanceof THREE.ParticleSystem ) || ! ( object.frustumCulled ) || _frustum.contains( object ) ) {
M
Mr.doob 已提交
3688

3689
					//object.matrixWorld.flattenToArray( object._modelMatrixArray );
3690

A
alteredq 已提交
3691
					setupMatrices( object, camera );
3692

3693
					unrollBufferMaterial( webglObject );
3694

3695
					webglObject.render = true;
3696

3697
					if ( this.sortObjects ) {
3698

3699
						if ( object.renderDepth ) {
3700

3701
							webglObject.z = object.renderDepth;
M
Mr.doob 已提交
3702

3703
						} else {
M
Mr.doob 已提交
3704

3705
							_vector3.copy( object.matrixWorld.getPosition() );
3706
							_projScreenMatrix.multiplyVector3( _vector3 );
3707

3708
							webglObject.z = _vector3.z;
3709

3710
						}
M
Mr.doob 已提交
3711

3712
					}
M
Mr.doob 已提交
3713

3714
				}
3715 3716

			}
3717 3718 3719

		}

3720
		if ( this.sortObjects ) {
M
Mr.doob 已提交
3721

3722
			renderList.sort( painterSort );
3723

3724
		}
3725

3726
		// set matrices for immediate objects
3727

3728
		renderList = scene.__webglObjectsImmediate;
3729

3730 3731 3732
		for ( i = 0, il = renderList.length; i < il; i ++ ) {

			webglObject = renderList[ i ];
3733
			object = webglObject.object;
3734

3735
			if ( object.visible ) {
3736

M
Mr.doob 已提交
3737 3738
				/*
				if ( object.matrixAutoUpdate ) {
3739

3740
					object.matrixWorld.flattenToArray( object._modelMatrixArray );
M
Mr.doob 已提交
3741

3742
				}
M
Mr.doob 已提交
3743
				*/
M
Mr.doob 已提交
3744

A
alteredq 已提交
3745
				setupMatrices( object, camera );
M
Mr.doob 已提交
3746

3747
				unrollImmediateBufferMaterial( webglObject );
M
Mr.doob 已提交
3748

3749
			}
M
Mr.doob 已提交
3750

3751
		}
3752

3753
		if ( scene.overrideMaterial ) {
3754

3755 3756 3757 3758 3759 3760
			var material = scene.overrideMaterial;

			this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
			this.setDepthTest( material.depthTest );
			this.setDepthWrite( material.depthWrite );
			setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
3761

3762 3763
			renderObjects( scene.__webglObjects, false, "", camera, lights, fog, true, material );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "", camera, lights, fog, false, material );
M
Mr.doob 已提交
3764

3765
		} else {
3766

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

3769
			this.setBlending( THREE.NormalBlending );
3770

3771 3772
			renderObjects( scene.__webglObjects, true, "opaque", camera, lights, fog, false );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "opaque", camera, lights, fog, false );
3773

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

3776 3777
			renderObjects( scene.__webglObjects, false, "transparent", camera, lights, fog, true );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "transparent", camera, lights, fog, true );
3778

3779
		}
3780

A
alteredq 已提交
3781
		// custom render plugins (post pass)
3782

A
alteredq 已提交
3783
		renderPlugins( this.renderPluginsPost, scene, camera );
3784 3785


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

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

3790
			updateRenderTargetMipmap( renderTarget );
3791

3792
		}
3793

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

		this.setDepthTest( true );
3797
		this.setDepthWrite( true );
3798

3799
		// _gl.finish();
3800

3801
	};
3802

A
alteredq 已提交
3803 3804 3805 3806 3807 3808
	function renderPlugins( plugins, scene, camera ) {

		if ( ! plugins.length ) return;

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

3809 3810
			// reset state for plugin (to start from clean slate)

A
alteredq 已提交
3811
			_currentProgram = null;
3812
			_currentCamera = null;
3813

A
alteredq 已提交
3814 3815 3816
			_oldBlending = -1;
			_oldDepthTest = -1;
			_oldDepthWrite = -1;
3817 3818
			_oldDoubleSided = -1;
			_oldFlipSided = -1;
A
alteredq 已提交
3819 3820
			_currentGeometryGroupHash = -1;
			_currentMaterialId = -1;
3821

3822
			_lightsNeedUpdate = true;
A
alteredq 已提交
3823

A
alteredq 已提交
3824
			plugins[ i ].render( scene, camera, _currentWidth, _currentHeight );
A
alteredq 已提交
3825

3826 3827
			// reset state after plugin (anything could have changed)

A
alteredq 已提交
3828
			_currentProgram = null;
3829
			_currentCamera = null;
3830

A
alteredq 已提交
3831 3832 3833
			_oldBlending = -1;
			_oldDepthTest = -1;
			_oldDepthWrite = -1;
3834 3835
			_oldDoubleSided = -1;
			_oldFlipSided = -1;
A
alteredq 已提交
3836 3837
			_currentGeometryGroupHash = -1;
			_currentMaterialId = -1;
3838

3839
			_lightsNeedUpdate = true;
A
alteredq 已提交
3840 3841 3842 3843 3844

		}

	};

3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880
	function renderObjects ( renderList, reverse, materialType, camera, lights, fog, useBlending, overrideMaterial ) {

		var webglObject, object, buffer, material, start, end, delta;

		if ( reverse ) {

			start = renderList.length - 1;
			end = -1;
			delta = -1;

		} else {

			start = 0;
			end = renderList.length;
			delta = 1;
		}

		for ( var i = start; i !== end; i += delta ) {

			webglObject = renderList[ i ];

			if ( webglObject.render ) {

				object = webglObject.object;
				buffer = webglObject.buffer;

				if ( overrideMaterial ) {

					material = overrideMaterial;

				} else {

					material = webglObject[ materialType ];

					if ( ! material ) continue;

3881
					if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
3882

A
alteredq 已提交
3883
					_this.setDepthTest( material.depthTest );
3884
					_this.setDepthWrite( material.depthWrite );
3885 3886 3887 3888
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

3889
				_this.setMaterialFaces( material );
3890 3891 3892 3893 3894 3895 3896 3897 3898 3899

				if ( buffer instanceof THREE.BufferGeometry ) {

					_this.renderBufferDirect( camera, lights, fog, material, buffer, object );

				} else {

					_this.renderBuffer( camera, lights, fog, material, buffer, object );

				}
3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927

			}

		}

	};

	function renderObjectsImmediate ( renderList, materialType, camera, lights, fog, useBlending, overrideMaterial ) {

		var webglObject, object, material, program;

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

			webglObject = renderList[ i ];
			object = webglObject.object;

			if ( object.visible ) {

				if ( overrideMaterial ) {

					material = overrideMaterial;

				} else {

					material = webglObject[ materialType ];

					if ( ! material ) continue;

3928
					if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
3929

A
alteredq 已提交
3930
					_this.setDepthTest( material.depthTest );
3931
					_this.setDepthWrite( material.depthWrite );
3932 3933 3934 3935
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

A
alteredq 已提交
3936
				_this.renderImmediateObject( camera, lights, fog, material, object );
3937

A
alteredq 已提交
3938
			}
3939

A
alteredq 已提交
3940
		}
3941

A
alteredq 已提交
3942
	};
3943

A
alteredq 已提交
3944
	this.renderImmediateObject = function ( camera, lights, fog, material, object ) {
3945

A
alteredq 已提交
3946
		var program = setProgram( camera, lights, fog, material, object );
3947

A
alteredq 已提交
3948
		_currentGeometryGroupHash = -1;
3949

3950
		_this.setMaterialFaces( material );
A
alteredq 已提交
3951 3952 3953 3954 3955 3956 3957

		if ( object.immediateRenderCallback ) {

			object.immediateRenderCallback( program, _gl, _frustum );

		} else {

3958
			object.render( function( object ) { _this.renderBufferImmediate( object, program, material ); } );
3959 3960 3961 3962 3963

		}

	};

3964
	function unrollImmediateBufferMaterial ( globject ) {
3965

3966 3967
		var object = globject.object,
			material = object.material;
3968

3969
		if ( material.transparent ) {
3970

3971 3972
			globject.transparent = material;
			globject.opaque = null;
3973

3974
		} else {
3975

3976 3977
			globject.opaque = material;
			globject.transparent = null;
3978

3979
		}
A
alteredq 已提交
3980

3981
	};
A
alteredq 已提交
3982

3983
	function unrollBufferMaterial ( globject ) {
A
alteredq 已提交
3984

3985 3986 3987
		var object = globject.object,
			buffer = globject.buffer,
			material, materialIndex, meshMaterial;
3988

3989
		meshMaterial = object.material;
3990

3991
		if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
M
Mr.doob 已提交
3992

3993
			materialIndex = buffer.materialIndex;
3994

3995
			if ( materialIndex >= 0 ) {
3996

3997
				material = object.geometry.materials[ materialIndex ];
M
Mr.doob 已提交
3998

3999
				if ( material.transparent ) {
M
Mr.doob 已提交
4000

4001 4002
					globject.transparent = material;
					globject.opaque = null;
4003

4004
				} else {
4005

4006 4007
					globject.opaque = material;
					globject.transparent = null;
4008

4009
				}
4010

4011
			}
4012

4013
		} else {
4014

4015
			material = meshMaterial;
4016

4017
			if ( material ) {
4018

4019
				if ( material.transparent ) {
M
Mr.doob 已提交
4020

4021 4022
					globject.transparent = material;
					globject.opaque = null;
A
alteredq 已提交
4023

4024
				} else {
4025

4026 4027
					globject.opaque = material;
					globject.transparent = null;
4028

4029
				}
4030

4031
			}
4032

4033
		}
4034

4035
	};
4036

4037
	// Geometry splitting
4038

4039
	function sortFacesByMaterial ( geometry ) {
4040

4041 4042 4043
		var f, fl, face, materialIndex, vertices,
			materialHash, groupHash,
			hash_map = {};
4044

4045
		var numMorphTargets = geometry.morphTargets.length;
4046
		var numMorphNormals = geometry.morphNormals.length;
4047

4048
		geometry.geometryGroups = {};
4049

4050
		for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
4051

4052 4053
			face = geometry.faces[ f ];
			materialIndex = face.materialIndex;
4054

4055
			materialHash = ( materialIndex !== undefined ) ? materialIndex : -1;
4056

4057
			if ( hash_map[ materialHash ] === undefined ) {
4058

4059
				hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 };
4060 4061 4062

			}

4063
			groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
4064

4065
			if ( geometry.geometryGroups[ groupHash ] === undefined ) {
4066

4067
				geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets, 'numMorphNormals': numMorphNormals };
4068

4069
			}
A
alteredq 已提交
4070

4071
			vertices = face instanceof THREE.Face3 ? 3 : 4;
A
alteredq 已提交
4072

4073
			if ( geometry.geometryGroups[ groupHash ].vertices + vertices > 65535 ) {
A
alteredq 已提交
4074

4075 4076
				hash_map[ materialHash ].counter += 1;
				groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
A
alteredq 已提交
4077

4078
				if ( geometry.geometryGroups[ groupHash ] === undefined ) {
A
alteredq 已提交
4079

4080
					geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets, 'numMorphNormals': numMorphNormals };
A
alteredq 已提交
4081

4082
				}
4083

4084
			}
4085

4086
			if ( face instanceof THREE.Face3 ) {
4087

4088
				geometry.geometryGroups[ groupHash ].faces3.push( f );
4089

4090
			} else {
4091

4092
				geometry.geometryGroups[ groupHash ].faces4.push( f );
4093

A
alteredq 已提交
4094
			}
4095

4096
			geometry.geometryGroups[ groupHash ].vertices += vertices;
4097

4098
		}
4099

4100
		geometry.geometryGroupsList = [];
4101

4102
		for ( var g in geometry.geometryGroups ) {
4103

4104
			geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;
4105

4106
			geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );
4107

4108
		}
4109

4110
	};
4111

4112 4113 4114 4115 4116 4117 4118 4119 4120
	// Objects refresh

	this.initWebGLObjects = function ( scene ) {

		if ( !scene.__webglObjects ) {

			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
			scene.__webglSprites = [];
4121
			scene.__webglFlares = [];
4122 4123

		}
4124

4125
		while ( scene.__objectsAdded.length ) {
4126

4127 4128
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
4129

4130
		}
A
alteredq 已提交
4131

4132
		while ( scene.__objectsRemoved.length ) {
4133

4134 4135
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
4136

4137
		}
4138

4139
		// update must be called after objects adding / removal
4140

4141
		for ( var o = 0, ol = scene.__webglObjects.length; o < ol; o ++ ) {
4142

4143
			updateObject( scene.__webglObjects[ o ].object );
M
Mr.doob 已提交
4144 4145 4146 4147 4148

		}

	};

4149
	// Objects adding
M
Mr.doob 已提交
4150

4151
	function addObject ( object, scene ) {
A
alteredq 已提交
4152

4153
		var g, geometry, geometryGroup;
4154

4155
		if ( ! object.__webglInit ) {
M
Mr.doob 已提交
4156

4157
			object.__webglInit = true;
M
Mr.doob 已提交
4158

4159
			object._modelViewMatrix = new THREE.Matrix4();
4160
			object._normalMatrix = new THREE.Matrix3();
M
Mr.doob 已提交
4161

4162
			if ( object instanceof THREE.Mesh ) {
M
Mr.doob 已提交
4163

4164
				geometry = object.geometry;
M
Mr.doob 已提交
4165

4166
				if ( geometry instanceof THREE.Geometry ) {
M
Mr.doob 已提交
4167

4168
					if ( geometry.geometryGroups === undefined ) {
M
Mr.doob 已提交
4169

4170
						sortFacesByMaterial( geometry );
M
Mr.doob 已提交
4171

4172 4173 4174
					}

					// create separate VBOs per geometry chunk
M
Mr.doob 已提交
4175

4176
					for ( g in geometry.geometryGroups ) {
M
Mr.doob 已提交
4177

4178
						geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
4179

4180
						// initialise VBO on the first access
M
Mr.doob 已提交
4181

4182
						if ( ! geometryGroup.__webglVertexBuffer ) {
4183

4184 4185
							createMeshBuffers( geometryGroup );
							initMeshBuffers( geometryGroup, object );
M
Mr.doob 已提交
4186

4187
							geometry.verticesNeedUpdate = true;
4188
							geometry.morphTargetsNeedUpdate = true;
M
Mr.doob 已提交
4189
							geometry.elementsNeedUpdate = true;
M
Mr.doob 已提交
4190
							geometry.uvsNeedUpdate = true;
M
Mr.doob 已提交
4191
							geometry.normalsNeedUpdate = true;
4192
							geometry.tangentsNeedUpdate = true;
M
Mr.doob 已提交
4193
							geometry.colorsNeedUpdate = true;
4194 4195

						}
M
Mr.doob 已提交
4196

4197
					}
M
Mr.doob 已提交
4198

4199 4200 4201 4202
				} else if ( geometry instanceof THREE.BufferGeometry ) {

					initDirectBuffers( geometry );

4203
				}
M
Mr.doob 已提交
4204

4205
			} else if ( object instanceof THREE.Ribbon ) {
M
Mr.doob 已提交
4206

4207
				geometry = object.geometry;
M
Mr.doob 已提交
4208

4209
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
4210

4211 4212
					createRibbonBuffers( geometry );
					initRibbonBuffers( geometry );
M
Mr.doob 已提交
4213

4214
					geometry.verticesNeedUpdate = true;
M
Mr.doob 已提交
4215
					geometry.colorsNeedUpdate = true;
M
Mr.doob 已提交
4216

4217
				}
M
Mr.doob 已提交
4218

4219
			} else if ( object instanceof THREE.Line ) {
M
Mr.doob 已提交
4220

4221
				geometry = object.geometry;
M
Mr.doob 已提交
4222

4223
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
4224

4225 4226
					createLineBuffers( geometry );
					initLineBuffers( geometry, object );
M
Mr.doob 已提交
4227

4228
					geometry.verticesNeedUpdate = true;
M
Mr.doob 已提交
4229
					geometry.colorsNeedUpdate = true;
4230

4231
				}
4232

4233
			} else if ( object instanceof THREE.ParticleSystem ) {
4234

4235
				geometry = object.geometry;
4236

4237
				if ( ! geometry.__webglVertexBuffer ) {
4238

4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251
					if ( geometry instanceof THREE.Geometry ) {

						createParticleBuffers( geometry );
						initParticleBuffers( geometry, object );

						geometry.verticesNeedUpdate = true;
						geometry.colorsNeedUpdate = true;

					} else if ( geometry instanceof THREE.BufferGeometry ) {

						initDirectBuffers( geometry );

					}
4252

4253

4254
				}
4255

4256
			}
4257

4258
		}
4259

4260
		if ( ! object.__webglActive ) {
4261

4262
			if ( object instanceof THREE.Mesh ) {
4263

4264
				geometry = object.geometry;
4265

4266 4267 4268 4269 4270 4271 4272 4273 4274
				if ( geometry instanceof THREE.BufferGeometry ) {

					addBuffer( scene.__webglObjects, geometry, object );

				} else {

					for ( g in geometry.geometryGroups ) {

						geometryGroup = geometry.geometryGroups[ g ];
4275

4276
						addBuffer( scene.__webglObjects, geometryGroup, object );
4277

4278
					}
4279

4280
				}
4281

4282 4283 4284
			} else if ( object instanceof THREE.Ribbon ||
						object instanceof THREE.Line ||
						object instanceof THREE.ParticleSystem ) {
4285

4286 4287
				geometry = object.geometry;
				addBuffer( scene.__webglObjects, geometry, object );
4288

4289
			} else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
4290

4291
				addBufferImmediate( scene.__webglObjectsImmediate, object );
4292

4293
			} else if ( object instanceof THREE.Sprite ) {
4294

4295
				scene.__webglSprites.push( object );
4296

4297 4298 4299 4300
			} else if ( object instanceof THREE.LensFlare ) {

				scene.__webglFlares.push( object );

4301 4302
			}

4303
			object.__webglActive = true;
4304

4305
		}
4306

4307
	};
4308

4309
	function addBuffer ( objlist, buffer, object ) {
4310

4311 4312 4313 4314 4315 4316 4317 4318
		objlist.push(
			{
				buffer: buffer,
				object: object,
				opaque: null,
				transparent: null
			}
		);
4319

4320
	};
4321

4322
	function addBufferImmediate ( objlist, object ) {
4323

4324 4325 4326 4327 4328
		objlist.push(
			{
				object: object,
				opaque: null,
				transparent: null
4329
			}
4330
		);
4331

4332
	};
4333

4334
	// Objects updates
4335

4336
	function updateObject ( object ) {
4337

4338 4339
		var geometry = object.geometry,
			geometryGroup, customAttributesDirty, material;
4340

4341
		if ( object instanceof THREE.Mesh ) {
4342

4343 4344
			if ( geometry instanceof THREE.BufferGeometry ) {

M
Mr.doob 已提交
4345
				if ( geometry.verticesNeedUpdate || geometry.elementsNeedUpdate ||
M
Mr.doob 已提交
4346
					 geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
4347
					 geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate ) {
4348

4349
					setDirectBuffers( geometry, _gl.DYNAMIC_DRAW, !geometry.dynamic );
4350

4351
				}
4352

4353
				geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4354
				geometry.elementsNeedUpdate = false;
M
Mr.doob 已提交
4355
				geometry.uvsNeedUpdate = false;
M
Mr.doob 已提交
4356
				geometry.normalsNeedUpdate = false;
M
Mr.doob 已提交
4357
				geometry.colorsNeedUpdate = false;
4358
				geometry.tangentsNeedUpdate = false;
4359

4360
			} else {
4361

4362
				// check all geometry groups
4363

4364 4365 4366 4367 4368 4369 4370 4371
				for( var i = 0, il = geometry.geometryGroupsList.length; i < il; i ++ ) {

					geometryGroup = geometry.geometryGroupsList[ i ];

					material = getBufferMaterial( object, geometryGroup );

					customAttributesDirty = material.attributes && areCustomAttributesDirty( material );

4372
					if ( geometry.verticesNeedUpdate || geometry.morphTargetsNeedUpdate || geometry.elementsNeedUpdate ||
M
Mr.doob 已提交
4373
						 geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
4374
						 geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate || customAttributesDirty ) {
4375 4376 4377 4378

						setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW, !geometry.dynamic, material );

					}
4379

4380
				}
M
Mr.doob 已提交
4381

4382
				geometry.verticesNeedUpdate = false;
4383
				geometry.morphTargetsNeedUpdate = false;
M
Mr.doob 已提交
4384
				geometry.elementsNeedUpdate = false;
M
Mr.doob 已提交
4385
				geometry.uvsNeedUpdate = false;
M
Mr.doob 已提交
4386
				geometry.normalsNeedUpdate = false;
M
Mr.doob 已提交
4387
				geometry.colorsNeedUpdate = false;
4388
				geometry.tangentsNeedUpdate = false;
4389

4390
				material.attributes && clearCustomAttributes( material );
4391

4392
			}
4393

4394
		} else if ( object instanceof THREE.Ribbon ) {
4395

M
Mr.doob 已提交
4396
			if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate ) {
4397

4398
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
4399

4400
			}
4401

4402
			geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4403
			geometry.colorsNeedUpdate = false;
4404

4405
		} else if ( object instanceof THREE.Line ) {
4406

4407
			material = getBufferMaterial( object, geometryGroup );
A
alteredq 已提交
4408

4409
			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
A
alteredq 已提交
4410

M
Mr.doob 已提交
4411
			if ( geometry.verticesNeedUpdate ||  geometry.colorsNeedUpdate || customAttributesDirty ) {
A
alteredq 已提交
4412

4413
				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
4414

4415
			}
4416

4417
			geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4418
			geometry.colorsNeedUpdate = false;
4419

4420
			material.attributes && clearCustomAttributes( material );
4421

4422
		} else if ( object instanceof THREE.ParticleSystem ) {
4423

4424
			if ( geometry instanceof THREE.BufferGeometry ) {
4425

4426
				if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate ) {
4427

4428
					setDirectBuffers( geometry, _gl.DYNAMIC_DRAW, !geometry.dynamic );
4429

4430
				}
4431

4432 4433
				geometry.verticesNeedUpdate = false;
				geometry.colorsNeedUpdate = false;
4434

4435
			} else {
4436

4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452
				material = getBufferMaterial( object, geometryGroup );

				customAttributesDirty = material.attributes && areCustomAttributesDirty( material );

				if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || object.sortParticles || customAttributesDirty ) {

					setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );

				}

				geometry.verticesNeedUpdate = false;
				geometry.colorsNeedUpdate = false;

				material.attributes && clearCustomAttributes( material );

			}
4453

4454
		}
4455

4456
	};
4457

4458
	// Objects updates - custom attributes check
4459

4460
	function areCustomAttributesDirty ( material ) {
4461

4462
		for ( var a in material.attributes ) {
4463

4464
			if ( material.attributes[ a ].needsUpdate ) return true;
4465

4466
		}
4467

4468
		return false;
4469

4470
	};
4471

4472 4473 4474
	function clearCustomAttributes ( material ) {

		for ( var a in material.attributes ) {
4475

4476
			material.attributes[ a ].needsUpdate = false;
4477

4478
		}
4479

4480
	};
4481

4482
	// Objects removal
4483

4484
	function removeObject ( object, scene ) {
4485

4486 4487 4488 4489
		if ( object instanceof THREE.Mesh  ||
			 object instanceof THREE.ParticleSystem ||
			 object instanceof THREE.Ribbon ||
			 object instanceof THREE.Line ) {
4490

4491
			removeInstances( scene.__webglObjects, object );
4492

4493
		} else if ( object instanceof THREE.Sprite ) {
4494

4495
			removeInstancesDirect( scene.__webglSprites, object );
4496

4497 4498 4499 4500
		} else if ( object instanceof THREE.LensFlare ) {

			removeInstancesDirect( scene.__webglFlares, object );

4501
		} else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
4502

4503
			removeInstances( scene.__webglObjectsImmediate, object );
4504

4505
		}
4506

4507
		object.__webglActive = false;
4508

4509
	};
4510

4511
	function removeInstances ( objlist, object ) {
4512

4513
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4514

4515
			if ( objlist[ o ].object === object ) {
4516

4517
				objlist.splice( o, 1 );
4518

4519
			}
4520

4521
		}
4522

4523
	};
4524

4525
	function removeInstancesDirect ( objlist, object ) {
4526

4527
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4528

4529
			if ( objlist[ o ] === object ) {
4530

4531
				objlist.splice( o, 1 );
4532

4533
			}
4534

4535
		}
4536

4537
	};
4538

4539
	// Materials
4540

4541
	this.initMaterial = function ( material, lights, fog, object ) {
4542

4543
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
4544

4545
		if ( material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
4546

4547
			shaderID = 'depth';
4548

4549
		} else if ( material instanceof THREE.MeshNormalMaterial ) {
4550

4551
			shaderID = 'normal';
M
Mr.doob 已提交
4552

4553
		} else if ( material instanceof THREE.MeshBasicMaterial ) {
M
Mr.doob 已提交
4554

4555
			shaderID = 'basic';
M
Mr.doob 已提交
4556

4557
		} else if ( material instanceof THREE.MeshLambertMaterial ) {
M
Mr.doob 已提交
4558

4559
			shaderID = 'lambert';
M
Mr.doob 已提交
4560

4561
		} else if ( material instanceof THREE.MeshPhongMaterial ) {
4562

4563
			shaderID = 'phong';
4564

4565
		} else if ( material instanceof THREE.LineBasicMaterial ) {
4566

4567
			shaderID = 'basic';
4568

4569
		} else if ( material instanceof THREE.ParticleBasicMaterial ) {
4570

4571
			shaderID = 'particle_basic';
4572 4573 4574

		}

4575
		if ( shaderID ) {
4576

4577
			setMaterialShaders( material, THREE.ShaderLib[ shaderID ] );
4578

4579
		}
4580

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

4584
		maxLightCount = allocateLights( lights );
4585

4586
		maxShadows = allocateShadows( lights );
4587

4588
		maxBones = allocateBones( object );
4589

4590
		parameters = {
4591

A
alteredq 已提交
4592 4593 4594
			map: !!material.map,
			envMap: !!material.envMap,
			lightMap: !!material.lightMap,
4595
			bumpMap: !!material.bumpMap,
4596
			normalMap: !!material.normalMap,
4597
			specularMap: !!material.specularMap,
A
alteredq 已提交
4598

4599
			vertexColors: material.vertexColors,
A
alteredq 已提交
4600 4601 4602 4603

			fog: fog,
			useFog: material.fog,

4604
			sizeAttenuation: material.sizeAttenuation,
A
alteredq 已提交
4605

4606
			skinning: material.skinning,
A
alteredq 已提交
4607
			maxBones: maxBones,
4608 4609 4610
			useVertexTexture: _supportsBoneTextures && object && object.useVertexTexture,
			boneTextureWidth: object && object.boneTextureWidth,
			boneTextureHeight: object && object.boneTextureHeight,
A
alteredq 已提交
4611

4612
			morphTargets: material.morphTargets,
A
alteredq 已提交
4613
			morphNormals: material.morphNormals,
4614
			maxMorphTargets: this.maxMorphTargets,
A
alteredq 已提交
4615
			maxMorphNormals: this.maxMorphNormals,
A
alteredq 已提交
4616 4617 4618 4619

			maxDirLights: maxLightCount.directional,
			maxPointLights: maxLightCount.point,
			maxSpotLights: maxLightCount.spot,
A
alteredq 已提交
4620
			maxHemiLights: maxLightCount.hemi,
A
alteredq 已提交
4621 4622

			maxShadows: maxShadows,
4623 4624
			shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
			shadowMapSoft: this.shadowMapSoft,
A
alteredq 已提交
4625 4626
			shadowMapDebug: this.shadowMapDebug,
			shadowMapCascade: this.shadowMapCascade,
A
alteredq 已提交
4627

4628 4629
			alphaTest: material.alphaTest,
			metal: material.metal,
4630
			perPixel: material.perPixel,
4631
			wrapAround: material.wrapAround,
4632 4633
			doubleSided: material.side === THREE.DoubleSide,
			flipSided: material.side === THREE.BackSide
4634

4635
		};
M
Mr.doob 已提交
4636

4637
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
4638

4639
		var attributes = material.program.attributes;
4640

4641 4642 4643 4644
		if ( attributes.position >= 0 ) _gl.enableVertexAttribArray( attributes.position );
		if ( attributes.color >= 0 ) _gl.enableVertexAttribArray( attributes.color );
		if ( attributes.normal >= 0 ) _gl.enableVertexAttribArray( attributes.normal );
		if ( attributes.tangent >= 0 ) _gl.enableVertexAttribArray( attributes.tangent );
4645

4646 4647
		if ( material.skinning &&
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
M
Mr.doob 已提交
4648

4649 4650
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
M
Mr.doob 已提交
4651 4652

		}
4653

4654
		if ( material.attributes ) {
A
alteredq 已提交
4655

4656
			for ( a in material.attributes ) {
M
Mr.doob 已提交
4657

4658
				if( attributes[ a ] !== undefined && attributes[ a ] >= 0 ) _gl.enableVertexAttribArray( attributes[ a ] );
4659

4660
			}
M
Mr.doob 已提交
4661

4662
		}
M
Mr.doob 已提交
4663

4664
		if ( material.morphTargets ) {
M
Mr.doob 已提交
4665

4666
			material.numSupportedMorphTargets = 0;
4667

4668
			var id, base = "morphTarget";
4669

4670
			for ( i = 0; i < this.maxMorphTargets; i ++ ) {
4671

4672
				id = base + i;
M
Mr.doob 已提交
4673

4674
				if ( attributes[ id ] >= 0 ) {
M
Mr.doob 已提交
4675

4676 4677
					_gl.enableVertexAttribArray( attributes[ id ] );
					material.numSupportedMorphTargets ++;
4678

4679
				}
4680

4681
			}
4682

4683
		}
4684

A
alteredq 已提交
4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705
		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

			var id, base = "morphNormal";

			for ( i = 0; i < this.maxMorphNormals; i ++ ) {

				id = base + i;

				if ( attributes[ id ] >= 0 ) {

					_gl.enableVertexAttribArray( attributes[ id ] );
					material.numSupportedMorphNormals ++;

				}

			}

		}

4706
		material.uniformsList = [];
4707

4708
		for ( u in material.uniforms ) {
4709

4710
			material.uniformsList.push( [ material.uniforms[ u ], u ] );
4711

4712
		}
M
Mr.doob 已提交
4713

4714
	};
M
Mr.doob 已提交
4715

4716
	function setMaterialShaders( material, shaders ) {
M
Mr.doob 已提交
4717

4718 4719 4720
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
M
Mr.doob 已提交
4721

4722
	};
M
Mr.doob 已提交
4723

4724
	function setProgram( camera, lights, fog, material, object ) {
4725

4726 4727
		_usedTextureUnits = 0;

A
alteredq 已提交
4728
		if ( material.needsUpdate ) {
4729

4730 4731
			if ( material.program ) _this.deallocateMaterial( material );

4732
			_this.initMaterial( material, lights, fog, object );
A
alteredq 已提交
4733
			material.needsUpdate = false;
4734

4735
		}
4736

4737
		if ( material.morphTargets ) {
4738

4739
			if ( ! object.__webglMorphTargetInfluences ) {
4740

4741
				object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );
4742

4743
			}
4744

4745
		}
4746

4747
		var refreshMaterial = false;
4748

4749 4750 4751
		var program = material.program,
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
4752

4753
		if ( program !== _currentProgram ) {
4754

4755 4756
			_gl.useProgram( program );
			_currentProgram = program;
4757

4758
			refreshMaterial = true;
4759

4760
		}
4761

4762
		if ( material.id !== _currentMaterialId ) {
4763

4764 4765
			_currentMaterialId = material.id;
			refreshMaterial = true;
4766

4767
		}
4768

4769
		if ( refreshMaterial || camera !== _currentCamera ) {
4770

A
alteredq 已提交
4771
			_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, camera._projectionMatrixArray );
A
alteredq 已提交
4772

4773 4774 4775 4776
			if ( camera !== _currentCamera ) _currentCamera = camera;

		}

4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805
		// 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 ) {

			if ( _supportsBoneTextures && object.useVertexTexture ) {

				if ( p_uniforms.boneTexture !== null ) {

					var textureUnit = getTextureUnit();

					_gl.uniform1i( p_uniforms.boneTexture, textureUnit );
					_this.setTexture( object.boneTexture, textureUnit );

				}

			} else {

				if ( p_uniforms.boneGlobalMatrices !== null ) {

					_gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.boneMatrices );

				}

			}

		}

4806 4807
		if ( refreshMaterial ) {

4808
			// refresh uniforms common to several materials
4809

4810
			if ( fog && material.fog ) {
4811

4812
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
4813

4814
			}
M
Mr.doob 已提交
4815

4816 4817 4818
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material.lights ) {
4819

4820 4821 4822 4823 4824 4825 4826
				if ( _lightsNeedUpdate ) {

					setupLights( program, lights );
					_lightsNeedUpdate = false;

				}

4827
				refreshUniformsLights( m_uniforms, _lights );
4828

4829
			}
M
Mr.doob 已提交
4830

4831 4832 4833
			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
4834

4835
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
4836 4837 4838

			}

4839
			// refresh single material specific uniforms
M
Mr.doob 已提交
4840

4841
			if ( material instanceof THREE.LineBasicMaterial ) {
4842

4843
				refreshUniformsLine( m_uniforms, material );
M
Mr.doob 已提交
4844

4845
			} else if ( material instanceof THREE.ParticleBasicMaterial ) {
M
Mr.doob 已提交
4846

4847
				refreshUniformsParticle( m_uniforms, material );
M
Mr.doob 已提交
4848

4849
			} else if ( material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
4850

4851
				refreshUniformsPhong( m_uniforms, material );
M
Mr.doob 已提交
4852

4853
			} else if ( material instanceof THREE.MeshLambertMaterial ) {
M
Mr.doob 已提交
4854

4855
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
4856

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

4859 4860 4861
				m_uniforms.mNear.value = camera.near;
				m_uniforms.mFar.value = camera.far;
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4862

4863
			} else if ( material instanceof THREE.MeshNormalMaterial ) {
M
Mr.doob 已提交
4864

4865
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4866

4867
			}
M
Mr.doob 已提交
4868

4869
			if ( object.receiveShadow && ! material._shadowPass ) {
M
Mr.doob 已提交
4870

4871
				refreshUniformsShadow( m_uniforms, lights );
M
Mr.doob 已提交
4872

4873
			}
M
Mr.doob 已提交
4874

4875
			// load common uniforms
M
Mr.doob 已提交
4876

4877
			loadUniformsGeneric( program, material.uniformsList );
M
Mr.doob 已提交
4878

4879 4880
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)
4881

4882 4883 4884
			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
				 material.envMap ) {
4885

4886
				if ( p_uniforms.cameraPosition !== null ) {
4887

4888 4889
					var position = camera.matrixWorld.getPosition();
					_gl.uniform3f( p_uniforms.cameraPosition, position.x, position.y, position.z );
4890

4891
				}
4892 4893 4894

			}

4895 4896 4897 4898
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {
4899

4900
				if ( p_uniforms.viewMatrix !== null ) {
4901

A
alteredq 已提交
4902
					_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, camera._viewMatrixArray );
4903

4904
				}
4905

4906
			}
M
Mr.doob 已提交
4907

4908 4909
		}

4910
		loadUniformsMatrices( p_uniforms, object );
M
Mr.doob 已提交
4911

4912
		if ( p_uniforms.modelMatrix !== null ) {
M
Mr.doob 已提交
4913

4914
			_gl.uniformMatrix4fv( p_uniforms.modelMatrix, false, object.matrixWorld.elements );
4915

4916
		}
4917

4918
		return program;
4919

4920
	};
4921

4922
	// Uniforms (refresh uniforms objects)
A
alteredq 已提交
4923

4924
	function refreshUniformsCommon ( uniforms, material ) {
4925

4926
		uniforms.opacity.value = material.opacity;
4927

4928
		if ( _this.gammaInput ) {
4929

4930
			uniforms.diffuse.value.copyGammaToLinear( material.color );
4931

4932
		} else {
4933

4934
			uniforms.diffuse.value = material.color;
4935

4936
		}
4937

4938 4939 4940
		uniforms.map.value = material.map;
		uniforms.lightMap.value = material.lightMap;
		uniforms.specularMap.value = material.specularMap;
4941

4942
		if ( material.bumpMap ) {
4943

4944
			uniforms.bumpMap.value = material.bumpMap;
4945
			uniforms.bumpScale.value = material.bumpScale;
M
Mr.doob 已提交
4946

4947
		}
M
Mr.doob 已提交
4948

4949 4950
		if ( material.normalMap ) {

4951
			uniforms.normalMap.value = material.normalMap;
4952
			uniforms.normalScale.value = material.normalScale;
4953

4954
		}
M
Mr.doob 已提交
4955

4956 4957 4958
		// uv repeat and offset setting priorities
		//	1. color map
		//	2. specular map
4959 4960
		//	3. normal map
		//	4. bump map
4961

4962
		var uvScaleMap;
4963

4964
		if ( material.map ) {
4965

4966
			uvScaleMap = material.map;
4967

4968
		} else if ( material.specularMap ) {
4969

4970 4971
			uvScaleMap = material.specularMap;

4972 4973 4974 4975
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987
		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

		}

		if ( uvScaleMap !== undefined ) {

			var offset = uvScaleMap.offset;
			var repeat = uvScaleMap.repeat;

			uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
4988

4989
		}
4990

4991
		uniforms.envMap.value = material.envMap;
4992
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
4993

4994
		if ( _this.gammaInput ) {
4995

4996 4997
			//uniforms.reflectivity.value = material.reflectivity * material.reflectivity;
			uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
4998

4999
		} else {
5000

5001
			uniforms.reflectivity.value = material.reflectivity;
5002

5003
		}
5004

5005 5006 5007
		uniforms.refractionRatio.value = material.refractionRatio;
		uniforms.combine.value = material.combine;
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
M
Mr.doob 已提交
5008

5009
	};
M
Mr.doob 已提交
5010

5011
	function refreshUniformsLine ( uniforms, material ) {
M
Mr.doob 已提交
5012

5013 5014
		uniforms.diffuse.value = material.color;
		uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
5015

5016
	};
M
Mr.doob 已提交
5017

5018
	function refreshUniformsParticle ( uniforms, material ) {
5019

5020 5021 5022 5023
		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.
5024

5025
		uniforms.map.value = material.map;
5026

5027
	};
5028

5029
	function refreshUniformsFog ( uniforms, fog ) {
5030

5031
		uniforms.fogColor.value = fog.color;
5032

5033
		if ( fog instanceof THREE.Fog ) {
5034

5035 5036
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
5037

5038
		} else if ( fog instanceof THREE.FogExp2 ) {
M
Mikael Emtinger 已提交
5039

5040
			uniforms.fogDensity.value = fog.density;
M
Mikael Emtinger 已提交
5041

5042
		}
M
Mikael Emtinger 已提交
5043

5044
	};
M
Mikael Emtinger 已提交
5045

5046
	function refreshUniformsPhong ( uniforms, material ) {
M
Mikael Emtinger 已提交
5047

5048
		uniforms.shininess.value = material.shininess;
5049

5050
		if ( _this.gammaInput ) {
M
Mikael Emtinger 已提交
5051

5052
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
5053
			uniforms.emissive.value.copyGammaToLinear( material.emissive );
5054
			uniforms.specular.value.copyGammaToLinear( material.specular );
5055

5056
		} else {
5057

5058
			uniforms.ambient.value = material.ambient;
5059
			uniforms.emissive.value = material.emissive;
5060
			uniforms.specular.value = material.specular;
5061

5062
		}
5063

5064 5065 5066 5067 5068 5069
		if ( material.wrapAround ) {

			uniforms.wrapRGB.value.copy( material.wrapRGB );

		}

5070
	};
5071

5072
	function refreshUniformsLambert ( uniforms, material ) {
5073

5074
		if ( _this.gammaInput ) {
5075

5076
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
5077
			uniforms.emissive.value.copyGammaToLinear( material.emissive );
M
Mr.doob 已提交
5078

5079
		} else {
5080

5081
			uniforms.ambient.value = material.ambient;
5082
			uniforms.emissive.value = material.emissive;
5083

5084
		}
5085

5086 5087 5088 5089 5090 5091
		if ( material.wrapAround ) {

			uniforms.wrapRGB.value.copy( material.wrapRGB );

		}

5092
	};
5093

5094
	function refreshUniformsLights ( uniforms, lights ) {
5095

5096
		uniforms.ambientLightColor.value = lights.ambient;
5097

5098 5099
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
5100

5101 5102 5103
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
		uniforms.pointLightDistance.value = lights.point.distances;
5104

A
alteredq 已提交
5105 5106 5107 5108 5109 5110 5111
		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.spotLightAngle.value = lights.spot.angles;
		uniforms.spotLightExponent.value = lights.spot.exponents;

A
alteredq 已提交
5112 5113 5114 5115
		uniforms.hemisphereLightSkyColor.value = lights.hemi.skyColors;
		uniforms.hemisphereLightGroundColor.value = lights.hemi.groundColors;
		uniforms.hemisphereLightPosition.value = lights.hemi.positions;

5116
	};
5117

5118
	function refreshUniformsShadow ( uniforms, lights ) {
M
Mr.doob 已提交
5119

5120
		if ( uniforms.shadowMatrix ) {
5121

5122
			var j = 0;
5123

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

5126
				var light = lights[ i ];
5127

A
alteredq 已提交
5128 5129
				if ( ! light.castShadow ) continue;

5130
				if ( light instanceof THREE.SpotLight || ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) ) {
5131

5132
					uniforms.shadowMap.value[ j ] = light.shadowMap;
5133
					uniforms.shadowMapSize.value[ j ] = light.shadowMapSize;
5134

5135 5136 5137 5138 5139 5140 5141 5142 5143 5144
					uniforms.shadowMatrix.value[ j ] = light.shadowMatrix;

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

					j ++;

				}

			}
5145

5146 5147
		}

5148
	};
5149

5150
	// Uniforms (load to GPU)
5151

5152
	function loadUniformsMatrices ( uniforms, object ) {
5153

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

5156
		if ( uniforms.normalMatrix ) {
5157

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

5160
		}
5161

5162
	};
5163

5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179
	function getTextureUnit() {

		var textureUnit = _usedTextureUnits;

		if ( textureUnit >= _maxTextures ) {

			console.warn( "Trying to use " + textureUnit + " texture units while this GPU supports only " + _maxTextures );

		}

		_usedTextureUnits += 1;

		return textureUnit;

	};

5180
	function loadUniformsGeneric ( program, uniforms ) {
5181

5182
		var uniform, value, type, location, texture, textureUnit, i, il, j, jl, offset;
5183

M
Mr.doob 已提交
5184
		for ( j = 0, jl = uniforms.length; j < jl; j ++ ) {
5185

5186 5187
			location = program.uniforms[ uniforms[ j ][ 1 ] ];
			if ( !location ) continue;
5188

5189
			uniform = uniforms[ j ][ 0 ];
5190

5191 5192
			type = uniform.type;
			value = uniform.value;
5193

5194
			if ( type === "i" ) { // single integer
5195

5196
				_gl.uniform1i( location, value );
5197

5198
			} else if ( type === "f" ) { // single float
5199

5200
				_gl.uniform1f( location, value );
5201

5202
			} else if ( type === "v2" ) { // single THREE.Vector2
5203

5204
				_gl.uniform2f( location, value.x, value.y );
5205

5206
			} else if ( type === "v3" ) { // single THREE.Vector3
5207

5208
				_gl.uniform3f( location, value.x, value.y, value.z );
5209

5210
			} else if ( type === "v4" ) { // single THREE.Vector4
5211

5212
				_gl.uniform4f( location, value.x, value.y, value.z, value.w );
5213

5214
			} else if ( type === "c" ) { // single THREE.Color
5215

5216
				_gl.uniform3f( location, value.r, value.g, value.b );
5217

5218 5219 5220
			} else if ( type === "iv1" ) { // flat array of integers (JS or typed array)

				_gl.uniform1iv( location, value );
5221 5222 5223 5224

			} else if ( type === "iv" ) { // flat array of integers with 3 x N size (JS or typed array)

				_gl.uniform3iv( location, value );
5225

5226
			} else if ( type === "fv1" ) { // flat array of floats (JS or typed array)
5227

5228
				_gl.uniform1fv( location, value );
5229

5230
			} else if ( type === "fv" ) { // flat array of floats with 3 x N size (JS or typed array)
5231

5232
				_gl.uniform3fv( location, value );
5233

5234
			} else if ( type === "v2v" ) { // array of THREE.Vector2
5235

5236
				if ( uniform._array === undefined ) {
5237

5238
					uniform._array = new Float32Array( 2 * value.length );
5239

5240
				}
5241

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

5244
					offset = i * 2;
5245

5246 5247
					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;
5248

5249
				}
5250

5251
				_gl.uniform2fv( location, uniform._array );
5252

5253
			} else if ( type === "v3v" ) { // array of THREE.Vector3
5254

5255
				if ( uniform._array === undefined ) {
M
Mr.doob 已提交
5256

5257
					uniform._array = new Float32Array( 3 * value.length );
A
alteredq 已提交
5258

5259
				}
5260

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

5263
					offset = i * 3;
5264

5265 5266 5267
					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;
					uniform._array[ offset + 2 ] = value[ i ].z;
A
alteredq 已提交
5268

5269
				}
5270

5271
				_gl.uniform3fv( location, uniform._array );
A
alteredq 已提交
5272

5273
			} else if ( type === "v4v" ) { // array of THREE.Vector4
M
Mr.doob 已提交
5274

5275
				if ( uniform._array === undefined ) {
M
Mr.doob 已提交
5276

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

5279
				}
A
alteredq 已提交
5280

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

5283
					offset = i * 4;
M
Mr.doob 已提交
5284

5285 5286 5287 5288
					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;
					uniform._array[ offset + 2 ] = value[ i ].z;
					uniform._array[ offset + 3 ] = value[ i ].w;
A
alteredq 已提交
5289

5290
				}
5291

5292
				_gl.uniform4fv( location, uniform._array );
A
alteredq 已提交
5293

5294
			} else if ( type === "m4") { // single THREE.Matrix4
A
alteredq 已提交
5295

5296
				if ( uniform._array === undefined ) {
A
alteredq 已提交
5297

5298
					uniform._array = new Float32Array( 16 );
A
alteredq 已提交
5299

5300
				}
M
Mr.doob 已提交
5301

5302 5303
				value.flattenToArray( uniform._array );
				_gl.uniformMatrix4fv( location, false, uniform._array );
5304

5305
			} else if ( type === "m4v" ) { // array of THREE.Matrix4
5306

5307
				if ( uniform._array === undefined ) {
5308

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

5311
				}
M
Mr.doob 已提交
5312

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

5315
					value[ i ].flattenToArrayOffset( uniform._array, i * 16 );
A
alteredq 已提交
5316

5317
				}
M
Mr.doob 已提交
5318

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

5321
			} else if ( type === "t" ) { // single THREE.Texture (2d or cube)
5322

5323 5324
				texture = value;
				textureUnit = getTextureUnit();
M
Mr.doob 已提交
5325

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

5328
				if ( !texture ) continue;
M
Mr.doob 已提交
5329

5330
				if ( texture.image instanceof Array && texture.image.length === 6 ) {
M
Mr.doob 已提交
5331

5332
					setCubeTexture( texture, textureUnit );
M
Mr.doob 已提交
5333

5334
				} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
M
Mr.doob 已提交
5335

5336
					setCubeTextureDynamic( texture, textureUnit );
5337

5338
				} else {
A
alteredq 已提交
5339

5340
					_this.setTexture( texture, textureUnit );
A
alteredq 已提交
5341

5342
				}
A
alteredq 已提交
5343

5344
			} else if ( type === "tv" ) { // array of THREE.Texture (2d)
5345

5346
				if ( uniform._array === undefined ) {
5347

5348
					uniform._array = [];
M
Mr.doob 已提交
5349

5350
				}
M
Mr.doob 已提交
5351

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

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

5356
				}
M
Mr.doob 已提交
5357

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

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

5362 5363
					texture = uniform.value[ i ];
					textureUnit = uniform._array[ i ];
M
Mr.doob 已提交
5364

5365
					if ( !texture ) continue;
M
Mr.doob 已提交
5366

5367
					_this.setTexture( texture, textureUnit );
M
Mr.doob 已提交
5368

5369
				}
M
Mr.doob 已提交
5370

M
Mr.doob 已提交
5371
			}
M
Mr.doob 已提交
5372

M
Mr.doob 已提交
5373
		}
M
Mr.doob 已提交
5374

5375
	};
M
Mr.doob 已提交
5376

A
alteredq 已提交
5377
	function setupMatrices ( object, camera ) {
M
Mr.doob 已提交
5378

5379
		object._modelViewMatrix.multiply( camera.matrixWorldInverse, object.matrixWorld );
M
Mr.doob 已提交
5380

5381
		object._normalMatrix.getInverse( object._modelViewMatrix );
5382
		object._normalMatrix.transpose();
M
Mr.doob 已提交
5383

A
alteredq 已提交
5384
	};
M
Mr.doob 已提交
5385

A
alteredq 已提交
5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403
	//

	function setColorGamma( array, offset, color, intensitySq ) {

		array[ offset ]     = color.r * color.r * intensitySq;
		array[ offset + 1 ] = color.g * color.g * intensitySq;
		array[ offset + 2 ] = color.b * color.b * intensitySq;

	};

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

		array[ offset ]     = color.r * intensity;
		array[ offset + 1 ] = color.g * intensity;
		array[ offset + 2 ] = color.b * intensity;

	};

5404
	function setupLights ( program, lights ) {
M
Mr.doob 已提交
5405

5406 5407
		var l, ll, light, n,
		r = 0, g = 0, b = 0,
A
alteredq 已提交
5408 5409 5410 5411
		color, skyColor, groundColor,
		intensity,  intensitySq,
		position,
		distance,
M
Mr.doob 已提交
5412

5413
		zlights = _lights,
A
alteredq 已提交
5414

A
alteredq 已提交
5415 5416 5417 5418 5419 5420
		dirColors = zlights.directional.colors,
		dirPositions = zlights.directional.positions,

		pointColors = zlights.point.colors,
		pointPositions = zlights.point.positions,
		pointDistances = zlights.point.distances,
A
alteredq 已提交
5421

A
alteredq 已提交
5422 5423 5424 5425 5426 5427
		spotColors = zlights.spot.colors,
		spotPositions = zlights.spot.positions,
		spotDistances = zlights.spot.distances,
		spotDirections = zlights.spot.directions,
		spotAngles = zlights.spot.angles,
		spotExponents = zlights.spot.exponents,
5428

A
alteredq 已提交
5429 5430 5431
		hemiSkyColors = zlights.hemi.skyColors,
		hemiGroundColors = zlights.hemi.groundColors,
		hemiPositions = zlights.hemi.positions,
A
alteredq 已提交
5432

A
alteredq 已提交
5433 5434 5435 5436
		dirLength = 0,
		pointLength = 0,
		spotLength = 0,
		hemiLength = 0,
5437

A
alteredq 已提交
5438 5439 5440 5441
		dirOffset = 0,
		pointOffset = 0,
		spotOffset = 0,
		hemiOffset = 0;
5442

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

5445
			light = lights[ l ];
A
alteredq 已提交
5446

5447
			if ( light.onlyShadow || ! light.visible ) continue;
A
alteredq 已提交
5448 5449

			color = light.color;
5450 5451
			intensity = light.intensity;
			distance = light.distance;
A
alteredq 已提交
5452

5453
			if ( light instanceof THREE.AmbientLight ) {
5454

5455
				if ( _this.gammaInput ) {
5456

5457 5458 5459
					r += color.r * color.r;
					g += color.g * color.g;
					b += color.b * color.b;
5460

5461
				} else {
5462

5463 5464 5465
					r += color.r;
					g += color.g;
					b += color.b;
5466

5467
				}
5468

5469
			} else if ( light instanceof THREE.DirectionalLight ) {
5470

A
alteredq 已提交
5471
				dirOffset = dirLength * 3;
5472

5473
				if ( _this.gammaInput ) {
5474

A
alteredq 已提交
5475
					setColorGamma( dirColors, dirOffset, color, intensity * intensity );
5476

5477
				} else {
5478

A
alteredq 已提交
5479
					setColorLinear( dirColors, dirOffset, color, intensity );
A
alteredq 已提交
5480

5481
				}
A
alteredq 已提交
5482

5483 5484 5485
				_direction.copy( light.matrixWorld.getPosition() );
				_direction.subSelf( light.target.matrixWorld.getPosition() );
				_direction.normalize();
A
alteredq 已提交
5486

A
alteredq 已提交
5487 5488 5489
				dirPositions[ dirOffset ]     = _direction.x;
				dirPositions[ dirOffset + 1 ] = _direction.y;
				dirPositions[ dirOffset + 2 ] = _direction.z;
A
alteredq 已提交
5490

A
alteredq 已提交
5491
				dirLength += 1;
A
alteredq 已提交
5492

A
alteredq 已提交
5493
			} else if( light instanceof THREE.PointLight ) {
M
Mr.doob 已提交
5494

A
alteredq 已提交
5495
				pointOffset = pointLength * 3;
M
Mr.doob 已提交
5496

5497
				if ( _this.gammaInput ) {
5498

A
alteredq 已提交
5499
					setColorGamma( pointColors, pointOffset, color, intensity * intensity );
A
alteredq 已提交
5500

5501
				} else {
A
alteredq 已提交
5502

A
alteredq 已提交
5503
					setColorLinear( pointColors, pointOffset, color, intensity );
A
alteredq 已提交
5504

5505
				}
A
alteredq 已提交
5506

A
alteredq 已提交
5507 5508
				position = light.matrixWorld.getPosition();

A
alteredq 已提交
5509 5510 5511
				pointPositions[ pointOffset ]     = position.x;
				pointPositions[ pointOffset + 1 ] = position.y;
				pointPositions[ pointOffset + 2 ] = position.z;
A
alteredq 已提交
5512

A
alteredq 已提交
5513
				pointDistances[ pointLength ] = distance;
A
alteredq 已提交
5514

A
alteredq 已提交
5515
				pointLength += 1;
5516

A
alteredq 已提交
5517 5518
			} else if( light instanceof THREE.SpotLight ) {

A
alteredq 已提交
5519
				spotOffset = spotLength * 3;
A
alteredq 已提交
5520 5521 5522

				if ( _this.gammaInput ) {

A
alteredq 已提交
5523
					setColorGamma( spotColors, spotOffset, color, intensity * intensity );
A
alteredq 已提交
5524 5525 5526

				} else {

A
alteredq 已提交
5527
					setColorLinear( spotColors, spotOffset, color, intensity );
A
alteredq 已提交
5528 5529 5530 5531 5532

				}

				position = light.matrixWorld.getPosition();

A
alteredq 已提交
5533 5534 5535
				spotPositions[ spotOffset ]     = position.x;
				spotPositions[ spotOffset + 1 ] = position.y;
				spotPositions[ spotOffset + 2 ] = position.z;
A
alteredq 已提交
5536

A
alteredq 已提交
5537
				spotDistances[ spotLength ] = distance;
A
alteredq 已提交
5538 5539 5540 5541 5542

				_direction.copy( position );
				_direction.subSelf( light.target.matrixWorld.getPosition() );
				_direction.normalize();

A
alteredq 已提交
5543 5544 5545 5546 5547 5548 5549 5550 5551 5552
				spotDirections[ spotOffset ]     = _direction.x;
				spotDirections[ spotOffset + 1 ] = _direction.y;
				spotDirections[ spotOffset + 2 ] = _direction.z;

				spotAngles[ spotLength ] = Math.cos( light.angle );
				spotExponents[ spotLength ] = light.exponent;

				spotLength += 1;

			} else if ( light instanceof THREE.HemisphereLight ) {
A
alteredq 已提交
5553

A
alteredq 已提交
5554 5555
				skyColor = light.color;
				groundColor = light.groundColor;
A
alteredq 已提交
5556

A
alteredq 已提交
5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579
				hemiOffset = hemiLength * 3;

				if ( _this.gammaInput ) {

					intensitySq = intensity * intensity;

					setColorGamma( hemiSkyColors, hemiOffset, skyColor, intensitySq );
					setColorGamma( hemiGroundColors, hemiOffset, groundColor, intensitySq );

				} else {

					setColorLinear( hemiSkyColors, hemiOffset, skyColor, intensity );
					setColorLinear( hemiGroundColors, hemiOffset, groundColor, intensity );

				}

				position = light.matrixWorld.getPosition();

				hemiPositions[ hemiOffset ]     = position.x;
				hemiPositions[ hemiOffset + 1 ] = position.y;
				hemiPositions[ hemiOffset + 2 ] = position.z;

				hemiLength += 1;
A
alteredq 已提交
5580

5581
			}
5582

5583
		}
A
alteredq 已提交
5584

5585 5586
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
A
alteredq 已提交
5587

A
alteredq 已提交
5588 5589 5590 5591 5592
		for ( l = dirLength * 3, ll = dirColors.length; l < ll; l ++ ) dirColors[ l ] = 0.0;
		for ( l = pointLength * 3, ll = pointColors.length; l < ll; l ++ ) pointColors[ l ] = 0.0;
		for ( l = spotLength * 3, ll = spotColors.length; l < ll; l ++ ) spotColors[ l ] = 0.0;
		for ( l = hemiLength * 3, ll = hemiSkyColors.length; l < ll; l ++ ) hemiSkyColors[ l ] = 0.0;
		for ( l = hemiLength * 3, ll = hemiGroundColors.length; l < ll; l ++ ) hemiGroundColors[ l ] = 0.0;
A
alteredq 已提交
5593

A
alteredq 已提交
5594 5595 5596 5597
		zlights.directional.length = dirLength;
		zlights.point.length = pointLength;
		zlights.spot.length = spotLength;
		zlights.hemi.length = hemiLength;
A
alteredq 已提交
5598

5599 5600 5601
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
5602

5603
	};
M
Mr.doob 已提交
5604

5605
	// GL state setting
M
Mr.doob 已提交
5606

5607
	this.setFaceCulling = function ( cullFace, frontFace ) {
M
Mr.doob 已提交
5608

5609
		if ( cullFace ) {
M
Mr.doob 已提交
5610

5611
			if ( !frontFace || frontFace === "ccw" ) {
5612

5613
				_gl.frontFace( _gl.CCW );
5614

5615
			} else {
5616

5617
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
5618

5619
			}
M
Mr.doob 已提交
5620

5621
			if( cullFace === "back" ) {
5622

5623
				_gl.cullFace( _gl.BACK );
5624

5625
			} else if( cullFace === "front" ) {
5626

5627
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
5628

5629
			} else {
5630

5631
				_gl.cullFace( _gl.FRONT_AND_BACK );
5632

5633
			}
5634

5635
			_gl.enable( _gl.CULL_FACE );
5636

5637
		} else {
5638

5639
			_gl.disable( _gl.CULL_FACE );
5640 5641 5642 5643 5644

		}

	};

5645
	this.setMaterialFaces = function ( material ) {
5646

5647 5648
		var doubleSided = material.side === THREE.DoubleSide;
		var flipSided = material.side === THREE.BackSide;
M
Mr.doob 已提交
5649

5650 5651 5652
		if ( _oldDoubleSided !== doubleSided ) {

			if ( doubleSided ) {
M
Mr.doob 已提交
5653

5654
				_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
5655

5656
			} else {
5657

5658
				_gl.enable( _gl.CULL_FACE );
5659

5660
			}
5661

5662
			_oldDoubleSided = doubleSided;
5663

5664
		}
5665

5666
		if ( _oldFlipSided !== flipSided ) {
5667

5668
			if ( flipSided ) {
5669

5670
				_gl.frontFace( _gl.CW );
5671

5672
			} else {
5673

5674
				_gl.frontFace( _gl.CCW );
5675

5676
			}
5677

5678
			_oldFlipSided = flipSided;
5679

5680
		}
5681

5682
	};
5683

A
alteredq 已提交
5684
	this.setDepthTest = function ( depthTest ) {
5685

5686
		if ( _oldDepthTest !== depthTest ) {
5687

5688
			if ( depthTest ) {
5689

5690
				_gl.enable( _gl.DEPTH_TEST );
5691

5692
			} else {
5693

5694
				_gl.disable( _gl.DEPTH_TEST );
5695 5696 5697

			}

5698
			_oldDepthTest = depthTest;
5699

5700
		}
5701

5702
	};
5703

5704
	this.setDepthWrite = function ( depthWrite ) {
A
alteredq 已提交
5705

5706
		if ( _oldDepthWrite !== depthWrite ) {
A
alteredq 已提交
5707

5708 5709
			_gl.depthMask( depthWrite );
			_oldDepthWrite = depthWrite;
A
alteredq 已提交
5710 5711 5712 5713 5714

		}

	};

5715
	function setLineWidth ( width ) {
5716

5717
		if ( width !== _oldLineWidth ) {
5718

5719 5720 5721
			_gl.lineWidth( width );

			_oldLineWidth = width;
5722 5723 5724

		}

5725
	};
5726

5727
	function setPolygonOffset ( polygonoffset, factor, units ) {
5728

5729
		if ( _oldPolygonOffset !== polygonoffset ) {
M
Mr.doob 已提交
5730

5731
			if ( polygonoffset ) {
5732

5733
				_gl.enable( _gl.POLYGON_OFFSET_FILL );
5734

5735
			} else {
5736

5737
				_gl.disable( _gl.POLYGON_OFFSET_FILL );
5738

5739
			}
5740

5741
			_oldPolygonOffset = polygonoffset;
5742

5743
		}
5744

5745
		if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
5746

5747
			_gl.polygonOffset( factor, units );
M
Mr.doob 已提交
5748

5749 5750
			_oldPolygonOffsetFactor = factor;
			_oldPolygonOffsetUnits = units;
M
Mr.doob 已提交
5751

5752
		}
M
Mr.doob 已提交
5753

5754
	};
M
Mr.doob 已提交
5755

5756
	this.setBlending = function ( blending, blendEquation, blendSrc, blendDst ) {
M
Mr.doob 已提交
5757

5758
		if ( blending !== _oldBlending ) {
M
Mr.doob 已提交
5759

5760
			if ( blending === THREE.NoBlending ) {
M
Mr.doob 已提交
5761

5762
				_gl.disable( _gl.BLEND );
M
Mr.doob 已提交
5763

5764
			} else if ( blending === THREE.AdditiveBlending ) {
M
Mr.doob 已提交
5765

5766 5767 5768
				_gl.enable( _gl.BLEND );
				_gl.blendEquation( _gl.FUNC_ADD );
				_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
M
Mr.doob 已提交
5769

5770
			} else if ( blending === THREE.SubtractiveBlending ) {
M
Mr.doob 已提交
5771

5772 5773 5774 5775
				// TODO: Find blendFuncSeparate() combination
				_gl.enable( _gl.BLEND );
				_gl.blendEquation( _gl.FUNC_ADD );
				_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
M
Mr.doob 已提交
5776

5777
			} else if ( blending === THREE.MultiplyBlending ) {
M
Mr.doob 已提交
5778

5779 5780 5781 5782
				// TODO: Find blendFuncSeparate() combination
				_gl.enable( _gl.BLEND );
				_gl.blendEquation( _gl.FUNC_ADD );
				_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
5783

5784
			} else if ( blending === THREE.CustomBlending ) {
5785

5786
				_gl.enable( _gl.BLEND );
5787

5788
			} else {
5789

5790 5791 5792
				_gl.enable( _gl.BLEND );
				_gl.blendEquationSeparate( _gl.FUNC_ADD, _gl.FUNC_ADD );
				_gl.blendFuncSeparate( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA, _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
5793

5794
			}
5795

5796
			_oldBlending = blending;
5797

5798
		}
5799

5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826
		if ( blending === THREE.CustomBlending ) {

			if ( blendEquation !== _oldBlendEquation ) {

				_gl.blendEquation( paramThreeToGL( blendEquation ) );

				_oldBlendEquation = blendEquation;

			}

			if ( blendSrc !== _oldBlendSrc || blendDst !== _oldBlendDst ) {

				_gl.blendFunc( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ) );

				_oldBlendSrc = blendSrc;
				_oldBlendDst = blendDst;

			}

		} else {

			_oldBlendEquation = null;
			_oldBlendSrc = null;
			_oldBlendDst = null;

		}

5827
	};
5828

5829 5830 5831
	// Shaders

	function buildProgram ( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
5832

5833
		var p, pl, program, code;
5834
		var chunks = [];
5835 5836 5837

		// Generate code

5838 5839 5840 5841 5842 5843 5844 5845 5846 5847
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

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

		}
5848 5849 5850

		for ( p in parameters ) {

5851 5852
			chunks.push( p );
			chunks.push( parameters[ p ] );
5853 5854 5855

		}

5856 5857
		code = chunks.join();

5858 5859 5860 5861
		// Check if code has been already compiled

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

A
alteredq 已提交
5862 5863 5864
			var programInfo = _programs[ p ];

			if ( programInfo.code === code ) {
5865 5866

				// console.log( "Code already compiled." /*: \n\n" + code*/ );
5867

A
alteredq 已提交
5868 5869 5870
				programInfo.usedTimes ++;

				return programInfo.program;
5871 5872 5873 5874

			}

		}
5875

5876
		//console.log( "building new program " );
5877 5878 5879

		//

5880
		program = _gl.createProgram();
M
Mr.doob 已提交
5881

5882
		var prefix_vertex = [
M
Mr.doob 已提交
5883

5884 5885
			"precision " + _precision + " float;",

5886
			_supportsVertexTextures ? "#define VERTEX_TEXTURES" : "",
5887

5888 5889 5890 5891
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

5892 5893
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
5894
			"#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
A
alteredq 已提交
5895
			"#define MAX_HEMI_LIGHTS " + parameters.maxHemiLights,
5896

5897 5898
			"#define MAX_SHADOWS " + parameters.maxShadows,

5899 5900
			"#define MAX_BONES " + parameters.maxBones,

5901
			parameters.map ? "#define USE_MAP" : "",
5902 5903
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
5904
			parameters.bumpMap ? "#define USE_BUMPMAP" : "",
5905
			parameters.normalMap ? "#define USE_NORMALMAP" : "",
5906
			parameters.specularMap ? "#define USE_SPECULARMAP" : "",
5907
			parameters.vertexColors ? "#define USE_COLOR" : "",
5908

5909
			parameters.skinning ? "#define USE_SKINNING" : "",
5910
			parameters.useVertexTexture ? "#define BONE_TEXTURE" : "",
5911 5912
			parameters.boneTextureWidth ? "#define N_BONE_PIXEL_X " + parameters.boneTextureWidth.toFixed( 1 ) : "",
			parameters.boneTextureHeight ? "#define N_BONE_PIXEL_Y " + parameters.boneTextureHeight.toFixed( 1 ) : "",
5913

5914
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
A
alteredq 已提交
5915
			parameters.morphNormals ? "#define USE_MORPHNORMALS" : "",
A
alteredq 已提交
5916
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
5917
			parameters.wrapAround ? "#define WRAP_AROUND" : "",
5918
			parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
5919
			parameters.flipSided ? "#define FLIP_SIDED" : "",
5920

5921
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5922
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
A
alteredq 已提交
5923 5924
			parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
			parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
5925

5926 5927
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

5928
			"uniform mat4 modelMatrix;",
M
Mr.doob 已提交
5929 5930
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
5931 5932
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
5933
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
5934

M
Mr.doob 已提交
5935 5936 5937
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
5938
			"attribute vec2 uv2;",
5939

5940
			"#ifdef USE_COLOR",
5941

5942
				"attribute vec3 color;",
5943

5944 5945
			"#endif",

5946
			"#ifdef USE_MORPHTARGETS",
5947

5948 5949 5950 5951
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
A
alteredq 已提交
5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967

				"#ifdef USE_MORPHNORMALS",

					"attribute vec3 morphNormal0;",
					"attribute vec3 morphNormal1;",
					"attribute vec3 morphNormal2;",
					"attribute vec3 morphNormal3;",

				"#else",

					"attribute vec3 morphTarget4;",
					"attribute vec3 morphTarget5;",
					"attribute vec3 morphTarget6;",
					"attribute vec3 morphTarget7;",

				"#endif",
5968

5969 5970 5971
			"#endif",

			"#ifdef USE_SKINNING",
5972

5973 5974
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
5975

5976
			"#endif",
5977

M
Mr.doob 已提交
5978
			""
A
alteredq 已提交
5979

M
Mr.doob 已提交
5980
		].join("\n");
5981

M
Mr.doob 已提交
5982 5983
		var prefix_fragment = [

5984
			"precision " + _precision + " float;",
M
Mr.doob 已提交
5985

5986
			( parameters.bumpMap || parameters.normalMap ) ? "#extension GL_OES_standard_derivatives : enable" : "",
5987

M
Mr.doob 已提交
5988 5989
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
5990
			"#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
A
alteredq 已提交
5991
			"#define MAX_HEMI_LIGHTS " + parameters.maxHemiLights,
M
Mr.doob 已提交
5992

5993 5994
			"#define MAX_SHADOWS " + parameters.maxShadows,

5995 5996
			parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",

5997 5998 5999 6000
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

M
Mr.doob 已提交
6001 6002
			( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
			( parameters.useFog && parameters.fog instanceof THREE.FogExp2 ) ? "#define FOG_EXP2" : "",
M
Mr.doob 已提交
6003 6004 6005 6006

			parameters.map ? "#define USE_MAP" : "",
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
6007
			parameters.bumpMap ? "#define USE_BUMPMAP" : "",
6008
			parameters.normalMap ? "#define USE_NORMALMAP" : "",
6009
			parameters.specularMap ? "#define USE_SPECULARMAP" : "",
M
Mr.doob 已提交
6010
			parameters.vertexColors ? "#define USE_COLOR" : "",
6011

6012 6013
			parameters.metal ? "#define METAL" : "",
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
6014
			parameters.wrapAround ? "#define WRAP_AROUND" : "",
6015
			parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
6016
			parameters.flipSided ? "#define FLIP_SIDED" : "",
6017

6018
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
6019
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
A
alteredq 已提交
6020 6021
			parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
			parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
M
Mr.doob 已提交
6022 6023 6024 6025 6026 6027 6028

			"uniform mat4 viewMatrix;",
			"uniform vec3 cameraPosition;",
			""

		].join("\n");

6029 6030 6031 6032 6033
		var glFragmentShader = getShader( "fragment", prefix_fragment + fragmentShader );
		var glVertexShader = getShader( "vertex", prefix_vertex + vertexShader );

		_gl.attachShader( program, glVertexShader );
		_gl.attachShader( program, glFragmentShader );
M
Mr.doob 已提交
6034

M
Mr.doob 已提交
6035
		_gl.linkProgram( program );
N
Nicolas Garcia Belmonte 已提交
6036

M
Mr.doob 已提交
6037
		if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
N
Nicolas Garcia Belmonte 已提交
6038

6039
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
6040

N
Nicolas Garcia Belmonte 已提交
6041
		}
6042

6043 6044 6045 6046 6047
		// clean up

		_gl.deleteShader( glFragmentShader );
		_gl.deleteShader( glVertexShader );

6048 6049
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
6050

M
Mr.doob 已提交
6051
		program.uniforms = {};
6052
		program.attributes = {};
M
Mr.doob 已提交
6053

6054 6055 6056 6057
		var identifiers, u, a, i;

		// cache uniform locations

6058
		identifiers = [
6059

6060
			'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'modelMatrix', 'cameraPosition',
6061
			'morphTargetInfluences'
M
Mr.doob 已提交
6062

6063
		];
M
Mr.doob 已提交
6064

6065
		if ( parameters.useVertexTexture ) {
6066 6067 6068 6069 6070 6071 6072 6073 6074

			identifiers.push( 'boneTexture' );

		} else {

			identifiers.push( 'boneGlobalMatrices' );

		}

6075
		for ( u in uniforms ) {
M
Mr.doob 已提交
6076

6077
			identifiers.push( u );
M
Mr.doob 已提交
6078

6079
		}
M
Mr.doob 已提交
6080

6081
		cacheUniformLocations( program, identifiers );
M
Mr.doob 已提交
6082

6083
		// cache attributes locations
M
Mr.doob 已提交
6084

6085
		identifiers = [
A
alteredq 已提交
6086

6087
			"position", "normal", "uv", "uv2", "tangent", "color",
6088
			"skinIndex", "skinWeight"
A
alteredq 已提交
6089

6090
		];
M
Mr.doob 已提交
6091

6092
		for ( i = 0; i < parameters.maxMorphTargets; i ++ ) {
M
Mr.doob 已提交
6093

6094
			identifiers.push( "morphTarget" + i );
M
Mr.doob 已提交
6095

6096
		}
6097

A
alteredq 已提交
6098 6099 6100 6101 6102 6103
		for ( i = 0; i < parameters.maxMorphNormals; i ++ ) {

			identifiers.push( "morphNormal" + i );

		}

6104
		for ( a in attributes ) {
6105

6106
			identifiers.push( a );
6107

6108
		}
6109

6110
		cacheAttributeLocations( program, identifiers );
6111

A
alteredq 已提交
6112
		program.id = _programs_counter ++;
6113

A
alteredq 已提交
6114
		_programs.push( { program: program, code: code, usedTimes: 1 } );
6115

6116
		_this.info.memory.programs = _programs.length;
6117

6118
		return program;
6119

6120
	};
6121

6122
	// Shader parameters cache
6123

6124
	function cacheUniformLocations ( program, identifiers ) {
6125

6126
		var i, l, id;
6127

6128
		for( i = 0, l = identifiers.length; i < l; i ++ ) {
6129

6130 6131
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
6132

6133
		}
M
Mr.doob 已提交
6134

6135
	};
M
Mr.doob 已提交
6136

6137
	function cacheAttributeLocations ( program, identifiers ) {
A
alteredq 已提交
6138

6139
		var i, l, id;
A
alteredq 已提交
6140

6141
		for( i = 0, l = identifiers.length; i < l; i ++ ) {
A
alteredq 已提交
6142

6143 6144
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
A
alteredq 已提交
6145

6146
		}
6147

6148
	};
A
alteredq 已提交
6149

6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166
	function addLineNumbers ( string ) {

		var chunks = string.split( "\n" );

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

			// Chrome reports shader errors on lines
			// starting counting from 1

			chunks[ i ] = ( i + 1 ) + ": " + chunks[ i ];

		}

		return chunks.join( "\n" );

	};

6167
	function getShader ( type, string ) {
A
alteredq 已提交
6168

6169
		var shader;
6170

6171
		if ( type === "fragment" ) {
A
alteredq 已提交
6172

6173
			shader = _gl.createShader( _gl.FRAGMENT_SHADER );
A
alteredq 已提交
6174

6175
		} else if ( type === "vertex" ) {
A
alteredq 已提交
6176

6177
			shader = _gl.createShader( _gl.VERTEX_SHADER );
A
alteredq 已提交
6178

6179
		}
A
alteredq 已提交
6180

6181 6182
		_gl.shaderSource( shader, string );
		_gl.compileShader( shader );
6183

6184
		if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {
6185

6186
			console.error( _gl.getShaderInfoLog( shader ) );
6187
			console.error( addLineNumbers( string ) );
6188
			return null;
6189

A
alteredq 已提交
6190 6191
		}

6192 6193
		return shader;

A
alteredq 已提交
6194
	};
6195

6196 6197
	// Textures

6198 6199 6200 6201 6202 6203 6204

	function isPowerOfTwo ( value ) {

		return ( value & ( value - 1 ) ) === 0;

	};

6205
	function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {
6206

6207
		if ( isImagePowerOfTwo ) {
M
Mr.doob 已提交
6208

6209 6210
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
6211

6212 6213
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
6214

6215
		} else {
M
Mr.doob 已提交
6216

6217 6218
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
6219

6220 6221
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
6222

6223
		}
M
Mr.doob 已提交
6224

6225
		if ( _glExtensionTextureFilterAnisotropic && texture.type !== THREE.FloatType ) {
6226

6227 6228 6229 6230 6231 6232
			if ( texture.anisotropy > 1 || texture.__oldAnisotropy ) {

				_gl.texParameterf( textureType, _glExtensionTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _maxAnisotropy ) );
				texture.__oldAnisotropy = texture.anisotropy;

			}
6233 6234 6235

		}

6236
	};
6237

6238
	this.setTexture = function ( texture, slot ) {
6239

6240
		if ( texture.needsUpdate ) {
A
alteredq 已提交
6241

6242
			if ( ! texture.__webglInit ) {
M
Mr.doob 已提交
6243

6244
				texture.__webglInit = true;
6245
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
6246

M
Mr.doob 已提交
6247 6248
				_this.info.memory.textures ++;

6249
			}
M
Mr.doob 已提交
6250

6251
			_gl.activeTexture( _gl.TEXTURE0 + slot );
6252 6253
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );

6254
			_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
6255 6256
			_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );

6257 6258
			var image = texture.image,
			isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
6259 6260
			glFormat = paramThreeToGL( texture.format ),
			glType = paramThreeToGL( texture.type );
6261

6262 6263
			setTextureParameters( _gl.TEXTURE_2D, texture, isImagePowerOfTwo );

6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275
			if ( texture instanceof THREE.CompressedTexture ) {

				var mipmap, mipmaps = texture.mipmaps;

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

					mipmap = mipmaps[ i ];
					_gl.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );

				}

			} else if ( texture instanceof THREE.DataTexture ) {
6276

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

A
alteredq 已提交
6279
			} else {
M
Mr.doob 已提交
6280

6281
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, texture.image );
M
Mr.doob 已提交
6282 6283 6284

			}

6285
			if ( texture.generateMipmaps && isImagePowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
M
Mr.doob 已提交
6286

A
alteredq 已提交
6287
			texture.needsUpdate = false;
6288

6289
			if ( texture.onUpdate ) texture.onUpdate();
6290

6291
		} else {
6292

6293 6294
			_gl.activeTexture( _gl.TEXTURE0 + slot );
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
6295 6296

		}
M
Mr.doob 已提交
6297

6298
	};
M
Mr.doob 已提交
6299

6300 6301 6302 6303 6304 6305 6306 6307 6308 6309
	function clampToMaxSize ( image, maxSize ) {

		if ( image.width <= maxSize && image.height <= maxSize ) {

			return image;

		}

		// Warning: Scaling through the canvas will only work with images that use
		// premultiplied alpha.
6310

6311 6312 6313 6314 6315 6316 6317
		var maxDimension = Math.max( image.width, image.height );
		var newWidth = Math.floor( image.width * maxSize / maxDimension );
		var newHeight = Math.floor( image.height * maxSize / maxDimension );

		var canvas = document.createElement( 'canvas' );
		canvas.width = newWidth;
		canvas.height = newHeight;
6318

6319
		var ctx = canvas.getContext( "2d" );
6320 6321
		ctx.drawImage( image, 0, 0, image.width, image.height, 0, 0, newWidth, newHeight );

6322 6323 6324 6325
		return canvas;

	}

6326
	function setCubeTexture ( texture, slot ) {
6327

6328
		if ( texture.image.length === 6 ) {
6329 6330 6331

			if ( texture.needsUpdate ) {

A
alteredq 已提交
6332
				if ( ! texture.image.__webglTextureCube ) {
6333 6334

					texture.image.__webglTextureCube = _gl.createTexture();
6335

A
alteredq 已提交
6336
				}
6337

A
alteredq 已提交
6338 6339
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
6340

6341
				_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
M
Mr.doob 已提交
6342

6343
				var cubeImage = [];
6344

A
alteredq 已提交
6345
				for ( var i = 0; i < 6; i ++ ) {
6346

6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358
					if ( _this.autoScaleCubemaps ) {

						cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize );

					} else {

						cubeImage[ i ] = texture.image[ i ];

					}

				}

6359 6360
				var image = cubeImage[ 0 ],
				isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
6361 6362
				glFormat = paramThreeToGL( texture.format ),
				glType = paramThreeToGL( texture.type );
6363

6364 6365
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo );

A
alteredq 已提交
6366
				for ( var i = 0; i < 6; i ++ ) {
6367

6368
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
6369

A
alteredq 已提交
6370
				}
6371

M
Mr.doob 已提交
6372 6373 6374 6375 6376
				if ( texture.generateMipmaps && isImagePowerOfTwo ) {

					_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

				}
6377

A
alteredq 已提交
6378
				texture.needsUpdate = false;
6379

6380
				if ( texture.onUpdate ) texture.onUpdate();
6381

A
alteredq 已提交
6382
			} else {
6383

A
alteredq 已提交
6384 6385
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
6386

A
alteredq 已提交
6387
			}
6388

A
alteredq 已提交
6389
		}
6390

A
alteredq 已提交
6391
	};
6392

6393
	function setCubeTextureDynamic ( texture, slot ) {
6394

A
alteredq 已提交
6395 6396
		_gl.activeTexture( _gl.TEXTURE0 + slot );
		_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
6397 6398 6399

	};

6400 6401 6402
	// Render targets

	function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
6403

6404 6405
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
A
alteredq 已提交
6406

6407
	};
M
Mr.doob 已提交
6408

6409
	function setupRenderBuffer ( renderbuffer, renderTarget  ) {
M
Mikael Emtinger 已提交
6410

6411
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
6412

6413
		if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
M
Mr.doob 已提交
6414

6415 6416
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
6417

6418 6419
		/* For some reason this is not working. Defaulting to RGBA4.
		} else if( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
A
alteredq 已提交
6420

6421 6422 6423 6424
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.STENCIL_INDEX8, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
		*/
		} else if( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
A
alteredq 已提交
6425

6426 6427
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
6428

6429
		} else {
A
alteredq 已提交
6430

6431
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
A
alteredq 已提交
6432

6433
		}
A
alteredq 已提交
6434

6435
	};
A
alteredq 已提交
6436

A
alteredq 已提交
6437
	this.setRenderTarget = function ( renderTarget ) {
A
alteredq 已提交
6438

6439
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
A
alteredq 已提交
6440

6441
		if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
A
alteredq 已提交
6442

M
Mr.doob 已提交
6443 6444
			if ( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
			if ( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
A
alteredq 已提交
6445

6446
			renderTarget.__webglTexture = _gl.createTexture();
A
alteredq 已提交
6447

6448
			// Setup texture, create render and frame buffers
6449

6450 6451
			var isTargetPowerOfTwo = isPowerOfTwo( renderTarget.width ) && isPowerOfTwo( renderTarget.height ),
				glFormat = paramThreeToGL( renderTarget.format ),
6452 6453
				glType = paramThreeToGL( renderTarget.type );

6454
			if ( isCube ) {
M
Mr.doob 已提交
6455

6456 6457
				renderTarget.__webglFramebuffer = [];
				renderTarget.__webglRenderbuffer = [];
M
Mikael Emtinger 已提交
6458

6459
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
6460
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, isTargetPowerOfTwo );
A
alteredq 已提交
6461

6462
				for ( var i = 0; i < 6; i ++ ) {
A
alteredq 已提交
6463

6464 6465
					renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
					renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
A
alteredq 已提交
6466

6467
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
A
alteredq 已提交
6468

6469 6470
					setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
					setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
A
alteredq 已提交
6471

6472
				}
6473

6474 6475
				if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

6476
			} else {
6477

6478 6479
				renderTarget.__webglFramebuffer = _gl.createFramebuffer();
				renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
6480

6481
				_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
6482
				setTextureParameters( _gl.TEXTURE_2D, renderTarget, isTargetPowerOfTwo );
6483

6484
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
6485

6486 6487
				setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
				setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
6488

6489 6490
				if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );

M
Mikael Emtinger 已提交
6491
			}
6492

6493
			// Release everything
M
Mr.doob 已提交
6494

A
alteredq 已提交
6495 6496 6497 6498 6499 6500 6501 6502 6503 6504
			if ( isCube ) {

				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

			} else {

				_gl.bindTexture( _gl.TEXTURE_2D, null );

			}

6505 6506
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
6507

6508 6509
		}

6510
		var framebuffer, width, height, vx, vy;
M
Mr.doob 已提交
6511

6512
		if ( renderTarget ) {
M
Mr.doob 已提交
6513

A
alteredq 已提交
6514 6515
			if ( isCube ) {

6516
				framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
A
alteredq 已提交
6517 6518 6519

			} else {

6520
				framebuffer = renderTarget.__webglFramebuffer;
A
alteredq 已提交
6521 6522 6523

			}

6524 6525
			width = renderTarget.width;
			height = renderTarget.height;
M
Mr.doob 已提交
6526

6527 6528 6529
			vx = 0;
			vy = 0;

6530
		} else {
M
Mr.doob 已提交
6531

6532
			framebuffer = null;
6533

6534 6535
			width = _viewportWidth;
			height = _viewportHeight;
6536

6537 6538
			vx = _viewportX;
			vy = _viewportY;
M
Mr.doob 已提交
6539

6540
		}
M
Mr.doob 已提交
6541

6542
		if ( framebuffer !== _currentFramebuffer ) {
M
Mr.doob 已提交
6543

6544
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
6545
			_gl.viewport( vx, vy, width, height );
M
Mr.doob 已提交
6546

6547
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
6548

6549
		}
6550

A
alteredq 已提交
6551 6552 6553
		_currentWidth = width;
		_currentHeight = height;

6554
	};
M
Mr.doob 已提交
6555

6556
	function updateRenderTargetMipmap ( renderTarget ) {
M
Mr.doob 已提交
6557

A
alteredq 已提交
6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570
		if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {

			_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
			_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
			_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

		} else {

			_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
			_gl.generateMipmap( _gl.TEXTURE_2D );
			_gl.bindTexture( _gl.TEXTURE_2D, null );

		}
M
Mr.doob 已提交
6571 6572

	};
6573

6574
	// Fallback filters for non-power-of-2 textures
6575

6576
	function filterFallback ( f ) {
6577

6578
		if ( f === THREE.NearestFilter || f === THREE.NearestMipMapNearestFilter || f === THREE.NearestMipMapLinearFilter ) {
6579

6580
			return _gl.NEAREST;
6581 6582

		}
6583

6584 6585
		return _gl.LINEAR;

6586
	};
6587

6588 6589
	// Map three.js constants to WebGL constants

6590
	function paramThreeToGL ( p ) {
M
Mr.doob 已提交
6591

6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637
		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;

		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;
M
Mr.doob 已提交
6638

6639 6640 6641 6642 6643 6644 6645 6646 6647
		if ( _glExtensionCompressedTextureS3TC !== undefined ) {

			if ( p === THREE.RGB_S3TC_DXT1_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGB_S3TC_DXT1_EXT;
			if ( p === THREE.RGBA_S3TC_DXT1_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT1_EXT;
			if ( p === THREE.RGBA_S3TC_DXT3_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT3_EXT;
			if ( p === THREE.RGBA_S3TC_DXT5_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT5_EXT;

		}

6648
		return 0;
M
Mr.doob 已提交
6649

6650 6651
	};

6652
	// Allocations
6653

6654
	function allocateBones ( object ) {
6655

6656
		if ( _supportsBoneTextures && object && object.useVertexTexture ) {
6657 6658

			return 1024;
6659

6660
		} else {
6661

6662 6663 6664 6665 6666 6667 6668
			// default for when object is not specified
			// ( for example when prebuilding shader
			//   to be used with multiple objects )
			//
			// 	- leave some extra space for other uniforms
			//  - limit here is ANGLE's 254 max uniform vectors
			//    (up to 54 should be safe)
6669

6670 6671
			var nVertexUniforms = _gl.getParameter( _gl.MAX_VERTEX_UNIFORM_VECTORS );
			var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );
6672

6673
			var maxBones = nVertexMatrices;
6674

6675
			if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
6676

6677
				maxBones = Math.min( object.bones.length, maxBones );
6678

6679
				if ( maxBones < object.bones.length ) {
6680

6681
					console.warn( "WebGLRenderer: too many bones - " + object.bones.length + ", this GPU supports just " + maxBones + " (try OpenGL instead of ANGLE)" );
6682

6683
				}
6684

6685
			}
6686

6687
			return maxBones;
6688

6689 6690 6691
		}

	};
6692

6693
	function allocateLights ( lights ) {
6694

A
alteredq 已提交
6695
		var l, ll, light, dirLights, pointLights, spotLights, hemiLights, maxDirLights, maxPointLights, maxSpotLights, maxHemiLights;
6696

A
alteredq 已提交
6697
		dirLights = pointLights = spotLights = hemiLights = maxDirLights = maxPointLights = maxSpotLights = maxHemiLights = 0;
A
alteredq 已提交
6698 6699

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

6701
			light = lights[ l ];
6702

A
alteredq 已提交
6703 6704
			if ( light.onlyShadow ) continue;

6705 6706
			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
			if ( light instanceof THREE.PointLight ) pointLights ++;
A
alteredq 已提交
6707
			if ( light instanceof THREE.SpotLight ) spotLights ++;
A
alteredq 已提交
6708
			if ( light instanceof THREE.HemisphereLight ) hemiLights ++;
6709

6710
		}
6711

A
alteredq 已提交
6712
		if ( ( pointLights + spotLights + dirLights + hemiLights) <= _maxLights ) {
6713

6714 6715
			maxDirLights = dirLights;
			maxPointLights = pointLights;
A
alteredq 已提交
6716
			maxSpotLights = spotLights;
A
alteredq 已提交
6717
			maxHemiLights = hemiLights;
6718

6719
		} else {
6720

6721 6722
			maxDirLights = Math.ceil( _maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = _maxLights - maxDirLights;
A
alteredq 已提交
6723 6724 6725 6726 6727

			// these are not really correct

			maxSpotLights = maxPointLights;
			maxHemiLights = maxDirLights;
6728 6729 6730

		}

A
alteredq 已提交
6731
		return { 'directional' : maxDirLights, 'point' : maxPointLights, 'spot': maxSpotLights, 'hemi': maxHemiLights };
6732 6733

	};
M
Mr.doob 已提交
6734

6735
	function allocateShadows ( lights ) {
6736

M
Mr.doob 已提交
6737
		var l, ll, light, maxShadows = 0;
6738 6739 6740 6741 6742

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

			light = lights[ l ];

A
alteredq 已提交
6743 6744
			if ( ! light.castShadow ) continue;

6745 6746
			if ( light instanceof THREE.SpotLight ) maxShadows ++;
			if ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) maxShadows ++;
6747 6748 6749 6750 6751 6752 6753

		}

		return maxShadows;

	};

6754
	// Initialization
M
Mr.doob 已提交
6755

6756 6757 6758 6759
	function initGL () {

		try {

6760
			if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { alpha: _alpha, premultipliedAlpha: _premultipliedAlpha, antialias: _antialias, stencil: _stencil, preserveDrawingBuffer: _preserveDrawingBuffer } ) ) ) {
6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771

				throw 'Error creating WebGL context.';

			}

		} catch ( error ) {

			console.error( error );

		}

6772
		_glExtensionTextureFloat = _gl.getExtension( 'OES_texture_float' );
A
alteredq 已提交
6773 6774 6775 6776 6777 6778
		_glExtensionStandardDerivatives = _gl.getExtension( 'OES_standard_derivatives' );

		_glExtensionTextureFilterAnisotropic = _gl.getExtension( 'EXT_texture_filter_anisotropic' ) ||
											   _gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) ||
											   _gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );

6779

6780 6781 6782 6783
		_glExtensionCompressedTextureS3TC = _gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) ||
											_gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) ||
											_gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );

6784
		if ( ! _glExtensionTextureFloat ) {
6785 6786 6787 6788 6789

			console.log( 'THREE.WebGLRenderer: Float textures not supported.' );

		}

A
alteredq 已提交
6790
		if ( ! _glExtensionStandardDerivatives ) {
6791

A
alteredq 已提交
6792
			console.log( 'THREE.WebGLRenderer: Standard derivatives not supported.' );
6793

A
alteredq 已提交
6794
		}
6795

A
alteredq 已提交
6796
		if ( ! _glExtensionTextureFilterAnisotropic ) {
6797

A
alteredq 已提交
6798
			console.log( 'THREE.WebGLRenderer: Anisotropic texture filtering not supported.' );
6799 6800 6801

		}

6802 6803 6804 6805 6806 6807
		if ( ! _glExtensionCompressedTextureS3TC ) {

			console.log( 'THREE.WebGLRenderer: S3TC compressed textures not supported.' );

		}

6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830
	};

	function setDefaultGLState () {

		_gl.clearColor( 0, 0, 0, 1 );
		_gl.clearDepth( 1 );
		_gl.clearStencil( 0 );

		_gl.enable( _gl.DEPTH_TEST );
		_gl.depthFunc( _gl.LEQUAL );

		_gl.frontFace( _gl.CCW );
		_gl.cullFace( _gl.BACK );
		_gl.enable( _gl.CULL_FACE );

		_gl.enable( _gl.BLEND );
		_gl.blendEquation( _gl.FUNC_ADD );
		_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA );

		_gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );

	};

6831 6832
	// default plugins (order is important)

A
alteredq 已提交
6833 6834 6835 6836 6837
	this.shadowMapPlugin = new THREE.ShadowMapPlugin();
	this.addPrePlugin( this.shadowMapPlugin );

	this.addPostPlugin( new THREE.SpritePlugin() );
	this.addPostPlugin( new THREE.LensFlarePlugin() );
6838

6839
};