WebGLRenderer.js 131.1 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

10
	// constructor parameters
M
Mr.doob 已提交
11

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

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

16
	_precision = parameters.precision !== undefined ? parameters.precision : 'highp',
17
	_antialias = parameters.antialias !== undefined ? parameters.antialias : false,
18
	_stencil = parameters.stencil !== undefined ? parameters.stencil : true,
19 20
	_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,

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

24
	_maxLights = parameters.maxLights !== undefined ? parameters.maxLights : 4;
25

26
	// public properties
M
Mr.doob 已提交
27

N
Nicolas Garcia Belmonte 已提交
28
	this.domElement = _canvas;
29 30 31
	this.context = null;

	// clearing
M
Mr.doob 已提交
32

N
Nicolas Garcia Belmonte 已提交
33
	this.autoClear = true;
M
Mr.doob 已提交
34 35 36 37
	this.autoClearColor = true;
	this.autoClearDepth = true;
	this.autoClearStencil = true;

38 39
	// scene graph

40
	this.sortObjects = true;
N
Nicolas Garcia Belmonte 已提交
41

42
	this.autoUpdateObjects = true;
43
	this.autoUpdateScene = true;
44 45 46 47 48 49 50

	// physically based shading

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

51 52 53 54 55 56 57 58 59 60 61 62
	// shadow map

	this.shadowMapBias = 0.0039;
	this.shadowMapDarkness = 0.5;
	this.shadowMapWidth = 512;
	this.shadowMapHeight = 512;

	this.shadowCameraNear = 1;
	this.shadowCameraFar = 5000;
	this.shadowCameraFov = 50;

	this.shadowMapEnabled = false;
63
	this.shadowMapAutoUpdate = true;
64
	this.shadowMapSoft = true;
65

66
	// morphs
67

68
	this.maxMorphTargets = 8;
69

70 71
	// custom render plugins

A
alteredq 已提交
72 73
	this.renderPluginsPre = [];
	this.renderPluginsPost = [];
74

75
	// info
76

77
	this.info = {
78

79
		memory: {
80

81 82 83
			programs: 0,
			geometries: 0,
			textures: 0
84

85
		},
86

87
		render: {
88

89 90 91
			calls: 0,
			vertices: 0,
			faces: 0
92 93 94

		}

95
	};
M
Mr.doob 已提交
96

97
	// internal properties
98

99
	var _this = this,
100

101
	_gl,
102

103
	_programs = [],
104

105
	// internal state cache
106

107 108 109 110 111
	_currentProgram = null,
	_currentFramebuffer = null,
	_currentMaterialId = -1,
	_currentGeometryGroupHash = null,
	_geometryGroupCounter = 0,
112

113
	// GL state cache
114

115 116 117 118 119 120 121 122 123
	_oldDoubleSided = null,
	_oldFlipSided = null,
	_oldBlending = null,
	_oldDepthTest = null,
	_oldDepthWrite = null,
	_oldPolygonOffset = null,
	_oldPolygonOffsetFactor = null,
	_oldPolygonOffsetUnits = null,
	_oldLineWidth = null,
124

125 126 127 128
	_viewportX = 0,
	_viewportY = 0,
	_viewportWidth = 0,
	_viewportHeight = 0,
129

A
alteredq 已提交
130
	// frustum
M
Mr.doob 已提交
131

A
alteredq 已提交
132
	_frustum = new THREE.Frustum(),
133

134
	 // camera matrices cache
M
Mikael Emtinger 已提交
135

136
	_projScreenMatrix = new THREE.Matrix4(),
M
Mr.doob 已提交
137

138
	_vector3 = new THREE.Vector4(),
M
Mikael Emtinger 已提交
139

140
	// light arrays cache
M
Mikael Emtinger 已提交
141

142
	_lights = {
M
Mr.doob 已提交
143

144 145 146
		ambient: [ 0, 0, 0 ],
		directional: { length: 0, colors: new Array(), positions: new Array() },
		point: { length: 0, colors: new Array(), positions: new Array(), distances: new Array() }
M
Mr.doob 已提交
147

148
	};
M
Mr.doob 已提交
149

150
	// initialize
M
Mikael Emtinger 已提交
151

152
	_gl = initGL();
M
Mikael Emtinger 已提交
153

154
	setDefaultGLState();
M
Mikael Emtinger 已提交
155

156
	this.context = _gl;
M
Mikael Emtinger 已提交
157

158
	var _supportsVertexTextures = ( maxVertexTextures() > 0 );
M
Mr.doob 已提交
159

160
	// API
M
Mr.doob 已提交
161

162
	this.getContext = function () {
M
Mr.doob 已提交
163

164
		return _gl;
M
Mr.doob 已提交
165

166
	};
M
Mr.doob 已提交
167

168
	this.supportsVertexTextures = function () {
M
Mikael Emtinger 已提交
169

170
		return _supportsVertexTextures;
M
Mikael Emtinger 已提交
171

172
	};
M
Mikael Emtinger 已提交
173

N
Nicolas Garcia Belmonte 已提交
174 175 176 177
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
178

179 180 181
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
182

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

185 186
		_viewportX = x;
		_viewportY = y;
187

188 189
		_viewportWidth = width;
		_viewportHeight = height;
190

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

N
Nicolas Garcia Belmonte 已提交
193
	};
194

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

197
		_gl.scissor( x, y, width, height );
198

199
	};
200

201
	this.enableScissorTest = function ( enable ) {
202

M
Mr.doob 已提交
203
		enable ? _gl.enable( _gl.SCISSOR_TEST ) : _gl.disable( _gl.SCISSOR_TEST );
204 205

	};
206

207 208
	// Clearing

209
	this.setClearColorHex = function ( hex, alpha ) {
210

211 212 213 214
		_clearColor.setHex( hex );
		_clearAlpha = alpha;

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

216
	};
A
alteredq 已提交
217

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

220 221 222 223
		_clearColor.copy( color );
		_clearAlpha = alpha;

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

	};
226

M
Mr.doob 已提交
227 228 229 230 231 232 233
	this.getClearColor = function () {

		return _clearColor;

	};

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

M
Mr.doob 已提交
235 236 237 238 239 240 241 242
		return _clearAlpha;

	};

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

		var bits = 0;

243 244 245
		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 已提交
246 247

		_gl.clear( bits );
N
Nicolas Garcia Belmonte 已提交
248 249 250

	};

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

A
alteredq 已提交
253
		this.setRenderTarget( renderTarget );
254
		this.clear( color, depth, stencil );
M
Mr.doob 已提交
255 256 257

	};

258 259
	// Plugins

A
alteredq 已提交
260
	this.addPostPlugin = function ( plugin ) {
261 262

		plugin.init( this );
A
alteredq 已提交
263
		this.renderPluginsPost.push( plugin );
264 265 266

	};

A
alteredq 已提交
267 268 269 270 271 272
	this.addPrePlugin = function ( plugin ) {

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

	};
273

274 275
	// Deallocation

276 277 278 279 280 281 282 283 284 285 286 287 288 289
	this.deallocateObject = function ( object ) {

		if ( ! object.__webglInit ) return;

		object.__webglInit = false;

		delete object._modelViewMatrix;

		delete object._normalMatrixArray;
		delete object._modelViewMatrixArray;
		delete object._objectMatrixArray;

		if ( object instanceof THREE.Mesh ) {

290
			for ( var g in object.geometry.geometryGroups ) {
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318

				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 已提交
319 320
		_this.info.memory.textures --;

321 322
	};

323
	// Rendering
324

325
	this.updateShadowMap = function ( scene, camera ) {
326

A
alteredq 已提交
327 328 329 330 331 332 333 334
		_currentProgram = null;
		_oldBlending = -1;
		_oldDepthTest = -1;
		_oldDepthWrite = -1;
		_currentGeometryGroupHash = -1;
		_currentMaterialId = -1;

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

336
	};
M
Mr.doob 已提交
337

338
	// Internal functions
339

340
	// Buffer allocation
341

342
	function createParticleBuffers ( geometry ) {
343

344 345
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
346

347
		_this.info.geometries ++;
348

349
	};
350

351
	function createLineBuffers ( geometry ) {
352

353 354
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
355

356
		_this.info.memory.geometries ++;
357

358
	};
359

360
	function createRibbonBuffers ( geometry ) {
361

362 363
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
364

365
		_this.info.memory.geometries ++;
M
Mr.doob 已提交
366

367
	};
368

369
	function createMeshBuffers ( geometryGroup ) {
370

371 372 373 374 375 376
		geometryGroup.__webglVertexBuffer = _gl.createBuffer();
		geometryGroup.__webglNormalBuffer = _gl.createBuffer();
		geometryGroup.__webglTangentBuffer = _gl.createBuffer();
		geometryGroup.__webglColorBuffer = _gl.createBuffer();
		geometryGroup.__webglUVBuffer = _gl.createBuffer();
		geometryGroup.__webglUV2Buffer = _gl.createBuffer();
377

378 379 380 381
		geometryGroup.__webglSkinVertexABuffer = _gl.createBuffer();
		geometryGroup.__webglSkinVertexBBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinIndicesBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinWeightsBuffer = _gl.createBuffer();
382

383 384
		geometryGroup.__webglFaceBuffer = _gl.createBuffer();
		geometryGroup.__webglLineBuffer = _gl.createBuffer();
385

386
		if ( geometryGroup.numMorphTargets ) {
387

388
			var m, ml;
389

390
			geometryGroup.__webglMorphTargetsBuffers = [];
391

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

394
				geometryGroup.__webglMorphTargetsBuffers.push( _gl.createBuffer() );
395

396
			}
397

398
		}
399

400
		_this.info.memory.geometries ++;
401

402
	};
403

404
	// Buffer deallocation
405

406
	function deleteParticleBuffers ( geometry ) {
407

408 409
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
410

411
		_this.info.memory.geometries --;
412

413
	};
414

415
	function deleteLineBuffers ( geometry ) {
416

417 418
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
419

M
Mr.doob 已提交
420 421
		_this.info.memory.geometries --;

422 423
	};

424
	function deleteRibbonBuffers ( geometry ) {
425 426 427 428

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

M
Mr.doob 已提交
429 430
		_this.info.memory.geometries --;

431 432
	};

433
	function deleteMeshBuffers ( geometryGroup ) {
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451

		_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.__webglSkinVertexABuffer );
		_gl.deleteBuffer( geometryGroup.__webglSkinVertexBBuffer );
		_gl.deleteBuffer( geometryGroup.__webglSkinIndicesBuffer );
		_gl.deleteBuffer( geometryGroup.__webglSkinWeightsBuffer );

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

		if ( geometryGroup.numMorphTargets ) {

452
			for ( var m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
453 454 455 456 457 458 459

				_gl.deleteBuffer( geometryGroup.__webglMorphTargetsBuffers[ m ] );

			}

		}

460 461 462 463 464 465 466 467 468 469 470

		if ( geometryGroup.__webglCustomAttributesList ) {

			for ( var id in geometryGroup.__webglCustomAttributesList ) {

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

			}

		}

M
Mr.doob 已提交
471 472
		_this.info.memory.geometries --;

473 474
	};

475
	// Buffer initialization
476

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

479 480
		var nvertices = geometry.vertices.length;

481
		var material = object.material;
482

483
		if ( material.attributes ) {
484

485
			if ( geometry.__webglCustomAttributesList === undefined ) {
486

487
				geometry.__webglCustomAttributesList = [];
488

489
			}
490

491
			for ( var a in material.attributes ) {
492

493
				var attribute = material.attributes[ a ];
494

495
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
496

497
					attribute.__webglInitialized = true;
498

A
alteredq 已提交
499
					var size = 1;		// "f" and "i"
500

501 502 503 504
					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;
505

506
					attribute.size = size;
A
alteredq 已提交
507

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

510 511
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
512

513
					attribute.needsUpdate = true;
514

515
				}
516

517
				geometry.__webglCustomAttributesList.push( attribute );
518

519
			}
520

521
		}
522

523
	};
524

525
	function initParticleBuffers ( geometry, object ) {
A
alteredq 已提交
526 527 528 529 530 531

		var nvertices = geometry.vertices.length;

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

532 533 534
		geometry.__sortArray = [];

		geometry.__webglParticleCount = nvertices;
A
alteredq 已提交
535 536 537 538 539

		initCustomAttributes ( geometry, object );

	};

540
	function initLineBuffers ( geometry, object ) {
A
alteredq 已提交
541 542 543 544 545 546

		var nvertices = geometry.vertices.length;

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

547
		geometry.__webglLineCount = nvertices;
A
alteredq 已提交
548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563

		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 已提交
564
	function initMeshBuffers ( geometryGroup, object ) {
M
Mr.doob 已提交
565

566 567 568
		var geometry = object.geometry,
			faces3 = geometryGroup.faces3,
			faces4 = geometryGroup.faces4,
M
Mr.doob 已提交
569

570 571 572
			nvertices = faces3.length * 3 + faces4.length * 4,
			ntris     = faces3.length * 1 + faces4.length * 2,
			nlines    = faces3.length * 3 + faces4.length * 4,
573

574
			material = getBufferMaterial( object, geometryGroup ),
575

576 577 578
			uvType = bufferGuessUVType( material ),
			normalType = bufferGuessNormalType( material ),
			vertexColorType = bufferGuessVertexColorType( material );
A
alteredq 已提交
579

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

582
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
583

584
		if ( normalType ) {
M
Mr.doob 已提交
585

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

588
		}
589

590
		if ( geometry.hasTangents ) {
591

592
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
593

594
		}
595

596
		if ( vertexColorType ) {
597

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

600
		}
M
Mr.doob 已提交
601

602
		if ( uvType ) {
603

604
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
605

606 607 608 609 610
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

612 613 614 615 616 617 618 619 620 621 622 623 624 625 626
				geometryGroup.__uv2Array = new Float32Array( nvertices * 2 );

			}

		}

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

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

		}

627
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
628
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
629

630 631
		if ( geometryGroup.numMorphTargets ) {

M
Mr.doob 已提交
632
			geometryGroup.__morphTargetsArrays = [];
633

634
			for ( var m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
635

636 637
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );

638 639 640
			}

		}
641

642
		geometryGroup.__webglFaceCount = ntris * 3;
643
		geometryGroup.__webglLineCount = nlines * 2;
644

M
Mr.doob 已提交
645

646
		// custom attributes
M
Mr.doob 已提交
647

648
		if ( material.attributes ) {
649

650
			if ( geometryGroup.__webglCustomAttributesList === undefined ) {
651

652
				geometryGroup.__webglCustomAttributesList = [];
653

654
			}
655

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

658 659
				// Do a shallow copy of the attribute object so different geometryGroup chunks use different
				// attribute buffers which are correctly indexed in the setMeshBuffers function
660

661
				var originalAttribute = material.attributes[ a ];
662

663
				var attribute = {};
664

665
				for ( var property in originalAttribute ) {
M
Mr.doob 已提交
666

667
					attribute[ property ] = originalAttribute[ property ];
668

669
				}
670

671
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
672

673
					attribute.__webglInitialized = true;
674

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

677 678 679 680
					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;
681

682
					attribute.size = size;
A
alteredq 已提交
683

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

686 687
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
688

689 690
					originalAttribute.needsUpdate = true;
					attribute.__original = originalAttribute;
691 692 693

				}

694 695
				geometryGroup.__webglCustomAttributesList.push( attribute );

696
			}
M
Mr.doob 已提交
697

698
		}
699

700 701
		geometryGroup.__inittedArrays = true;

702
	};
M
Mr.doob 已提交
703

704
	function getBufferMaterial( object, geometryGroup ) {
705

706
		if ( object.material && ! ( object.material instanceof THREE.MeshFaceMaterial ) ) {
707

708
			return object.material;
709

710
		} else if ( geometryGroup.materialIndex >= 0 ) {
711

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

714
		}
715

716
	};
M
Mr.doob 已提交
717

718
	function materialNeedsSmoothNormals ( material ) {
719

720
		return material && material.shading !== undefined && material.shading === THREE.SmoothShading;
721

722
	};
M
Mr.doob 已提交
723

724
	function bufferGuessNormalType ( material ) {
725

726
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
727

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

730
			return false;
731

732
		}
733

734
		if ( materialNeedsSmoothNormals( material ) ) {
735

736
			return THREE.SmoothShading;
M
Mr.doob 已提交
737

738
		} else {
739

740
			return THREE.FlatShading;
741

742
		}
743

744
	};
745

746
	function bufferGuessVertexColorType ( material ) {
747

748
		if ( material.vertexColors ) {
749

750
			return material.vertexColors;
751

752
		}
M
Mr.doob 已提交
753

754
		return false;
M
Mr.doob 已提交
755

756
	};
M
Mr.doob 已提交
757

758
	function bufferGuessUVType ( material ) {
759

760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 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 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 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 1141 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 1176 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
		// material must use some texture to require uvs

		if ( material.map || material.lightMap || material instanceof THREE.ShaderMaterial ) {

			return true;

		}

		return false;

	};

	// 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,

		dirtyVertices = geometry.__dirtyVertices,
		dirtyElements = geometry.__dirtyElements,
		dirtyColors = geometry.__dirtyColors,

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

		if ( object.sortParticles ) {

			_projScreenMatrix.multiplySelf( object.matrixWorld );

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

				vertex = vertices[ v ].position;

				_vector3.copy( vertex );
				_projScreenMatrix.multiplyVector3( _vector3 );

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

			}

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

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

				vertex = vertices[ sortArray[v][1] ].position;

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

					vertex = vertices[ v ].position;

					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 &&
					     ( customAttribute.boundTo === undefined ||
						   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,

		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors,

		customAttributes = geometry.__webglCustomAttributesList,

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

		if ( dirtyVertices ) {

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

				vertex = vertices[ v ].position;

				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,

		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors;

		if ( dirtyVertices ) {

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

				vertex = vertices[ v ].position;

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

		}

	};

1304
	function setMeshBuffers( geometryGroup, object, hint, dispose, material ) {
1305 1306 1307 1308 1309 1310 1311 1312

		if ( ! geometryGroup.__inittedArrays ) {

			// console.log( object );
			return;

		}

1313 1314 1315 1316 1317 1318
		var normalType = bufferGuessNormalType( material ),
		vertexColorType = bufferGuessVertexColorType( material ),
		uvType = bufferGuessUVType( material ),

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

1319 1320 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
		var f, fl, fi, face,
		vertexNormals, faceNormal, normal,
		vertexColors, faceColor,
		vertexTangents,
		uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4,
		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,

		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,

		skinVertexAArray = geometryGroup.__skinVertexAArray,
		skinVertexBArray = geometryGroup.__skinVertexBArray,
		skinIndexArray = geometryGroup.__skinIndexArray,
		skinWeightArray = geometryGroup.__skinWeightArray,

		morphTargetsArrays = geometryGroup.__morphTargetsArrays,

		customAttributes = geometryGroup.__webglCustomAttributesList,
		customAttribute,

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

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

		dirtyVertices = geometry.__dirtyVertices,
		dirtyElements = geometry.__dirtyElements,
		dirtyUvs = geometry.__dirtyUvs,
		dirtyNormals = geometry.__dirtyNormals,
		dirtyTangents = geometry.__dirtyTangents,
		dirtyColors = geometry.__dirtyColors,
		dirtyMorphTargets = geometry.__dirtyMorphTargets,

		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_skinVerticesA = geometry.skinVerticesA,
		obj_skinVerticesB = geometry.skinVerticesB,
		obj_skinIndices = geometry.skinIndices,
		obj_skinWeights = geometry.skinWeights,

		morphTargets = geometry.morphTargets;

		if ( dirtyVertices ) {

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

				face = obj_faces[ chunk_faces3[ f ] ];

				v1 = vertices[ face.a ].position;
				v2 = vertices[ face.b ].position;
				v3 = vertices[ face.c ].position;

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

1420
				offset += 9;
M
Mr.doob 已提交
1421

1422
			}
1423

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

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

A
alteredq 已提交
1428 1429 1430 1431
				v1 = vertices[ face.a ].position;
				v2 = vertices[ face.b ].position;
				v3 = vertices[ face.c ].position;
				v4 = vertices[ face.d ].position;
1432

A
alteredq 已提交
1433 1434 1435
				vertexArray[ offset ]     = v1.x;
				vertexArray[ offset + 1 ] = v1.y;
				vertexArray[ offset + 2 ] = v1.z;
1436

A
alteredq 已提交
1437 1438 1439
				vertexArray[ offset + 3 ] = v2.x;
				vertexArray[ offset + 4 ] = v2.y;
				vertexArray[ offset + 5 ] = v2.z;
1440

A
alteredq 已提交
1441 1442 1443
				vertexArray[ offset + 6 ] = v3.x;
				vertexArray[ offset + 7 ] = v3.y;
				vertexArray[ offset + 8 ] = v3.z;
1444

A
alteredq 已提交
1445 1446 1447
				vertexArray[ offset + 9 ]  = v4.x;
				vertexArray[ offset + 10 ] = v4.y;
				vertexArray[ offset + 11 ] = v4.z;
1448

A
alteredq 已提交
1449
				offset += 12;
1450

A
alteredq 已提交
1451
			}
1452

A
alteredq 已提交
1453 1454
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1455

A
alteredq 已提交
1456
		}
M
Mr.doob 已提交
1457

A
alteredq 已提交
1458
		if ( dirtyMorphTargets ) {
M
Mr.doob 已提交
1459

1460
			for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {
1461

1462
				offset_morphTarget = 0;
1463

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

					face = obj_faces[ chunk_faces3[ f ]	];
M
Mr.doob 已提交
1467

A
alteredq 已提交
1468 1469 1470
					v1 = morphTargets[ vk ].vertices[ face.a ].position;
					v2 = morphTargets[ vk ].vertices[ face.b ].position;
					v3 = morphTargets[ vk ].vertices[ face.c ].position;
M
Mr.doob 已提交
1471

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

A
alteredq 已提交
1474 1475 1476
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
M
Mr.doob 已提交
1477

A
alteredq 已提交
1478 1479 1480
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
M
Mr.doob 已提交
1481

A
alteredq 已提交
1482 1483 1484
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
M
Mr.doob 已提交
1485

1486
					offset_morphTarget += 9;
1487

1488
				}
1489

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

1492
					face = obj_faces[ chunk_faces4[ f ] ];
1493

1494 1495 1496
					v1 = morphTargets[ vk ].vertices[ face.a ].position;
					v2 = morphTargets[ vk ].vertices[ face.b ].position;
					v3 = morphTargets[ vk ].vertices[ face.c ].position;
A
alteredq 已提交
1497
					v4 = morphTargets[ vk ].vertices[ face.d ].position;
1498

1499
					vka = morphTargetsArrays[ vk ];
1500

1501 1502 1503
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
1504

1505 1506 1507
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
1508

1509 1510 1511
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
1512

A
alteredq 已提交
1513 1514 1515 1516
					vka[ offset_morphTarget + 9 ]  = v4.x;
					vka[ offset_morphTarget + 10 ] = v4.y;
					vka[ offset_morphTarget + 11 ] = v4.z;

1517
					offset_morphTarget += 12;
A
alteredq 已提交
1518

1519
				}
A
alteredq 已提交
1520 1521 1522

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

1524
			}
1525

A
alteredq 已提交
1526 1527 1528 1529 1530 1531 1532
		}

		if ( obj_skinWeights.length ) {

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

				face = obj_faces[ chunk_faces3[ f ]	];
1533

1534
				// weights
A
alteredq 已提交
1535

1536 1537 1538
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
A
alteredq 已提交
1539

1540 1541 1542 1543
				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 已提交
1544

1545 1546 1547 1548
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1549

1550 1551 1552 1553
				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 已提交
1554

1555
				// indices
A
alteredq 已提交
1556

1557 1558 1559
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
A
alteredq 已提交
1560

1561 1562 1563 1564
				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 已提交
1565

1566 1567 1568 1569
				skinIndexArray[ offset_skin + 4 ] = si2.x;
				skinIndexArray[ offset_skin + 5 ] = si2.y;
				skinIndexArray[ offset_skin + 6 ] = si2.z;
				skinIndexArray[ offset_skin + 7 ] = si2.w;
1570

1571 1572 1573 1574
				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 已提交
1575

1576
				// vertices A
A
alteredq 已提交
1577

1578 1579 1580
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
A
alteredq 已提交
1581

1582 1583 1584 1585
				skinVertexAArray[ offset_skin ]     = sa1.x;
				skinVertexAArray[ offset_skin + 1 ] = sa1.y;
				skinVertexAArray[ offset_skin + 2 ] = sa1.z;
				skinVertexAArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
A
alteredq 已提交
1586

1587 1588 1589 1590
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1591

1592 1593 1594 1595
				skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
				skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
				skinVertexAArray[ offset_skin + 10 ] = sa3.z;
				skinVertexAArray[ offset_skin + 11 ] = 1;
A
alteredq 已提交
1596

1597
				// vertices B
A
alteredq 已提交
1598

1599 1600 1601
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
A
alteredq 已提交
1602

1603 1604 1605 1606
				skinVertexBArray[ offset_skin ]     = sb1.x;
				skinVertexBArray[ offset_skin + 1 ] = sb1.y;
				skinVertexBArray[ offset_skin + 2 ] = sb1.z;
				skinVertexBArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
A
alteredq 已提交
1607

1608 1609 1610 1611
				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
				skinVertexBArray[ offset_skin + 7 ] = 1;
1612

1613 1614 1615 1616
				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
				skinVertexBArray[ offset_skin + 11 ] = 1;
1617

1618
				offset_skin += 12;
1619

1620
			}
1621

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

A
alteredq 已提交
1624
				face = obj_faces[ chunk_faces4[ f ] ];
1625

A
alteredq 已提交
1626
				// weights
1627

A
alteredq 已提交
1628 1629 1630 1631
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
				sw4 = obj_skinWeights[ face.d ];
1632

A
alteredq 已提交
1633 1634 1635 1636
				skinWeightArray[ offset_skin ]     = sw1.x;
				skinWeightArray[ offset_skin + 1 ] = sw1.y;
				skinWeightArray[ offset_skin + 2 ] = sw1.z;
				skinWeightArray[ offset_skin + 3 ] = sw1.w;
1637

A
alteredq 已提交
1638 1639 1640 1641
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1642

A
alteredq 已提交
1643 1644 1645 1646
				skinWeightArray[ offset_skin + 8 ]  = sw3.x;
				skinWeightArray[ offset_skin + 9 ]  = sw3.y;
				skinWeightArray[ offset_skin + 10 ] = sw3.z;
				skinWeightArray[ offset_skin + 11 ] = sw3.w;
1647

A
alteredq 已提交
1648 1649 1650 1651
				skinWeightArray[ offset_skin + 12 ] = sw4.x;
				skinWeightArray[ offset_skin + 13 ] = sw4.y;
				skinWeightArray[ offset_skin + 14 ] = sw4.z;
				skinWeightArray[ offset_skin + 15 ] = sw4.w;
1652

A
alteredq 已提交
1653
				// indices
1654

A
alteredq 已提交
1655 1656 1657 1658
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
				si4 = obj_skinIndices[ face.d ];
1659

A
alteredq 已提交
1660 1661 1662 1663
				skinIndexArray[ offset_skin ]     = si1.x;
				skinIndexArray[ offset_skin + 1 ] = si1.y;
				skinIndexArray[ offset_skin + 2 ] = si1.z;
				skinIndexArray[ offset_skin + 3 ] = si1.w;
1664

A
alteredq 已提交
1665 1666 1667 1668
				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 已提交
1669

A
alteredq 已提交
1670 1671 1672 1673
				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 已提交
1674

A
alteredq 已提交
1675 1676 1677 1678
				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 已提交
1679

A
alteredq 已提交
1680
				// vertices A
M
Mr.doob 已提交
1681

A
alteredq 已提交
1682 1683 1684 1685
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
				sa4 = obj_skinVerticesA[ face.d ];
1686

A
alteredq 已提交
1687 1688 1689 1690
				skinVertexAArray[ offset_skin ]     = sa1.x;
				skinVertexAArray[ offset_skin + 1 ] = sa1.y;
				skinVertexAArray[ offset_skin + 2 ] = sa1.z;
				skinVertexAArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
M
Mr.doob 已提交
1691

A
alteredq 已提交
1692 1693 1694 1695
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1696

A
alteredq 已提交
1697 1698 1699 1700
				skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
				skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
				skinVertexAArray[ offset_skin + 10 ] = sa3.z;
				skinVertexAArray[ offset_skin + 11 ] = 1;
1701

A
alteredq 已提交
1702 1703 1704 1705
				skinVertexAArray[ offset_skin + 12 ] = sa4.x;
				skinVertexAArray[ offset_skin + 13 ] = sa4.y;
				skinVertexAArray[ offset_skin + 14 ] = sa4.z;
				skinVertexAArray[ offset_skin + 15 ] = 1;
M
Mr.doob 已提交
1706

A
alteredq 已提交
1707
				// vertices B
M
Mr.doob 已提交
1708

A
alteredq 已提交
1709 1710 1711 1712
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
				sb4 = obj_skinVerticesB[ face.d ];
M
Mr.doob 已提交
1713

A
alteredq 已提交
1714 1715 1716 1717
				skinVertexBArray[ offset_skin ]     = sb1.x;
				skinVertexBArray[ offset_skin + 1 ] = sb1.y;
				skinVertexBArray[ offset_skin + 2 ] = sb1.z;
				skinVertexBArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
M
Mr.doob 已提交
1718

A
alteredq 已提交
1719 1720 1721 1722
				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
				skinVertexBArray[ offset_skin + 7 ] = 1;
1723

A
alteredq 已提交
1724 1725 1726 1727
				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
				skinVertexBArray[ offset_skin + 11 ] = 1;
1728

A
alteredq 已提交
1729 1730 1731 1732
				skinVertexBArray[ offset_skin + 12 ] = sb4.x;
				skinVertexBArray[ offset_skin + 13 ] = sb4.y;
				skinVertexBArray[ offset_skin + 14 ] = sb4.z;
				skinVertexBArray[ offset_skin + 15 ] = 1;
1733

A
alteredq 已提交
1734
				offset_skin += 16;
M
Mr.doob 已提交
1735

A
alteredq 已提交
1736
			}
M
Mr.doob 已提交
1737

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

A
alteredq 已提交
1740 1741
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );
M
Mr.doob 已提交
1742

A
alteredq 已提交
1743 1744 1745 1746 1747 1748 1749 1750
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );

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

1752
			}
1753

A
alteredq 已提交
1754
		}
M
Mr.doob 已提交
1755

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

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

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

A
alteredq 已提交
1762 1763
				vertexColors = face.vertexColors;
				faceColor = face.color;
1764

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

A
alteredq 已提交
1767 1768 1769
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
1770

A
alteredq 已提交
1771
				} else {
1772

A
alteredq 已提交
1773 1774 1775
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
1776

A
alteredq 已提交
1777
				}
1778

A
alteredq 已提交
1779 1780 1781
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
1782

A
alteredq 已提交
1783 1784 1785
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
1786

A
alteredq 已提交
1787 1788 1789
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
1790

A
alteredq 已提交
1791
				offset_color += 9;
M
Mr.doob 已提交
1792

A
alteredq 已提交
1793
			}
M
Mr.doob 已提交
1794

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

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

A
alteredq 已提交
1799 1800
				vertexColors = face.vertexColors;
				faceColor = face.color;
M
Mr.doob 已提交
1801

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

A
alteredq 已提交
1804 1805 1806 1807
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
					c4 = vertexColors[ 3 ];
1808

A
alteredq 已提交
1809
				} else {
M
Mr.doob 已提交
1810

A
alteredq 已提交
1811 1812 1813 1814
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
					c4 = faceColor;
M
Mr.doob 已提交
1815

A
alteredq 已提交
1816
				}
1817

A
alteredq 已提交
1818 1819 1820
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
1821

A
alteredq 已提交
1822 1823 1824
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
M
Mr.doob 已提交
1825

A
alteredq 已提交
1826 1827 1828
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
M
Mr.doob 已提交
1829

A
alteredq 已提交
1830 1831 1832
				colorArray[ offset_color + 9 ]  = c4.r;
				colorArray[ offset_color + 10 ] = c4.g;
				colorArray[ offset_color + 11 ] = c4.b;
M
Mr.doob 已提交
1833

A
alteredq 已提交
1834
				offset_color += 12;
1835

1836
			}
1837

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

A
alteredq 已提交
1840 1841
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
M
Mr.doob 已提交
1842

1843
			}
1844

A
alteredq 已提交
1845
		}
M
Mr.doob 已提交
1846

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

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

A
alteredq 已提交
1851
				face = obj_faces[ chunk_faces3[ f ]	];
1852

A
alteredq 已提交
1853
				vertexTangents = face.vertexTangents;
M
Mr.doob 已提交
1854

A
alteredq 已提交
1855 1856 1857
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
1858

A
alteredq 已提交
1859 1860 1861 1862
				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 已提交
1863

A
alteredq 已提交
1864 1865 1866 1867
				tangentArray[ offset_tangent + 4 ] = t2.x;
				tangentArray[ offset_tangent + 5 ] = t2.y;
				tangentArray[ offset_tangent + 6 ] = t2.z;
				tangentArray[ offset_tangent + 7 ] = t2.w;
1868

A
alteredq 已提交
1869 1870 1871 1872
				tangentArray[ offset_tangent + 8 ]  = t3.x;
				tangentArray[ offset_tangent + 9 ]  = t3.y;
				tangentArray[ offset_tangent + 10 ] = t3.z;
				tangentArray[ offset_tangent + 11 ] = t3.w;
1873

A
alteredq 已提交
1874
				offset_tangent += 12;
1875

1876
			}
1877

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

A
alteredq 已提交
1880
				face = obj_faces[ chunk_faces4[ f ] ];
1881

A
alteredq 已提交
1882
				vertexTangents = face.vertexTangents;
1883

A
alteredq 已提交
1884 1885 1886 1887
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
				t4 = vertexTangents[ 3 ];
1888

A
alteredq 已提交
1889 1890 1891 1892
				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 已提交
1893

A
alteredq 已提交
1894 1895 1896 1897
				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 已提交
1898

A
alteredq 已提交
1899 1900 1901 1902
				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 已提交
1903

A
alteredq 已提交
1904 1905 1906 1907
				tangentArray[ offset_tangent + 12 ] = t4.x;
				tangentArray[ offset_tangent + 13 ] = t4.y;
				tangentArray[ offset_tangent + 14 ] = t4.z;
				tangentArray[ offset_tangent + 15 ] = t4.w;
1908

A
alteredq 已提交
1909
				offset_tangent += 16;
1910

A
alteredq 已提交
1911
			}
1912

A
alteredq 已提交
1913 1914
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
1915

A
alteredq 已提交
1916
		}
1917

A
alteredq 已提交
1918
		if ( dirtyNormals && normalType ) {
1919

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

A
alteredq 已提交
1922
				face = obj_faces[ chunk_faces3[ f ]	];
1923

A
alteredq 已提交
1924 1925
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
1926

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

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

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

A
alteredq 已提交
1933 1934 1935
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
1936

A
alteredq 已提交
1937
						offset_normal += 3;
1938

A
alteredq 已提交
1939
					}
1940

A
alteredq 已提交
1941
				} else {
M
Mr.doob 已提交
1942

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

A
alteredq 已提交
1945 1946 1947
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
1948

A
alteredq 已提交
1949
						offset_normal += 3;
M
Mr.doob 已提交
1950

A
alteredq 已提交
1951
					}
1952

A
alteredq 已提交
1953
				}
1954

A
alteredq 已提交
1955
			}
1956

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

A
alteredq 已提交
1959
				face = obj_faces[ chunk_faces4[ f ] ];
1960

A
alteredq 已提交
1961 1962
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
1963

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

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

A
alteredq 已提交
1968
						vn = vertexNormals[ i ];
1969

A
alteredq 已提交
1970 1971 1972
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
1973

A
alteredq 已提交
1974
						offset_normal += 3;
1975

A
alteredq 已提交
1976
					}
M
Mr.doob 已提交
1977

A
alteredq 已提交
1978
				} else {
1979

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

A
alteredq 已提交
1982 1983 1984
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1985

A
alteredq 已提交
1986
						offset_normal += 3;
M
Mr.doob 已提交
1987

A
alteredq 已提交
1988
					}
1989

A
alteredq 已提交
1990
				}
1991

A
alteredq 已提交
1992
			}
M
Mr.doob 已提交
1993

A
alteredq 已提交
1994 1995
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
1996

A
alteredq 已提交
1997
		}
M
Mr.doob 已提交
1998

A
alteredq 已提交
1999
		if ( dirtyUvs && obj_uvs && uvType ) {
2000

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

A
alteredq 已提交
2003
				fi = chunk_faces3[ f ];
2004

A
alteredq 已提交
2005 2006
				face = obj_faces[ fi ];
				uv = obj_uvs[ fi ];
2007

A
alteredq 已提交
2008
				if ( uv === undefined ) continue;
2009

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

A
alteredq 已提交
2012
					uvi = uv[ i ];
2013

A
alteredq 已提交
2014 2015
					uvArray[ offset_uv ]     = uvi.u;
					uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
2016

A
alteredq 已提交
2017
					offset_uv += 2;
M
Mr.doob 已提交
2018

A
alteredq 已提交
2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039
				}

			}

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

2041 2042
				}

2043
			}
2044

A
alteredq 已提交
2045
			if ( offset_uv > 0 ) {
2046

A
alteredq 已提交
2047 2048
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
2049

A
alteredq 已提交
2050
			}
2051

A
alteredq 已提交
2052
		}
2053

A
alteredq 已提交
2054
		if ( dirtyUvs && obj_uvs2 && uvType ) {
2055

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

A
alteredq 已提交
2058
				fi = chunk_faces3[ f ];
2059

A
alteredq 已提交
2060 2061
				face = obj_faces[ fi ];
				uv2 = obj_uvs2[ fi ];
2062

A
alteredq 已提交
2063 2064 2065 2066 2067 2068 2069 2070 2071 2072
				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;
2073

2074 2075
				}

A
alteredq 已提交
2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096
			}

			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;

				}
2097

2098
			}
2099

A
alteredq 已提交
2100
			if ( offset_uv2 > 0 ) {
2101

A
alteredq 已提交
2102 2103
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );
2104

A
alteredq 已提交
2105
			}
2106

A
alteredq 已提交
2107
		}
2108

A
alteredq 已提交
2109
		if ( dirtyElements ) {
2110

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

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

A
alteredq 已提交
2115 2116 2117
				faceArray[ offset_face ] 	 = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 2;
2118

A
alteredq 已提交
2119
				offset_face += 3;
2120

A
alteredq 已提交
2121 2122
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2123

A
alteredq 已提交
2124 2125
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 2;
2126

A
alteredq 已提交
2127 2128
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
2129

A
alteredq 已提交
2130
				offset_line += 6;
2131

A
alteredq 已提交
2132
				vertexIndex += 3;
2133

A
alteredq 已提交
2134
			}
2135

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

A
alteredq 已提交
2138
				face = obj_faces[ chunk_faces4[ f ] ];
2139

A
alteredq 已提交
2140 2141 2142
				faceArray[ offset_face ]     = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 3;
2143

A
alteredq 已提交
2144 2145 2146
				faceArray[ offset_face + 3 ] = vertexIndex + 1;
				faceArray[ offset_face + 4 ] = vertexIndex + 2;
				faceArray[ offset_face + 5 ] = vertexIndex + 3;
2147

A
alteredq 已提交
2148
				offset_face += 6;
2149

A
alteredq 已提交
2150 2151
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2152

A
alteredq 已提交
2153 2154
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 3;
2155

A
alteredq 已提交
2156 2157
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
2158

A
alteredq 已提交
2159 2160
				lineArray[ offset_line + 6 ] = vertexIndex + 2;
				lineArray[ offset_line + 7 ] = vertexIndex + 3;
2161

A
alteredq 已提交
2162
				offset_line += 8;
2163

A
alteredq 已提交
2164
				vertexIndex += 4;
2165

2166
			}
2167

A
alteredq 已提交
2168 2169
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
2170

A
alteredq 已提交
2171 2172
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
2173

A
alteredq 已提交
2174
		}
2175

A
alteredq 已提交
2176
		if ( customAttributes ) {
2177

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

2180
				customAttribute = customAttributes[ i ];
2181

2182
				if ( ! customAttribute.__original.needsUpdate ) continue;
2183

2184 2185
				offset_custom = 0;
				offset_customSrc = 0;
2186

2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219
				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 ++ ) {

2220
							value = customAttribute.value[ chunk_faces3[ f ] ];
2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231

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

2232
							value = customAttribute.value[ chunk_faces4[ f ] ];
2233 2234 2235 2236 2237 2238 2239 2240 2241

							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;

						}
2242

2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261
					}

				} 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 已提交
2262

2263 2264
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2265

2266
							offset_custom += 6;
A
alteredq 已提交
2267

2268
						}
A
alteredq 已提交
2269

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

2272
							face = obj_faces[ chunk_faces4[ f ] ];
A
alteredq 已提交
2273

2274 2275 2276 2277
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
A
alteredq 已提交
2278

2279 2280
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2281

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

2285 2286
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2287

2288 2289
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
A
alteredq 已提交
2290

2291
							offset_custom += 8;
A
alteredq 已提交
2292

2293
						}
A
alteredq 已提交
2294

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

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

2299
							value = customAttribute.value[ chunk_faces3[ f ] ];
A
alteredq 已提交
2300

2301 2302 2303
							v1 = value;
							v2 = value;
							v3 = value;
A
alteredq 已提交
2304

2305 2306
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2307

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

2311 2312
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2313

2314
							offset_custom += 6;
A
alteredq 已提交
2315

2316
						}
A
alteredq 已提交
2317

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

2320
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2321

2322 2323 2324 2325
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2326

2327 2328
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2329

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

2333 2334
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2335

2336 2337
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
2338

2339
							offset_custom += 8;
M
Mr.doob 已提交
2340

2341
						}
M
Mr.doob 已提交
2342

M
Mr.doob 已提交
2343
					}
M
Mr.doob 已提交
2344

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

2347
					var pp;
2348

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

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

2353
					} else {
M
Mr.doob 已提交
2354

2355
						pp = [ "x", "y", "z" ];
2356

2357
					}
2358

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

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

2363
							face = obj_faces[ chunk_faces3[ f ]	];
2364

2365 2366 2367
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
2368

2369 2370 2371
							customAttribute.array[ offset_custom ] 	   = v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
2372

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

2377 2378 2379
							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 已提交
2380

2381
							offset_custom += 9;
M
Mr.doob 已提交
2382

2383
						}
M
Mr.doob 已提交
2384

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

2387
							face = obj_faces[ chunk_faces4[ f ] ];
M
Mr.doob 已提交
2388

2389 2390 2391 2392
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
M
Mr.doob 已提交
2393

2394 2395 2396
							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 已提交
2397

2398 2399 2400
							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 已提交
2401

2402 2403 2404
							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 已提交
2405

2406 2407 2408
							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 已提交
2409

2410
							offset_custom += 12;
M
Mr.doob 已提交
2411

2412
						}
M
Mr.doob 已提交
2413

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

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

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

2420 2421 2422
							v1 = value;
							v2 = value;
							v3 = value;
M
Mr.doob 已提交
2423

2424 2425 2426
							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 已提交
2427

2428 2429 2430
							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 已提交
2431

2432 2433 2434
							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 已提交
2435

2436
							offset_custom += 9;
M
Mr.doob 已提交
2437

2438
						}
2439

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

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

2444 2445 2446 2447
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
2448

2449 2450 2451
							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
2452

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

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

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

2465
							offset_custom += 12;
2466

2467
						}
2468

A
alteredq 已提交
2469
					}
M
Mr.doob 已提交
2470

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

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

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

2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538
							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 ++ ) {

2539
							value = customAttribute.value[ chunk_faces3[ f ] ];
2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556

							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;
2557 2558
							customAttribute.array[ offset_custom + 10 ] = v3.z;
							customAttribute.array[ offset_custom + 11 ] = v3.w;
A
alteredq 已提交
2559

2560
							offset_custom += 12;
A
alteredq 已提交
2561

2562 2563
						}

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

2566
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2567

2568 2569 2570 2571
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2572

2573 2574 2575 2576
							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;
2577

2578 2579 2580 2581
							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;
2582

2583 2584 2585 2586
							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;
2587

2588 2589 2590 2591
							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;
2592

2593
							offset_custom += 16;
A
alteredq 已提交
2594

2595
						}
A
alteredq 已提交
2596 2597 2598 2599 2600

					}

				}

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

A
alteredq 已提交
2604 2605 2606 2607
			}

		}

2608
		if ( dispose ) {
2609

2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622
			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.__skinVertexAArray;
			delete geometryGroup.__skinVertexBArray;
			delete geometryGroup.__skinIndexArray;
			delete geometryGroup.__skinWeightArray;
A
alteredq 已提交
2623

2624
		}
A
alteredq 已提交
2625

2626
	};
A
alteredq 已提交
2627

2628
	// Buffer rendering
A
alteredq 已提交
2629

A
alteredq 已提交
2630
	this.renderBufferImmediate = function ( object, program, shading ) {
A
alteredq 已提交
2631

2632 2633
		if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
A
alteredq 已提交
2634

2635
		if ( object.hasPos ) {
A
alteredq 已提交
2636

2637 2638 2639 2640
			_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 已提交
2641 2642 2643

		}

2644
		if ( object.hasNormal ) {
A
alteredq 已提交
2645

2646
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
A
alteredq 已提交
2647

2648
			if ( shading === THREE.FlatShading ) {
2649

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

2655
				for( i = 0; i < il; i += 9 ) {
2656

2657
					normalArray = object.normalArray;
2658

2659 2660 2661
					nax  = normalArray[ i ];
					nay  = normalArray[ i + 1 ];
					naz  = normalArray[ i + 2 ];
2662

2663 2664 2665
					nbx  = normalArray[ i + 3 ];
					nby  = normalArray[ i + 4 ];
					nbz  = normalArray[ i + 5 ];
2666

2667 2668 2669
					ncx  = normalArray[ i + 6 ];
					ncy  = normalArray[ i + 7 ];
					ncz  = normalArray[ i + 8 ];
2670

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

2675 2676 2677
					normalArray[ i ] 	 = nx;
					normalArray[ i + 1 ] = ny;
					normalArray[ i + 2 ] = nz;
2678

2679 2680 2681
					normalArray[ i + 3 ] = nx;
					normalArray[ i + 4 ] = ny;
					normalArray[ i + 5 ] = nz;
2682

2683 2684 2685
					normalArray[ i + 6 ] = nx;
					normalArray[ i + 7 ] = ny;
					normalArray[ i + 8 ] = nz;
2686

2687
				}
2688

2689
			}
2690

2691 2692 2693
			_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 );
2694

2695
		}
2696

2697
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );
2698

2699
		object.count = 0;
2700

2701
	};
2702

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

2705
		if ( material.opacity === 0 ) return;
2706

2707
		var program, attributes, linewidth, primitives, a, attribute, i, il;
2708

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

2711
		attributes = program.attributes;
2712

2713 2714 2715
		var updateBuffers = false,
			wireframeBit = material.wireframe ? 1 : 0,
			geometryGroupHash = ( geometryGroup.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit;
2716

2717
		if ( geometryGroupHash !== _currentGeometryGroupHash ) {
A
alteredq 已提交
2718

2719 2720
			_currentGeometryGroupHash = geometryGroupHash;
			updateBuffers = true;
2721

2722
		}
2723

2724
		// vertices
2725

2726
		if ( !material.morphTargets && attributes.position >= 0 ) {
2727

2728
			if ( updateBuffers ) {
2729

2730 2731
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
				_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
2732

2733
			}
2734

2735
		} else {
2736

2737
			if ( object.morphTargetBase ) {
2738

2739
				setupMorphTargets( material, geometryGroup, object );
2740

2741
			}
2742

2743
		}
2744

2745

2746
		if ( updateBuffers ) {
2747

2748
			// custom attributes
2749

2750
			// Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
2751

2752
			if ( geometryGroup.__webglCustomAttributesList ) {
2753

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

2756
					attribute = geometryGroup.__webglCustomAttributesList[ i ];
2757

2758
					if( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
2759

2760 2761
						_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
						_gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 );
2762

2763
					}
2764

2765
				}
2766

2767
			}
2768 2769


2770
			// colors
2771

2772
			if ( attributes.color >= 0 ) {
2773

2774 2775
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
2776

2777
			}
2778

2779
			// normals
2780

2781
			if ( attributes.normal >= 0 ) {
2782

2783 2784
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
				_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
2785

2786
			}
2787

2788
			// tangents
2789

2790
			if ( attributes.tangent >= 0 ) {
2791

2792 2793
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
				_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
2794

2795
			}
2796

2797
			// uvs
2798

2799
			if ( attributes.uv >= 0 ) {
2800

2801
				if ( geometryGroup.__webglUVBuffer ) {
2802

2803 2804
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
					_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
2805

2806
					_gl.enableVertexAttribArray( attributes.uv );
2807

2808
				} else {
2809

2810
					_gl.disableVertexAttribArray( attributes.uv );
2811 2812 2813 2814 2815

				}

			}

2816
			if ( attributes.uv2 >= 0 ) {
2817

2818
				if ( geometryGroup.__webglUV2Buffer ) {
2819

2820 2821
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
					_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
2822

2823
					_gl.enableVertexAttribArray( attributes.uv2 );
2824

2825
				} else {
2826

2827
					_gl.disableVertexAttribArray( attributes.uv2 );
2828 2829

				}
2830 2831

			}
2832

2833 2834 2835
			if ( material.skinning &&
				 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
				 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
A
alteredq 已提交
2836

2837 2838
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
2839

2840 2841
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
				_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
2842

2843 2844
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
				_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
2845

2846 2847
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
				_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
2848

A
alteredq 已提交
2849
			}
2850

2851
		}
2852

2853
		// render mesh
2854

2855
		if ( object instanceof THREE.Mesh ) {
2856

2857
			// wireframe
2858

2859
			if ( material.wireframe ) {
2860

2861
				setLineWidth( material.wireframeLinewidth );
2862

2863 2864
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
2865

2866
			// triangles
2867

2868
			} else {
2869

2870 2871
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
2872

2873
			}
2874

2875 2876 2877
			_this.info.render.calls ++;
			_this.info.render.vertices += geometryGroup.__webglFaceCount;
			_this.info.render.faces += geometryGroup.__webglFaceCount / 3;
2878

2879
		// render lines
2880

2881
		} else if ( object instanceof THREE.Line ) {
2882

2883
			primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
2884

2885
			setLineWidth( material.linewidth );
2886

2887
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
2888

2889
			_this.info.render.calls ++;
2890

2891
		// render particles
2892

2893
		} else if ( object instanceof THREE.ParticleSystem ) {
2894

2895
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
2896

2897
			_this.info.render.calls ++;
2898

2899
		// render ribbon
2900

2901
		} else if ( object instanceof THREE.Ribbon ) {
2902

2903
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
2904

2905
			_this.info.render.calls ++;
2906

2907
		}
2908

2909
	};
2910

2911
	function setupMorphTargets ( material, geometryGroup, object ) {
2912

2913
		// set base
2914

2915
		var attributes = material.program.attributes;
2916

2917
		if ( object.morphTargetBase !== - 1 ) {
2918

2919 2920
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
2921

2922
		} else if ( attributes.position >= 0 ) {
2923

2924 2925
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
2926

2927
		}
2928

2929
		if ( object.morphTargetForcedOrder.length ) {
2930

2931
			// set forced order
2932

2933 2934 2935 2936 2937
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;

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

2939 2940 2941 2942 2943 2944
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ order[ m ] ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );

				object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ] ];

				m ++;
2945 2946
			}

2947 2948 2949 2950 2951 2952 2953 2954 2955 2956
		} else {

			// find most influencing

			var used = [];
			var candidateInfluence = - 1;
			var candidate = 0;
			var influences = object.morphTargetInfluences;
			var i, il = influences.length;
			var m = 0;
2957

2958
			if ( object.morphTargetBase !== - 1 ) {
2959

2960
				used[ object.morphTargetBase ] = true;
2961

2962
			}
2963

2964
			while ( m < material.numSupportedMorphTargets ) {
2965

2966
				for ( i = 0; i < il; i ++ ) {
2967

2968
					if ( !used[ i ] && influences[ i ] > candidateInfluence ) {
2969

2970 2971
						candidate = i;
						candidateInfluence = influences[ candidate ];
2972

2973
					}
2974

2975
				}
2976

2977 2978
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
2979

2980
				object.__webglMorphTargetInfluences[ m ] = candidateInfluence;
2981

2982 2983 2984
				used[ candidate ] = 1;
				candidateInfluence = -1;
				m ++;
2985 2986 2987 2988 2989

			}

		}

2990
		// load updated influences uniform
2991

2992
		if( material.program.uniforms.morphTargetInfluences !== null ) {
M
Mr.doob 已提交
2993

2994
			_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
2995

2996
		}
2997

2998
	};
2999 3000


3001
	function painterSort ( a, b ) {
3002

3003
		return b.z - a.z;
3004

3005
	};
3006

3007
	// Rendering
3008

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

3011 3012 3013 3014 3015 3016 3017 3018
		var i, il,

		program, material,
		webglObject, object,
		renderList,

		lights = scene.lights,
		fog = scene.fog;
M
Mr.doob 已提交
3019

3020
		_currentMaterialId = -1;
3021

3022
		if ( this.autoUpdateObjects ) this.initWebGLObjects( scene );
3023

3024
		if ( camera.parent === undefined ) {
3025

3026 3027
			console.warn( 'DEPRECATED: Camera hasn\'t been added to a Scene. Adding it...' );
			scene.add( camera );
3028

3029
		}
3030

3031
		if ( this.autoUpdateScene ) scene.updateMatrixWorld();
3032

A
alteredq 已提交
3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057
		// custom render plugins (pre pass)

		if ( this.renderPluginsPre.length ) {

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

				_currentProgram = null;
				_oldBlending = -1;
				_oldDepthTest = -1;
				_oldDepthWrite = -1;
				_currentGeometryGroupHash = -1;
				_currentMaterialId = -1;

				this.renderPluginsPre[ i ].render( scene, camera, _viewportWidth, _viewportHeight );

				_currentProgram = null;
				_oldBlending = -1;
				_oldDepthTest = -1;
				_oldDepthWrite = -1;
				_currentGeometryGroupHash = -1;
				_currentMaterialId = -1;

			}

		}
A
alteredq 已提交
3058 3059 3060 3061 3062

		_this.info.render.calls = 0;
		_this.info.render.vertices = 0;
		_this.info.render.faces = 0;

3063
		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
A
alteredq 已提交
3064 3065 3066 3067 3068 3069

		if ( ! camera._viewMatrixArray ) camera._viewMatrixArray = new Float32Array( 16 );
		camera.matrixWorldInverse.flattenToArray( camera._viewMatrixArray );

		if ( ! camera._projectionMatrixArray ) camera._projectionMatrixArray = new Float32Array( 16 );
		camera.projectionMatrix.flattenToArray( camera._projectionMatrixArray );
3070

3071
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
A
alteredq 已提交
3072
		_frustum.setFromMatrix( _projScreenMatrix );
3073

A
alteredq 已提交
3074
		this.setRenderTarget( renderTarget );
3075

3076
		if ( this.autoClear || forceClear ) {
3077

3078
			this.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );
M
Mr.doob 已提交
3079

3080
		}
M
Mr.doob 已提交
3081

3082
		// set matrices for regular objects (frustum culled)
3083

3084
		renderList = scene.__webglObjects;
3085

3086
		for ( i = 0, il = renderList.length; i < il; i ++ ) {
3087

3088
			webglObject = renderList[ i ];
3089
			object = webglObject.object;
3090

A
alteredq 已提交
3091 3092
			webglObject.render = false;

3093
			if ( object.visible ) {
3094

A
alteredq 已提交
3095
				if ( ! ( object instanceof THREE.Mesh ) || ! ( object.frustumCulled ) || _frustum.contains( object ) ) {
M
Mr.doob 已提交
3096

3097
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
3098

A
alteredq 已提交
3099
					setupMatrices( object, camera );
3100

3101
					unrollBufferMaterial( webglObject );
3102

3103
					webglObject.render = true;
3104

3105
					if ( this.sortObjects ) {
3106

3107
						if ( object.renderDepth ) {
3108

3109
							webglObject.z = object.renderDepth;
M
Mr.doob 已提交
3110

3111
						} else {
M
Mr.doob 已提交
3112

3113 3114
							_vector3.copy( object.position );
							_projScreenMatrix.multiplyVector3( _vector3 );
3115

3116
							webglObject.z = _vector3.z;
3117

3118
						}
M
Mr.doob 已提交
3119

3120
					}
M
Mr.doob 已提交
3121

3122
				}
3123 3124

			}
3125 3126 3127

		}

3128
		if ( this.sortObjects ) {
M
Mr.doob 已提交
3129

3130
			renderList.sort( painterSort );
3131

3132
		}
3133

3134
		// set matrices for immediate objects
3135

3136
		renderList = scene.__webglObjectsImmediate;
3137

3138 3139 3140
		for ( i = 0, il = renderList.length; i < il; i ++ ) {

			webglObject = renderList[ i ];
3141
			object = webglObject.object;
3142

3143
			if ( object.visible ) {
3144

3145
				if( object.matrixAutoUpdate ) {
3146

3147
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3148

3149
				}
M
Mr.doob 已提交
3150

A
alteredq 已提交
3151
				setupMatrices( object, camera );
M
Mr.doob 已提交
3152

3153
				unrollImmediateBufferMaterial( webglObject );
M
Mr.doob 已提交
3154

3155
			}
M
Mr.doob 已提交
3156

3157
		}
3158

3159
		if ( scene.overrideMaterial ) {
3160

3161
			this.setBlending( scene.overrideMaterial.blending );
A
alteredq 已提交
3162
			this.setDepthTest( scene.overrideMaterial.depthTest );
3163 3164
			setDepthWrite( scene.overrideMaterial.depthWrite );
			setPolygonOffset( scene.overrideMaterial.polygonOffset, scene.overrideMaterial.polygonOffsetFactor, scene.overrideMaterial.polygonOffsetUnits );
3165

3166 3167
			renderObjects( scene.__webglObjects, false, "", camera, lights, fog, true, scene.overrideMaterial );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "", camera, lights, fog, false, scene.overrideMaterial );
M
Mr.doob 已提交
3168

3169
		} else {
3170

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

3173
			this.setBlending( THREE.NormalBlending );
3174

3175 3176
			renderObjects( scene.__webglObjects, true, "opaque", camera, lights, fog, false );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "opaque", camera, lights, fog, false );
3177

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

3180 3181
			renderObjects( scene.__webglObjects, false, "transparent", camera, lights, fog, true );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "transparent", camera, lights, fog, true );
3182

3183
		}
3184

A
alteredq 已提交
3185
		// custom render plugins (post pass)
3186

A
alteredq 已提交
3187
		if ( this.renderPluginsPost.length ) {
3188

A
alteredq 已提交
3189
			for ( i = 0, il = this.renderPluginsPost.length; i < il; i ++ ) {
3190

A
alteredq 已提交
3191
				this.renderPluginsPost[ i ].render( scene, camera, _viewportWidth, _viewportHeight );
3192 3193 3194 3195 3196 3197

				_currentProgram = null;
				_oldBlending = -1;
				_oldDepthTest = -1;
				_oldDepthWrite = -1;
				_currentGeometryGroupHash = -1;
A
alteredq 已提交
3198
				_currentMaterialId = -1;
3199 3200 3201 3202 3203

			}

		}

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

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

3208
			updateRenderTargetMipmap( renderTarget );
3209

3210
		}
3211

3212
		//_gl.finish();
3213

3214
	};
3215

3216 3217 3218 3219 3220 3221 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
	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;

3252
					if ( useBlending ) _this.setBlending( material.blending );
3253

A
alteredq 已提交
3254
					_this.setDepthTest( material.depthTest );
3255 3256 3257 3258 3259
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

A
alteredq 已提交
3260 3261
				_this.setObjectFaces( object );
				_this.renderBuffer( camera, lights, fog, material, buffer, object );
3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289

			}

		}

	};

	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;

A
alteredq 已提交
3290
					if ( useBlending ) _this.setBlending( material.blending );
3291

A
alteredq 已提交
3292
					_this.setDepthTest( material.depthTest );
3293 3294 3295 3296 3297
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

A
alteredq 已提交
3298
				_this.renderImmediateObject( camera, lights, fog, material, object );
3299

A
alteredq 已提交
3300
			}
3301

A
alteredq 已提交
3302
		}
3303

A
alteredq 已提交
3304
	};
3305

A
alteredq 已提交
3306
	this.renderImmediateObject = function ( camera, lights, fog, material, object ) {
3307

A
alteredq 已提交
3308
		var program = setProgram( camera, lights, fog, material, object );
3309

A
alteredq 已提交
3310
		_currentGeometryGroupHash = -1;
3311

A
alteredq 已提交
3312 3313 3314 3315 3316 3317 3318 3319 3320
		_this.setObjectFaces( object );

		if ( object.immediateRenderCallback ) {

			object.immediateRenderCallback( program, _gl, _frustum );

		} else {

			object.render( function( object ) { _this.renderBufferImmediate( object, program, material.shading ); } );
3321 3322 3323 3324 3325

		}

	};

3326
	function unrollImmediateBufferMaterial ( globject ) {
3327

3328 3329
		var object = globject.object,
			material = object.material;
3330

3331
		if ( material.transparent ) {
3332

3333 3334
			globject.transparent = material;
			globject.opaque = null;
3335

3336
		} else {
3337

3338 3339
			globject.opaque = material;
			globject.transparent = null;
3340

3341
		}
A
alteredq 已提交
3342

3343
	};
A
alteredq 已提交
3344

3345
	function unrollBufferMaterial ( globject ) {
A
alteredq 已提交
3346

3347 3348 3349
		var object = globject.object,
			buffer = globject.buffer,
			material, materialIndex, meshMaterial;
3350

3351
		meshMaterial = object.material;
3352

3353
		if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
M
Mr.doob 已提交
3354

3355
			materialIndex = buffer.materialIndex;
3356

3357
			if ( materialIndex >= 0 ) {
3358

3359
				material = object.geometry.materials[ materialIndex ];
M
Mr.doob 已提交
3360

3361
				if ( material.transparent ) {
M
Mr.doob 已提交
3362

3363 3364
					globject.transparent = material;
					globject.opaque = null;
3365

3366
				} else {
3367

3368 3369
					globject.opaque = material;
					globject.transparent = null;
3370

3371
				}
3372

3373
			}
3374

3375
		} else {
3376

3377
			material = meshMaterial;
3378

3379
			if ( material ) {
3380

3381
				if ( material.transparent ) {
M
Mr.doob 已提交
3382

3383 3384
					globject.transparent = material;
					globject.opaque = null;
A
alteredq 已提交
3385

3386
				} else {
3387

3388 3389
					globject.opaque = material;
					globject.transparent = null;
3390

3391
				}
3392

3393
			}
3394

3395
		}
3396

3397
	};
3398

3399
	// Geometry splitting
3400

3401
	function sortFacesByMaterial ( geometry ) {
3402

3403 3404 3405
		var f, fl, face, materialIndex, vertices,
			materialHash, groupHash,
			hash_map = {};
3406

3407
		var numMorphTargets = geometry.morphTargets.length;
3408

3409
		geometry.geometryGroups = {};
3410

3411
		for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
3412

3413 3414
			face = geometry.faces[ f ];
			materialIndex = face.materialIndex;
3415

3416
			materialHash = ( materialIndex !== undefined ) ? materialIndex : -1;
3417

3418
			if ( hash_map[ materialHash ] === undefined ) {
3419

3420
				hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 };
3421 3422 3423

			}

3424
			groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
3425

3426
			if ( geometry.geometryGroups[ groupHash ] === undefined ) {
3427

3428
				geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets };
3429

3430
			}
A
alteredq 已提交
3431

3432
			vertices = face instanceof THREE.Face3 ? 3 : 4;
A
alteredq 已提交
3433

3434
			if ( geometry.geometryGroups[ groupHash ].vertices + vertices > 65535 ) {
A
alteredq 已提交
3435

3436 3437
				hash_map[ materialHash ].counter += 1;
				groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
A
alteredq 已提交
3438

3439
				if ( geometry.geometryGroups[ groupHash ] === undefined ) {
A
alteredq 已提交
3440

3441
					geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets };
A
alteredq 已提交
3442

3443
				}
3444

3445
			}
3446

3447
			if ( face instanceof THREE.Face3 ) {
3448

3449
				geometry.geometryGroups[ groupHash ].faces3.push( f );
3450

3451
			} else {
3452

3453
				geometry.geometryGroups[ groupHash ].faces4.push( f );
3454

A
alteredq 已提交
3455
			}
3456

3457
			geometry.geometryGroups[ groupHash ].vertices += vertices;
3458

3459
		}
3460

3461
		geometry.geometryGroupsList = [];
3462

3463
		for ( var g in geometry.geometryGroups ) {
3464

3465
			geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;
3466

3467
			geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );
3468

3469
		}
3470

3471
	};
3472

3473 3474 3475 3476 3477 3478 3479 3480 3481
	// Objects refresh

	this.initWebGLObjects = function ( scene ) {

		if ( !scene.__webglObjects ) {

			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
			scene.__webglSprites = [];
3482
			scene.__webglFlares = [];
3483 3484

		}
3485

3486
		while ( scene.__objectsAdded.length ) {
3487

3488 3489
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
3490

3491
		}
A
alteredq 已提交
3492

3493
		while ( scene.__objectsRemoved.length ) {
3494

3495 3496
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
3497

3498
		}
3499

3500
		// update must be called after objects adding / removal
3501

3502
		for ( var o = 0, ol = scene.__webglObjects.length; o < ol; o ++ ) {
3503

3504
			updateObject( scene.__webglObjects[ o ].object );
M
Mr.doob 已提交
3505 3506 3507 3508 3509

		}

	};

3510
	// Objects adding
M
Mr.doob 已提交
3511

3512
	function addObject ( object, scene ) {
A
alteredq 已提交
3513

3514
		var g, geometry, geometryGroup;
3515

3516
		if ( ! object.__webglInit ) {
M
Mr.doob 已提交
3517

3518
			object.__webglInit = true;
M
Mr.doob 已提交
3519

3520
			object._modelViewMatrix = new THREE.Matrix4();
M
Mr.doob 已提交
3521

3522 3523 3524
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
M
Mr.doob 已提交
3525

3526
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3527

3528
			if ( object instanceof THREE.Mesh ) {
M
Mr.doob 已提交
3529

3530
				geometry = object.geometry;
M
Mr.doob 已提交
3531

3532
				if ( geometry.geometryGroups === undefined ) {
M
Mr.doob 已提交
3533

3534
					sortFacesByMaterial( geometry );
M
Mr.doob 已提交
3535

3536
				}
M
Mr.doob 已提交
3537

3538
				// create separate VBOs per geometry chunk
M
Mr.doob 已提交
3539

3540
				for ( g in geometry.geometryGroups ) {
M
Mr.doob 已提交
3541

3542
					geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
3543

3544
					// initialise VBO on the first access
M
Mr.doob 已提交
3545

3546
					if ( ! geometryGroup.__webglVertexBuffer ) {
3547

3548 3549
						createMeshBuffers( geometryGroup );
						initMeshBuffers( geometryGroup, object );
M
Mr.doob 已提交
3550

3551 3552 3553 3554 3555 3556 3557
						geometry.__dirtyVertices = true;
						geometry.__dirtyMorphTargets = true;
						geometry.__dirtyElements = true;
						geometry.__dirtyUvs = true;
						geometry.__dirtyNormals = true;
						geometry.__dirtyTangents = true;
						geometry.__dirtyColors = true;
M
Mr.doob 已提交
3558

3559
					}
M
Mr.doob 已提交
3560

3561
				}
M
Mr.doob 已提交
3562

3563
			} else if ( object instanceof THREE.Ribbon ) {
M
Mr.doob 已提交
3564

3565
				geometry = object.geometry;
M
Mr.doob 已提交
3566

3567
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
3568

3569 3570
					createRibbonBuffers( geometry );
					initRibbonBuffers( geometry );
M
Mr.doob 已提交
3571

3572 3573
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
3574

3575
				}
M
Mr.doob 已提交
3576

3577
			} else if ( object instanceof THREE.Line ) {
M
Mr.doob 已提交
3578

3579
				geometry = object.geometry;
M
Mr.doob 已提交
3580

3581
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
3582

3583 3584
					createLineBuffers( geometry );
					initLineBuffers( geometry, object );
M
Mr.doob 已提交
3585

3586 3587
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
3588

3589
				}
3590

3591
			} else if ( object instanceof THREE.ParticleSystem ) {
3592

3593
				geometry = object.geometry;
3594

3595
				if ( ! geometry.__webglVertexBuffer ) {
3596

3597 3598
					createParticleBuffers( geometry );
					initParticleBuffers( geometry, object );
3599

3600 3601
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
3602

3603
				}
3604

3605
			}
3606

3607
		}
3608

3609
		if ( ! object.__webglActive ) {
3610

3611
			if ( object instanceof THREE.Mesh ) {
3612

3613
				geometry = object.geometry;
3614

3615
				for ( g in geometry.geometryGroups ) {
3616

3617
					geometryGroup = geometry.geometryGroups[ g ];
3618

3619
					addBuffer( scene.__webglObjects, geometryGroup, object );
3620

3621
				}
3622

3623 3624 3625
			} else if ( object instanceof THREE.Ribbon ||
						object instanceof THREE.Line ||
						object instanceof THREE.ParticleSystem ) {
3626

3627 3628
				geometry = object.geometry;
				addBuffer( scene.__webglObjects, geometry, object );
3629

3630
			} else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes || object.immediateRenderCallback ) {
3631

3632
				addBufferImmediate( scene.__webglObjectsImmediate, object );
3633

3634
			} else if ( object instanceof THREE.Sprite ) {
3635

3636
				scene.__webglSprites.push( object );
3637

3638 3639 3640 3641
			} else if ( object instanceof THREE.LensFlare ) {

				scene.__webglFlares.push( object );

3642 3643
			}

3644
			object.__webglActive = true;
3645

3646
		}
3647

3648
	};
3649

3650
	function addBuffer ( objlist, buffer, object ) {
3651

3652 3653 3654 3655 3656 3657 3658 3659
		objlist.push(
			{
				buffer: buffer,
				object: object,
				opaque: null,
				transparent: null
			}
		);
3660

3661
	};
3662

3663
	function addBufferImmediate ( objlist, object ) {
3664

3665 3666 3667 3668 3669
		objlist.push(
			{
				object: object,
				opaque: null,
				transparent: null
3670
			}
3671
		);
3672

3673
	};
3674

3675
	// Objects updates
3676

3677
	function updateObject ( object ) {
3678

3679 3680
		var geometry = object.geometry,
			geometryGroup, customAttributesDirty, material;
3681

3682
		if ( object instanceof THREE.Mesh ) {
3683

3684
			// check all geometry groups
3685

3686
			for( var i = 0, il = geometry.geometryGroupsList.length; i < il; i ++ ) {
3687

3688
				geometryGroup = geometry.geometryGroupsList[ i ];
3689

3690
				material = getBufferMaterial( object, geometryGroup );
3691

3692
				customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
3693

3694 3695 3696
				if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
					 geometry.__dirtyUvs || geometry.__dirtyNormals ||
					 geometry.__dirtyColors || geometry.__dirtyTangents || customAttributesDirty ) {
3697

3698
					setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW, !geometry.dynamic, material );
3699

3700
				}
M
Mr.doob 已提交
3701

3702
			}
3703

3704 3705 3706 3707 3708 3709 3710
			geometry.__dirtyVertices = false;
			geometry.__dirtyMorphTargets = false;
			geometry.__dirtyElements = false;
			geometry.__dirtyUvs = false;
			geometry.__dirtyNormals = false;
			geometry.__dirtyColors = false;
			geometry.__dirtyTangents = false;
3711

3712
			material.attributes && clearCustomAttributes( material );
3713

3714
		} else if ( object instanceof THREE.Ribbon ) {
3715

3716
			if ( geometry.__dirtyVertices || geometry.__dirtyColors ) {
3717

3718
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
3719

3720
			}
3721

3722 3723
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
3724

3725
		} else if ( object instanceof THREE.Line ) {
3726

3727
			material = getBufferMaterial( object, geometryGroup );
A
alteredq 已提交
3728

3729
			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
A
alteredq 已提交
3730

3731
			if ( geometry.__dirtyVertices ||  geometry.__dirtyColors || customAttributesDirty ) {
A
alteredq 已提交
3732

3733
				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
3734

3735
			}
3736

3737 3738
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
3739

3740
			material.attributes && clearCustomAttributes( material );
3741

3742
		} else if ( object instanceof THREE.ParticleSystem ) {
3743

3744
			material = getBufferMaterial( object, geometryGroup );
3745

3746
			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
3747

3748
			if ( geometry.__dirtyVertices || geometry.__dirtyColors || object.sortParticles || customAttributesDirty ) {
3749

3750
				setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
3751

3752
			}
3753

3754 3755
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
3756

3757
			material.attributes && clearCustomAttributes( material );
3758

3759
		}
3760

3761
	};
3762

3763
	// Objects updates - custom attributes check
3764

3765
	function areCustomAttributesDirty ( material ) {
3766

3767
		for ( var a in material.attributes ) {
3768

3769
			if ( material.attributes[ a ].needsUpdate ) return true;
3770

3771
		}
3772

3773
		return false;
3774

3775
	};
3776

3777 3778 3779
	function clearCustomAttributes ( material ) {

		for ( var a in material.attributes ) {
3780

3781
			material.attributes[ a ].needsUpdate = false;
3782

3783
		}
3784

3785
	};
3786

3787
	// Objects removal
3788

3789
	function removeObject ( object, scene ) {
3790

3791 3792 3793 3794
		if ( object instanceof THREE.Mesh  ||
			 object instanceof THREE.ParticleSystem ||
			 object instanceof THREE.Ribbon ||
			 object instanceof THREE.Line ) {
3795

3796
			removeInstances( scene.__webglObjects, object );
3797

3798
		} else if ( object instanceof THREE.Sprite ) {
3799

3800
			removeInstancesDirect( scene.__webglSprites, object );
3801

3802 3803 3804 3805
		} else if ( object instanceof THREE.LensFlare ) {

			removeInstancesDirect( scene.__webglFlares, object );

3806
		} else if ( object instanceof THREE.MarchingCubes || object.immediateRenderCallback ) {
3807

3808
			removeInstances( scene.__webglObjectsImmediate, object );
3809

3810
		}
3811

3812
		object.__webglActive = false;
3813

3814
	};
3815

3816
	function removeInstances ( objlist, object ) {
3817

3818
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
3819

3820
			if ( objlist[ o ].object === object ) {
3821

3822
				objlist.splice( o, 1 );
3823

3824
			}
3825

3826
		}
3827

3828
	};
3829

3830
	function removeInstancesDirect ( objlist, object ) {
3831

3832
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
3833

3834
			if ( objlist[ o ] === object ) {
3835

3836
				objlist.splice( o, 1 );
3837

3838
			}
3839

3840
		}
3841

3842
	};
3843

3844
	// Materials
3845

3846
	this.initMaterial = function ( material, lights, fog, object ) {
3847

3848
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
3849

3850
		if ( material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
3851

3852
			shaderID = 'depth';
3853

3854
		} else if ( material instanceof THREE.MeshNormalMaterial ) {
3855

3856
			shaderID = 'normal';
M
Mr.doob 已提交
3857

3858
		} else if ( material instanceof THREE.MeshBasicMaterial ) {
M
Mr.doob 已提交
3859

3860
			shaderID = 'basic';
M
Mr.doob 已提交
3861

3862
		} else if ( material instanceof THREE.MeshLambertMaterial ) {
M
Mr.doob 已提交
3863

3864
			shaderID = 'lambert';
M
Mr.doob 已提交
3865

3866
		} else if ( material instanceof THREE.MeshPhongMaterial ) {
3867

3868
			shaderID = 'phong';
3869

3870
		} else if ( material instanceof THREE.LineBasicMaterial ) {
3871

3872
			shaderID = 'basic';
3873

3874
		} else if ( material instanceof THREE.ParticleBasicMaterial ) {
3875

3876
			shaderID = 'particle_basic';
3877 3878 3879

		}

3880
		if ( shaderID ) {
3881

3882
			setMaterialShaders( material, THREE.ShaderLib[ shaderID ] );
3883

3884
		}
3885

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

3889
		maxLightCount = allocateLights( lights );
3890

3891
		maxShadows = allocateShadows( lights );
3892

3893
		maxBones = allocateBones( object );
3894

3895
		parameters = {
3896

3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913
			map: !!material.map, envMap: !!material.envMap, lightMap: !!material.lightMap,
			vertexColors: material.vertexColors,
			fog: fog, useFog: material.fog,
			sizeAttenuation: material.sizeAttenuation,
			skinning: material.skinning,
			morphTargets: material.morphTargets,
			maxMorphTargets: this.maxMorphTargets,
			maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
			maxBones: maxBones,
			shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
			shadowMapSoft: this.shadowMapSoft,
			shadowMapWidth: this.shadowMapWidth,
			shadowMapHeight: this.shadowMapHeight,
			maxShadows: maxShadows,
			alphaTest: material.alphaTest,
			metal: material.metal,
			perPixel: material.perPixel
3914

3915
		};
M
Mr.doob 已提交
3916

3917
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
3918

3919
		var attributes = material.program.attributes;
3920

3921 3922 3923 3924
		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 );
3925

3926 3927 3928
		if ( material.skinning &&
			 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
M
Mr.doob 已提交
3929

3930 3931 3932 3933
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
M
Mr.doob 已提交
3934 3935

		}
3936

3937
		if ( material.attributes ) {
A
alteredq 已提交
3938

3939
			for ( a in material.attributes ) {
M
Mr.doob 已提交
3940

3941
				if( attributes[ a ] !== undefined && attributes[ a ] >= 0 ) _gl.enableVertexAttribArray( attributes[ a ] );
3942

3943
			}
M
Mr.doob 已提交
3944

3945
		}
M
Mr.doob 已提交
3946

3947
		if ( material.morphTargets ) {
M
Mr.doob 已提交
3948

3949
			material.numSupportedMorphTargets = 0;
3950

3951
			var id, base = "morphTarget";
3952

3953
			for ( i = 0; i < this.maxMorphTargets; i ++ ) {
3954

3955
				id = base + i;
M
Mr.doob 已提交
3956

3957
				if ( attributes[ id ] >= 0 ) {
M
Mr.doob 已提交
3958

3959 3960
					_gl.enableVertexAttribArray( attributes[ id ] );
					material.numSupportedMorphTargets ++;
3961

3962
				}
3963

3964
			}
3965

3966
		}
3967

3968
		material.uniformsList = [];
3969

3970
		for ( u in material.uniforms ) {
3971

3972
			material.uniformsList.push( [ material.uniforms[ u ], u ] );
3973

3974
		}
M
Mr.doob 已提交
3975

3976
	};
M
Mr.doob 已提交
3977

3978
	function setMaterialShaders ( material, shaders ) {
M
Mr.doob 已提交
3979

3980 3981 3982
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
M
Mr.doob 已提交
3983

3984
	};
M
Mr.doob 已提交
3985

3986
	function setProgram ( camera, lights, fog, material, object ) {
3987

3988
		if ( ! material.program ) {
3989

3990
			_this.initMaterial( material, lights, fog, object );
3991

3992
		}
3993

3994
		if ( material.morphTargets ) {
3995

3996
			if ( ! object.__webglMorphTargetInfluences ) {
3997

3998
				object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );
3999

4000
				for ( var i = 0, il = _this.maxMorphTargets; i < il; i ++ ) {
4001

4002
					object.__webglMorphTargetInfluences[ i ] = 0;
4003

4004
				}
4005

4006
			}
4007

4008
		}
4009

4010
		var refreshMaterial = false;
4011

4012 4013 4014
		var program = material.program,
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
4015

4016
		if ( program !== _currentProgram ) {
4017

4018 4019
			_gl.useProgram( program );
			_currentProgram = program;
4020

4021
			refreshMaterial = true;
4022

4023
		}
4024

4025
		if ( material.id !== _currentMaterialId ) {
4026

4027 4028
			_currentMaterialId = material.id;
			refreshMaterial = true;
4029

4030
		}
4031

4032
		if ( refreshMaterial ) {
4033

A
alteredq 已提交
4034
			_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, camera._projectionMatrixArray );
A
alteredq 已提交
4035

4036
			// refresh uniforms common to several materials
4037

4038
			if ( fog && material.fog ) {
4039

4040
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
4041

4042
			}
M
Mr.doob 已提交
4043

4044 4045 4046
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material.lights ) {
4047

4048 4049
				setupLights( program, lights );
				refreshUniformsLights( m_uniforms, _lights );
4050

4051
			}
M
Mr.doob 已提交
4052

4053 4054 4055
			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
4056

4057
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
4058 4059 4060

			}

4061
			// refresh single material specific uniforms
M
Mr.doob 已提交
4062

4063
			if ( material instanceof THREE.LineBasicMaterial ) {
4064

4065
				refreshUniformsLine( m_uniforms, material );
M
Mr.doob 已提交
4066

4067
			} else if ( material instanceof THREE.ParticleBasicMaterial ) {
M
Mr.doob 已提交
4068

4069
				refreshUniformsParticle( m_uniforms, material );
M
Mr.doob 已提交
4070

4071
			} else if ( material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
4072

4073
				refreshUniformsPhong( m_uniforms, material );
M
Mr.doob 已提交
4074

4075
			} else if ( material instanceof THREE.MeshLambertMaterial ) {
M
Mr.doob 已提交
4076

4077
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
4078

4079
			} else if ( material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
4080

4081 4082 4083
				m_uniforms.mNear.value = camera.near;
				m_uniforms.mFar.value = camera.far;
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4084

4085
			} else if ( material instanceof THREE.MeshNormalMaterial ) {
M
Mr.doob 已提交
4086

4087
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4088

4089
			}
M
Mr.doob 已提交
4090

4091
			if ( object.receiveShadow && ! material._shadowPass ) {
M
Mr.doob 已提交
4092

4093
				refreshUniformsShadow( m_uniforms, material );
M
Mr.doob 已提交
4094

4095
			}
M
Mr.doob 已提交
4096

4097
			// load common uniforms
M
Mr.doob 已提交
4098

4099
			loadUniformsGeneric( program, material.uniformsList );
M
Mr.doob 已提交
4100

4101 4102
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)
4103

4104 4105 4106
			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
				 material.envMap ) {
4107

4108
				if( p_uniforms.cameraPosition !== null ) {
4109

4110
					_gl.uniform3f( p_uniforms.cameraPosition, camera.position.x, camera.position.y, camera.position.z );
4111

4112
				}
4113 4114 4115

			}

4116 4117 4118 4119
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {
4120

4121
				if( p_uniforms.viewMatrix !== null ) {
4122

A
alteredq 已提交
4123
					_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, camera._viewMatrixArray );
4124

4125
				}
4126

4127
			}
M
Mr.doob 已提交
4128

4129
			if ( material.skinning ) {
4130

A
alteredq 已提交
4131
				loadUniformsSkinning( p_uniforms, object, camera );
4132

4133
			}
4134

4135
		}
M
Mr.doob 已提交
4136

4137
		loadUniformsMatrices( p_uniforms, object );
M
Mr.doob 已提交
4138

4139 4140 4141 4142
		if ( material instanceof THREE.ShaderMaterial ||
			 material.envMap ||
			 material.skinning ||
			 object.receiveShadow ) {
M
Mr.doob 已提交
4143

4144
			if ( p_uniforms.objectMatrix !== null ) {
M
Mr.doob 已提交
4145

4146
				_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
M
Mr.doob 已提交
4147

4148
			}
4149

4150
		}
4151

4152
		return program;
4153

4154
	};
4155

4156
	// Uniforms (refresh uniforms objects)
A
alteredq 已提交
4157

4158
	function refreshUniformsCommon ( uniforms, material ) {
4159

4160
		uniforms.opacity.value = material.opacity;
4161

4162
		if ( _this.gammaInput ) {
4163

4164
			uniforms.diffuse.value.copyGammaToLinear( material.color );
4165

4166
		} else {
4167

4168
			uniforms.diffuse.value = material.color;
4169

4170
		}
4171

4172
		uniforms.map.texture = material.map;
4173

4174
		if ( material.map ) {
4175

4176
			uniforms.offsetRepeat.value.set( material.map.offset.x, material.map.offset.y, material.map.repeat.x, material.map.repeat.y );
M
Mr.doob 已提交
4177

4178
		}
M
Mr.doob 已提交
4179

4180
		uniforms.lightMap.texture = material.lightMap;
4181

4182 4183
		uniforms.envMap.texture = material.envMap;
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
4184

4185
		if ( _this.gammaInput ) {
4186

4187 4188
			//uniforms.reflectivity.value = material.reflectivity * material.reflectivity;
			uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
4189

4190
		} else {
4191

4192
			uniforms.reflectivity.value = material.reflectivity;
4193

4194
		}
4195

4196 4197 4198
		uniforms.refractionRatio.value = material.refractionRatio;
		uniforms.combine.value = material.combine;
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
M
Mr.doob 已提交
4199

4200
	};
M
Mr.doob 已提交
4201

4202
	function refreshUniformsLine ( uniforms, material ) {
M
Mr.doob 已提交
4203

4204 4205
		uniforms.diffuse.value = material.color;
		uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4206

4207
	};
M
Mr.doob 已提交
4208

4209
	function refreshUniformsParticle ( uniforms, material ) {
4210

4211 4212 4213 4214
		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.
4215

4216
		uniforms.map.texture = material.map;
4217

4218
	};
4219

4220
	function refreshUniformsFog ( uniforms, fog ) {
4221

4222
		uniforms.fogColor.value = fog.color;
4223

4224
		if ( fog instanceof THREE.Fog ) {
4225

4226 4227
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
4228

4229
		} else if ( fog instanceof THREE.FogExp2 ) {
M
Mikael Emtinger 已提交
4230

4231
			uniforms.fogDensity.value = fog.density;
M
Mikael Emtinger 已提交
4232

4233
		}
M
Mikael Emtinger 已提交
4234

4235
	};
M
Mikael Emtinger 已提交
4236

4237
	function refreshUniformsPhong ( uniforms, material ) {
M
Mikael Emtinger 已提交
4238

4239
		uniforms.shininess.value = material.shininess;
4240

4241
		if ( _this.gammaInput ) {
M
Mikael Emtinger 已提交
4242

4243 4244
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
			uniforms.specular.value.copyGammaToLinear( material.specular );
4245

4246
		} else {
4247

4248 4249
			uniforms.ambient.value = material.ambient;
			uniforms.specular.value = material.specular;
4250

4251
		}
4252

4253
	};
4254

4255
	function refreshUniformsLambert ( uniforms, material ) {
4256

4257
		if ( _this.gammaInput ) {
4258

4259
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
M
Mr.doob 已提交
4260

4261
		} else {
4262

4263
			uniforms.ambient.value = material.ambient;
4264

4265
		}
4266

4267
	};
4268

4269
	function refreshUniformsLights ( uniforms, lights ) {
4270

4271
		uniforms.ambientLightColor.value = lights.ambient;
4272

4273 4274
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
4275

4276 4277 4278
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
		uniforms.pointLightDistance.value = lights.point.distances;
4279

4280
	};
4281

4282
	function refreshUniformsShadow ( uniforms, material ) {
M
Mr.doob 已提交
4283

4284
		if ( uniforms.shadowMatrix ) {
4285

A
alteredq 已提交
4286
			for ( var i = 0; i < _this.shadowMapPlugin.shadowMatrix.length; i ++ ) {
4287

A
alteredq 已提交
4288 4289
				uniforms.shadowMatrix.value[ i ] = _this.shadowMapPlugin.shadowMatrix[ i ];
				uniforms.shadowMap.texture[ i ] = _this.shadowMapPlugin.shadowMap[ i ];
4290 4291


4292
			}
4293

4294 4295 4296
			uniforms.shadowDarkness.value = _this.shadowMapDarkness;
			uniforms.shadowBias.value = _this.shadowMapBias;

4297 4298
		}

4299
	};
4300

4301
	// Uniforms (load to GPU)
4302

A
alteredq 已提交
4303
	function loadUniformsSkinning ( uniforms, object, camera ) {
4304

A
alteredq 已提交
4305
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, camera._viewMatrixArray );
4306
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
4307

4308
	};
4309

4310

4311
	function loadUniformsMatrices ( uniforms, object ) {
4312

4313
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
4314

4315
		if ( uniforms.normalMatrix ) {
4316

4317
			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );
4318

4319
		}
4320

4321
	};
4322

4323
	function loadUniformsGeneric ( program, uniforms ) {
4324

4325
		var uniform, value, type, location, texture, i, il, j, jl, offset;
4326

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

4329 4330
			location = program.uniforms[ uniforms[ j ][ 1 ] ];
			if ( !location ) continue;
4331

4332
			uniform = uniforms[ j ][ 0 ];
4333

4334 4335
			type = uniform.type;
			value = uniform.value;
4336

4337
			// single integer
4338

4339
			if( type === "i" ) {
4340

4341
				_gl.uniform1i( location, value );
4342

4343
			// single float
4344

4345
			} else if( type === "f" ) {
4346

4347
				_gl.uniform1f( location, value );
4348

4349
			// single THREE.Vector2
4350

4351
			} else if( type === "v2" ) {
4352

4353
				_gl.uniform2f( location, value.x, value.y );
4354

4355
			// single THREE.Vector3
4356

4357
			} else if( type === "v3" ) {
4358

4359
				_gl.uniform3f( location, value.x, value.y, value.z );
4360

4361
			// single THREE.Vector4
4362

4363
			} else if( type === "v4" ) {
4364

4365
				_gl.uniform4f( location, value.x, value.y, value.z, value.w );
4366

4367
			// single THREE.Color
4368

4369
			} else if( type === "c" ) {
4370

4371
				_gl.uniform3f( location, value.r, value.g, value.b );
4372

4373
			// flat array of floats (JS or typed array)
4374

4375
			} else if( type === "fv1" ) {
4376

4377
				_gl.uniform1fv( location, value );
4378

4379
			// flat array of floats with 3 x N size (JS or typed array)
4380

4381
			} else if( type === "fv" ) {
4382

4383
				_gl.uniform3fv( location, value );
4384

4385
			// array of THREE.Vector3
4386

4387
			} else if( type === "v3v" ) {
4388

4389
				if ( ! uniform._array ) {
4390

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

4393
				}
A
alteredq 已提交
4394

4395
				for ( i = 0, il = value.length; i < il; i ++ ) {
A
alteredq 已提交
4396

4397
					offset = i * 3;
4398

4399 4400 4401
					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;
					uniform._array[ offset + 2 ] = value[ i ].z;
4402

4403
				}
4404

4405
				_gl.uniform3fv( location, uniform._array );
4406

4407
			// single THREE.Matrix4
4408

4409
			} else if( type === "m4" ) {
M
Mr.doob 已提交
4410

4411
				if ( ! uniform._array ) {
A
alteredq 已提交
4412

4413
					uniform._array = new Float32Array( 16 );
4414

4415
				}
4416

4417 4418
				value.flattenToArray( uniform._array );
				_gl.uniformMatrix4fv( location, false, uniform._array );
4419

4420
			// array of THREE.Matrix4
4421

4422
			} else if( type === "m4v" ) {
A
alteredq 已提交
4423

4424 4425 4426
				if ( ! uniform._array ) {

					uniform._array = new Float32Array( 16 * value.length );
A
alteredq 已提交
4427

M
Mr.doob 已提交
4428
				}
M
Mr.doob 已提交
4429

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

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

4434
				}
A
alteredq 已提交
4435

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

4438

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

4441
			} else if( type === "t" ) {
A
alteredq 已提交
4442

4443
				_gl.uniform1i( location, value );
4444

4445
				texture = uniform.texture;
A
alteredq 已提交
4446

4447
				if ( !texture ) continue;
A
alteredq 已提交
4448

4449
				if ( texture.image instanceof Array && texture.image.length === 6 ) {
A
alteredq 已提交
4450

4451
					setCubeTexture( texture, value );
A
alteredq 已提交
4452

4453
				} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
M
Mr.doob 已提交
4454

4455 4456 4457 4458
					setCubeTextureDynamic( texture, value );

				} else {

4459
					_this.setTexture( texture, value );
4460

M
Mr.doob 已提交
4461
				}
M
Mr.doob 已提交
4462

4463
			// array of THREE.Texture (2d)
M
Mr.doob 已提交
4464

4465
			} else if( type === "tv" ) {
M
Mr.doob 已提交
4466

4467
				if ( ! uniform._array ) {
M
Mr.doob 已提交
4468

4469
					uniform._array = [];
A
alteredq 已提交
4470

4471 4472 4473 4474 4475
					for( i = 0, il = uniform.texture.length; i < il; i ++ ) {

						uniform._array[ i ] = value + i;

					}
A
alteredq 已提交
4476

M
Mr.doob 已提交
4477
				}
A
alteredq 已提交
4478

4479
				_gl.uniform1iv( location, uniform._array );
A
alteredq 已提交
4480

4481
				for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
4482

4483
					texture = uniform.texture[ i ];
4484

4485
					if ( !texture ) continue;
M
Mr.doob 已提交
4486

4487
					_this.setTexture( texture, uniform._array[ i ] );
M
Mr.doob 已提交
4488

M
Mr.doob 已提交
4489
				}
M
Mr.doob 已提交
4490

M
Mr.doob 已提交
4491
			}
M
Mr.doob 已提交
4492

M
Mr.doob 已提交
4493
		}
M
Mr.doob 已提交
4494

4495
	};
M
Mr.doob 已提交
4496

A
alteredq 已提交
4497
	function setupMatrices ( object, camera ) {
M
Mr.doob 已提交
4498

4499
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
M
Mr.doob 已提交
4500

A
alteredq 已提交
4501
		THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
M
Mr.doob 已提交
4502

A
alteredq 已提交
4503
	};
M
Mr.doob 已提交
4504

4505
	function setupLights ( program, lights ) {
M
Mr.doob 已提交
4506

4507 4508 4509
		var l, ll, light, n,
		r = 0, g = 0, b = 0,
		color, position, intensity, distance,
M
Mr.doob 已提交
4510

4511
		zlights = _lights,
A
alteredq 已提交
4512

4513 4514
		dcolors = zlights.directional.colors,
		dpositions = zlights.directional.positions,
A
alteredq 已提交
4515

4516 4517 4518
		pcolors = zlights.point.colors,
		ppositions = zlights.point.positions,
		pdistances = zlights.point.distances,
4519

4520 4521
		dlength = 0,
		plength = 0,
4522

4523 4524
		doffset = 0,
		poffset = 0;
4525

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

4528 4529
			light = lights[ l ];
			color = light.color;
A
alteredq 已提交
4530

4531 4532 4533
			position = light.position;
			intensity = light.intensity;
			distance = light.distance;
A
alteredq 已提交
4534

4535
			if ( light instanceof THREE.AmbientLight ) {
4536

4537
				if ( _this.gammaInput ) {
4538

4539 4540 4541
					r += color.r * color.r;
					g += color.g * color.g;
					b += color.b * color.b;
4542

4543
				} else {
4544

4545 4546 4547
					r += color.r;
					g += color.g;
					b += color.b;
4548

4549
				}
4550

4551
			} else if ( light instanceof THREE.DirectionalLight ) {
4552

4553
				doffset = dlength * 3;
4554

4555
				if ( _this.gammaInput ) {
4556

4557 4558 4559
					dcolors[ doffset ]     = color.r * color.r * intensity * intensity;
					dcolors[ doffset + 1 ] = color.g * color.g * intensity * intensity;
					dcolors[ doffset + 2 ] = color.b * color.b * intensity * intensity;
4560

4561
				} else {
4562

4563 4564 4565
					dcolors[ doffset ]     = color.r * intensity;
					dcolors[ doffset + 1 ] = color.g * intensity;
					dcolors[ doffset + 2 ] = color.b * intensity;
A
alteredq 已提交
4566

4567
				}
A
alteredq 已提交
4568

4569 4570 4571
				dpositions[ doffset ]     = position.x;
				dpositions[ doffset + 1 ] = position.y;
				dpositions[ doffset + 2 ] = position.z;
A
alteredq 已提交
4572

4573
				dlength += 1;
A
alteredq 已提交
4574

4575
			} else if ( light instanceof THREE.SpotLight ) { // hack, not a proper spotlight
A
alteredq 已提交
4576

4577
				doffset = dlength * 3;
A
alteredq 已提交
4578

4579
				if ( _this.gammaInput ) {
4580

4581 4582 4583
					dcolors[ doffset ]     = color.r * color.r * intensity * intensity;
					dcolors[ doffset + 1 ] = color.g * color.g * intensity * intensity;
					dcolors[ doffset + 2 ] = color.b * color.b * intensity * intensity;
4584

4585
				} else {
A
alteredq 已提交
4586

4587 4588 4589
					dcolors[ doffset ]     = color.r * intensity;
					dcolors[ doffset + 1 ] = color.g * intensity;
					dcolors[ doffset + 2 ] = color.b * intensity;
A
alteredq 已提交
4590 4591 4592

				}

4593
				n = 1 / position.length();
A
alteredq 已提交
4594

4595 4596 4597
				dpositions[ doffset ]     = position.x * n;
				dpositions[ doffset + 1 ] = position.y * n;
				dpositions[ doffset + 2 ] = position.z * n;
M
Mr.doob 已提交
4598

4599
				dlength += 1;
4600

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

4603
				poffset = plength * 3;
M
Mr.doob 已提交
4604

4605
				if ( _this.gammaInput ) {
4606

4607 4608 4609
					pcolors[ poffset ]     = color.r * color.r * intensity * intensity;
					pcolors[ poffset + 1 ] = color.g * color.g * intensity * intensity;
					pcolors[ poffset + 2 ] = color.b * color.b * intensity * intensity;
A
alteredq 已提交
4610

4611
				} else {
A
alteredq 已提交
4612

4613 4614 4615
					pcolors[ poffset ]     = color.r * intensity;
					pcolors[ poffset + 1 ] = color.g * intensity;
					pcolors[ poffset + 2 ] = color.b * intensity;
A
alteredq 已提交
4616

4617
				}
A
alteredq 已提交
4618

4619 4620 4621
				ppositions[ poffset ]     = position.x;
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
A
alteredq 已提交
4622

4623
				pdistances[ plength ] = distance;
A
alteredq 已提交
4624

4625
				plength += 1;
4626

4627
			}
4628

4629
		}
A
alteredq 已提交
4630

4631 4632
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
A
alteredq 已提交
4633

4634 4635
		for ( l = dlength * 3, ll = dcolors.length; l < ll; l ++ ) dcolors[ l ] = 0.0;
		for ( l = plength * 3, ll = pcolors.length; l < ll; l ++ ) pcolors[ l ] = 0.0;
A
alteredq 已提交
4636

4637 4638
		zlights.point.length = plength;
		zlights.directional.length = dlength;
A
alteredq 已提交
4639

4640 4641 4642
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
4643

4644
	};
M
Mr.doob 已提交
4645

4646
	// GL state setting
M
Mr.doob 已提交
4647

4648
	this.setFaceCulling = function ( cullFace, frontFace ) {
M
Mr.doob 已提交
4649

4650
		if ( cullFace ) {
M
Mr.doob 已提交
4651

4652
			if ( !frontFace || frontFace === "ccw" ) {
4653

4654
				_gl.frontFace( _gl.CCW );
4655

4656
			} else {
4657

4658
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
4659

4660
			}
M
Mr.doob 已提交
4661

4662
			if( cullFace === "back" ) {
4663

4664
				_gl.cullFace( _gl.BACK );
4665

4666
			} else if( cullFace === "front" ) {
4667

4668
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
4669

4670
			} else {
4671

4672
				_gl.cullFace( _gl.FRONT_AND_BACK );
4673

4674
			}
4675

4676
			_gl.enable( _gl.CULL_FACE );
4677

4678
		} else {
4679

4680
			_gl.disable( _gl.CULL_FACE );
4681 4682 4683 4684 4685

		}

	};

A
alteredq 已提交
4686
	this.setObjectFaces = function ( object ) {
4687

4688
		if ( _oldDoubleSided !== object.doubleSided ) {
M
Mr.doob 已提交
4689

4690
			if( object.doubleSided ) {
M
Mr.doob 已提交
4691

4692
				_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
4693

4694
			} else {
4695

4696
				_gl.enable( _gl.CULL_FACE );
4697

4698
			}
4699

4700
			_oldDoubleSided = object.doubleSided;
4701

4702
		}
4703

4704
		if ( _oldFlipSided !== object.flipSided ) {
4705

4706
			if( object.flipSided ) {
4707

4708
				_gl.frontFace( _gl.CW );
4709

4710
			} else {
4711

4712
				_gl.frontFace( _gl.CCW );
4713

4714
			}
4715

4716
			_oldFlipSided = object.flipSided;
4717

4718
		}
4719

4720
	};
4721

A
alteredq 已提交
4722
	this.setDepthTest = function ( depthTest ) {
4723

4724
		if ( _oldDepthTest !== depthTest ) {
4725

4726
			if( depthTest ) {
4727

4728
				_gl.enable( _gl.DEPTH_TEST );
4729

4730
			} else {
4731

4732
				_gl.disable( _gl.DEPTH_TEST );
4733 4734 4735

			}

4736
			_oldDepthTest = depthTest;
4737

4738
		}
4739

4740
	};
4741

A
alteredq 已提交
4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753
	function setLineWidth ( width ) {

		if ( width !== _oldLineWidth ) {

			_gl.lineWidth( width );

			_oldLineWidth = width;

		}

	};

4754
	function setDepthWrite ( depthWrite ) {
4755

4756
		if ( _oldDepthWrite !== depthWrite ) {
4757

4758 4759
			_gl.depthMask( depthWrite );
			_oldDepthWrite = depthWrite;
4760 4761 4762

		}

4763
	};
4764

4765
	function setPolygonOffset ( polygonoffset, factor, units ) {
4766

4767
		if ( _oldPolygonOffset !== polygonoffset ) {
M
Mr.doob 已提交
4768

4769
			if ( polygonoffset ) {
4770

4771
				_gl.enable( _gl.POLYGON_OFFSET_FILL );
4772

4773
			} else {
4774

4775
				_gl.disable( _gl.POLYGON_OFFSET_FILL );
4776

4777
			}
4778

4779
			_oldPolygonOffset = polygonoffset;
4780

4781
		}
4782

4783
		if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
4784

4785
			_gl.polygonOffset( factor, units );
M
Mr.doob 已提交
4786

4787 4788
			_oldPolygonOffsetFactor = factor;
			_oldPolygonOffsetUnits = units;
M
Mr.doob 已提交
4789

4790
		}
M
Mr.doob 已提交
4791

4792
	};
M
Mr.doob 已提交
4793

4794
	this.setBlending = function ( blending ) {
M
Mr.doob 已提交
4795

4796
		if ( blending !== _oldBlending ) {
M
Mr.doob 已提交
4797

4798
			switch ( blending ) {
M
Mr.doob 已提交
4799

4800
				case THREE.AdditiveBlending:
M
Mr.doob 已提交
4801

4802 4803
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
M
Mr.doob 已提交
4804

4805
					break;
M
Mr.doob 已提交
4806

4807
				case THREE.SubtractiveBlending:
M
Mr.doob 已提交
4808

4809
					// TODO: Find blendFuncSeparate() combination
M
Mr.doob 已提交
4810

4811 4812
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
M
Mr.doob 已提交
4813

4814
					break;
M
Mr.doob 已提交
4815

4816
				case THREE.MultiplyBlending:
M
Mr.doob 已提交
4817

4818
					// TODO: Find blendFuncSeparate() combination
M
Mr.doob 已提交
4819

4820 4821
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
M
Mr.doob 已提交
4822

4823
					break;
4824

4825
				default:
N
Nicolas Garcia Belmonte 已提交
4826

4827 4828
					_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 );
4829

4830
					break;
4831

4832
			}
4833

4834
			_oldBlending = blending;
4835

4836
		}
4837 4838

	};
4839

4840 4841 4842
	// Shaders

	function buildProgram ( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
4843

4844
		var p, pl, program, code;
4845
		var chunks = [];
4846 4847 4848

		// Generate code

4849 4850 4851 4852 4853 4854 4855 4856 4857 4858
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

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

		}
4859 4860 4861

		for ( p in parameters ) {

4862 4863
			chunks.push( p );
			chunks.push( parameters[ p ] );
4864 4865 4866

		}

4867 4868
		code = chunks.join();

4869 4870 4871 4872
		// Check if code has been already compiled

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

4873
			if ( _programs[ p ].code === code ) {
4874 4875

				// console.log( "Code already compiled." /*: \n\n" + code*/ );
4876

4877 4878 4879 4880 4881
				return _programs[ p ].program;

			}

		}
4882

4883
		//console.log( "building new program " );
4884 4885 4886

		//

4887
		program = _gl.createProgram();
M
Mr.doob 已提交
4888

4889
		var prefix_vertex = [
M
Mr.doob 已提交
4890

A
alteredq 已提交
4891
			_supportsVertexTextures ? "#define VERTEX_TEXTURES" : "",
4892

4893 4894 4895 4896
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

4897 4898 4899
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

4900 4901
			"#define MAX_SHADOWS " + parameters.maxShadows,

4902 4903
			"#define MAX_BONES " + parameters.maxBones,

4904
			parameters.map ? "#define USE_MAP" : "",
4905 4906 4907
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
4908
			parameters.skinning ? "#define USE_SKINNING" : "",
4909
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
A
alteredq 已提交
4910
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
4911

4912
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
4913
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
4914

4915 4916
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
4917 4918 4919
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
4920 4921
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
4922
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
4923 4924 4925

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
4926 4927 4928
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
4929
			"attribute vec2 uv2;",
4930

4931
			"#ifdef USE_COLOR",
4932

4933
				"attribute vec3 color;",
4934

4935 4936
			"#endif",

4937
			"#ifdef USE_MORPHTARGETS",
4938

4939 4940 4941 4942 4943 4944 4945 4946
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
				"attribute vec3 morphTarget4;",
				"attribute vec3 morphTarget5;",
				"attribute vec3 morphTarget6;",
				"attribute vec3 morphTarget7;",
4947

4948 4949 4950
			"#endif",

			"#ifdef USE_SKINNING",
4951

4952 4953 4954 4955
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
4956

4957
			"#endif",
4958

M
Mr.doob 已提交
4959
			""
A
alteredq 已提交
4960

M
Mr.doob 已提交
4961
		].join("\n");
4962

M
Mr.doob 已提交
4963 4964 4965
		var prefix_fragment = [

			"#ifdef GL_ES",
4966
			"precision " + _precision + " float;",
M
Mr.doob 已提交
4967 4968 4969 4970 4971
			"#endif",

			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

4972 4973
			"#define MAX_SHADOWS " + parameters.maxShadows,

4974 4975
			parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",

4976 4977 4978 4979
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

M
Mr.doob 已提交
4980 4981
			( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
			( parameters.useFog && parameters.fog instanceof THREE.FogExp2 ) ? "#define FOG_EXP2" : "",
M
Mr.doob 已提交
4982 4983 4984 4985 4986

			parameters.map ? "#define USE_MAP" : "",
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
4987

4988 4989 4990
			parameters.metal ? "#define METAL" : "",
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",

4991
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
4992 4993 4994
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
			parameters.shadowMapSoft ? "#define SHADOWMAP_WIDTH " + parameters.shadowMapWidth.toFixed( 1 ) : "",
			parameters.shadowMapSoft ? "#define SHADOWMAP_HEIGHT " + parameters.shadowMapHeight.toFixed( 1 ) : "",
M
Mr.doob 已提交
4995 4996 4997 4998 4999 5000 5001

			"uniform mat4 viewMatrix;",
			"uniform vec3 cameraPosition;",
			""

		].join("\n");

5002 5003
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
5004

M
Mr.doob 已提交
5005
		_gl.linkProgram( program );
N
Nicolas Garcia Belmonte 已提交
5006

M
Mr.doob 已提交
5007
		if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
N
Nicolas Garcia Belmonte 已提交
5008

5009
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
5010

N
Nicolas Garcia Belmonte 已提交
5011
		}
5012

5013 5014
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
5015

M
Mr.doob 已提交
5016
		program.uniforms = {};
5017
		program.attributes = {};
M
Mr.doob 已提交
5018

5019 5020 5021 5022
		var identifiers, u, a, i;

		// cache uniform locations

5023
		identifiers = [
5024

5025 5026
			'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
			'cameraInverseMatrix', 'boneGlobalMatrices', 'morphTargetInfluences'
M
Mr.doob 已提交
5027

5028
		];
M
Mr.doob 已提交
5029

5030
		for ( u in uniforms ) {
M
Mr.doob 已提交
5031

5032
			identifiers.push( u );
M
Mr.doob 已提交
5033

5034
		}
M
Mr.doob 已提交
5035

5036
		cacheUniformLocations( program, identifiers );
M
Mr.doob 已提交
5037

5038
		// cache attributes locations
M
Mr.doob 已提交
5039

5040
		identifiers = [
A
alteredq 已提交
5041

5042 5043
			"position", "normal", "uv", "uv2", "tangent", "color",
			"skinVertexA", "skinVertexB", "skinIndex", "skinWeight"
A
alteredq 已提交
5044

5045
		];
M
Mr.doob 已提交
5046

5047
		for ( i = 0; i < parameters.maxMorphTargets; i ++ ) {
M
Mr.doob 已提交
5048

5049
			identifiers.push( "morphTarget" + i );
M
Mr.doob 已提交
5050

5051
		}
5052

5053
		for ( a in attributes ) {
5054

5055
			identifiers.push( a );
5056

5057
		}
5058

5059
		cacheAttributeLocations( program, identifiers );
5060

5061
		program.id = _programs.length;
5062

5063
		_programs.push( { program: program, code: code } );
5064

5065
		_this.info.memory.programs = _programs.length;
5066

5067
		return program;
5068

5069
	};
5070

5071
	// Shader parameters cache
5072

5073
	function cacheUniformLocations ( program, identifiers ) {
5074

5075
		var i, l, id;
5076

5077
		for( i = 0, l = identifiers.length; i < l; i++ ) {
5078

5079 5080
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
5081

5082
		}
M
Mr.doob 已提交
5083

5084
	};
M
Mr.doob 已提交
5085

5086
	function cacheAttributeLocations ( program, identifiers ) {
A
alteredq 已提交
5087

5088
		var i, l, id;
A
alteredq 已提交
5089

5090
		for( i = 0, l = identifiers.length; i < l; i++ ) {
A
alteredq 已提交
5091

5092 5093
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
A
alteredq 已提交
5094

5095
		}
5096

5097
	};
A
alteredq 已提交
5098

5099
	function getShader ( type, string ) {
A
alteredq 已提交
5100

5101
		var shader;
5102

5103
		if ( type === "fragment" ) {
A
alteredq 已提交
5104

5105
			shader = _gl.createShader( _gl.FRAGMENT_SHADER );
A
alteredq 已提交
5106

5107
		} else if ( type === "vertex" ) {
A
alteredq 已提交
5108

5109
			shader = _gl.createShader( _gl.VERTEX_SHADER );
A
alteredq 已提交
5110

5111
		}
A
alteredq 已提交
5112

5113 5114
		_gl.shaderSource( shader, string );
		_gl.compileShader( shader );
5115

5116
		if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {
5117

5118 5119 5120
			console.error( _gl.getShaderInfoLog( shader ) );
			console.error( string );
			return null;
5121

A
alteredq 已提交
5122 5123
		}

5124 5125
		return shader;

A
alteredq 已提交
5126
	};
5127

5128 5129
	// Textures

5130 5131 5132 5133 5134 5135 5136

	function isPowerOfTwo ( value ) {

		return ( value & ( value - 1 ) ) === 0;

	};

5137
	function setTextureParameters ( textureType, texture, image ) {
5138

5139
		if ( isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ) ) {
M
Mr.doob 已提交
5140

5141 5142
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
5143

5144 5145
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
5146

5147
			return true;
M
Mr.doob 已提交
5148

5149
		} else {
M
Mr.doob 已提交
5150

5151 5152
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
5153

5154 5155
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
5156

5157 5158
			return false;

5159
		}
M
Mr.doob 已提交
5160

5161
	};
5162

5163
	this.setTexture = function ( texture, slot ) {
5164

5165
		if ( texture.needsUpdate ) {
A
alteredq 已提交
5166

5167
			if ( ! texture.__webglInit ) {
M
Mr.doob 已提交
5168

5169
				texture.__webglInit = true;
5170
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5171

M
Mr.doob 已提交
5172 5173
				_this.info.memory.textures ++;

5174
			}
M
Mr.doob 已提交
5175

5176
			_gl.activeTexture( _gl.TEXTURE0 + slot );
5177 5178
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );

5179 5180
			var needsMipMaps = setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );

5181
			if ( texture instanceof THREE.DataTexture ) {
5182 5183

				_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( texture.format ), texture.image.width, texture.image.height, 0, paramThreeToGL( texture.format ), _gl.UNSIGNED_BYTE, texture.image.data );
M
Mr.doob 已提交
5184

A
alteredq 已提交
5185
			} else {
M
Mr.doob 已提交
5186

M
Mr.doob 已提交
5187
				_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
5188 5189 5190

			}

5191 5192 5193 5194 5195
			if ( needsMipMaps ) {

				_gl.generateMipmap( _gl.TEXTURE_2D );

			}
M
Mr.doob 已提交
5196

A
alteredq 已提交
5197
			texture.needsUpdate = false;
5198

5199 5200
			if ( texture.onUpdated ) texture.onUpdated();

5201
		} else {
5202

5203 5204
			_gl.activeTexture( _gl.TEXTURE0 + slot );
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
5205 5206

		}
M
Mr.doob 已提交
5207

5208
	};
M
Mr.doob 已提交
5209

5210
	function setCubeTexture ( texture, slot ) {
5211

5212
		if ( texture.image.length === 6 ) {
5213 5214 5215

			if ( texture.needsUpdate ) {

A
alteredq 已提交
5216
				if ( ! texture.image.__webglTextureCube ) {
5217 5218

					texture.image.__webglTextureCube = _gl.createTexture();
5219

A
alteredq 已提交
5220
				}
5221

A
alteredq 已提交
5222 5223
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5224

5225 5226
				var needsMipMaps = setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[ 0 ] );

A
alteredq 已提交
5227
				for ( var i = 0; i < 6; i ++ ) {
5228

A
alteredq 已提交
5229
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
5230

A
alteredq 已提交
5231
				}
5232

5233 5234 5235 5236 5237
				if ( needsMipMaps ) {

					_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

				}
5238

A
alteredq 已提交
5239
				texture.needsUpdate = false;
5240

A
alteredq 已提交
5241
			} else {
5242

A
alteredq 已提交
5243 5244
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5245

A
alteredq 已提交
5246
			}
5247

A
alteredq 已提交
5248
		}
5249

A
alteredq 已提交
5250
	};
5251

5252
	function setCubeTextureDynamic ( texture, slot ) {
5253

A
alteredq 已提交
5254 5255
		_gl.activeTexture( _gl.TEXTURE0 + slot );
		_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
5256 5257 5258

	};

5259 5260 5261
	// Render targets

	function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
5262

5263 5264
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
A
alteredq 已提交
5265

5266
	};
M
Mr.doob 已提交
5267

5268
	function setupRenderBuffer ( renderbuffer, renderTarget  ) {
M
Mikael Emtinger 已提交
5269

5270
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
5271

5272
		if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
M
Mr.doob 已提交
5273

5274 5275
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5276

5277 5278
		/* For some reason this is not working. Defaulting to RGBA4.
		} else if( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
A
alteredq 已提交
5279

5280 5281 5282 5283
			_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 已提交
5284

5285 5286
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5287

5288
		} else {
A
alteredq 已提交
5289

5290
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
A
alteredq 已提交
5291

5292
		}
A
alteredq 已提交
5293

5294
	};
A
alteredq 已提交
5295

A
alteredq 已提交
5296
	this.setRenderTarget = function ( renderTarget ) {
A
alteredq 已提交
5297

5298
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
A
alteredq 已提交
5299

5300
		if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
A
alteredq 已提交
5301

5302 5303
			if( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
			if( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
A
alteredq 已提交
5304

5305
			renderTarget.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5306

5307
			// Setup texture, create render and frame buffers
5308

5309
			if ( isCube ) {
M
Mr.doob 已提交
5310

5311 5312
				renderTarget.__webglFramebuffer = [];
				renderTarget.__webglRenderbuffer = [];
M
Mikael Emtinger 已提交
5313

5314 5315
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, renderTarget );
A
alteredq 已提交
5316

5317
				for ( var i = 0; i < 6; i ++ ) {
A
alteredq 已提交
5318

5319 5320
					renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
					renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
A
alteredq 已提交
5321

5322
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, paramThreeToGL( renderTarget.format ), renderTarget.width, renderTarget.height, 0, paramThreeToGL( renderTarget.format ), paramThreeToGL( renderTarget.type ), null );
A
alteredq 已提交
5323

5324 5325
					setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
					setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
A
alteredq 已提交
5326

5327
				}
5328

5329
			} else {
5330

5331 5332
				renderTarget.__webglFramebuffer = _gl.createFramebuffer();
				renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
5333

5334 5335
				_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
				setTextureParameters( _gl.TEXTURE_2D, renderTarget, renderTarget );
5336

5337
				_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTarget.format ), renderTarget.width, renderTarget.height, 0, paramThreeToGL( renderTarget.format ), paramThreeToGL( renderTarget.type ), null );
5338

5339 5340
				setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
				setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
5341

M
Mikael Emtinger 已提交
5342
			}
5343

5344
			// Release everything
M
Mr.doob 已提交
5345

A
alteredq 已提交
5346 5347 5348 5349 5350 5351 5352 5353 5354 5355
			if ( isCube ) {

				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

			} else {

				_gl.bindTexture( _gl.TEXTURE_2D, null );

			}

5356 5357
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
5358

5359 5360
		}

5361
		var framebuffer, width, height, vx, vy;
M
Mr.doob 已提交
5362

5363
		if ( renderTarget ) {
M
Mr.doob 已提交
5364

A
alteredq 已提交
5365 5366
			if ( isCube ) {

5367
				framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
A
alteredq 已提交
5368 5369 5370

			} else {

5371
				framebuffer = renderTarget.__webglFramebuffer;
A
alteredq 已提交
5372 5373 5374

			}

5375 5376
			width = renderTarget.width;
			height = renderTarget.height;
M
Mr.doob 已提交
5377

5378 5379 5380
			vx = 0;
			vy = 0;

5381
		} else {
M
Mr.doob 已提交
5382

5383
			framebuffer = null;
5384

5385 5386
			width = _viewportWidth;
			height = _viewportHeight;
5387

5388 5389
			vx = _viewportX;
			vy = _viewportY;
M
Mr.doob 已提交
5390

5391
		}
M
Mr.doob 已提交
5392

5393
		if ( framebuffer !== _currentFramebuffer ) {
M
Mr.doob 已提交
5394

5395
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
5396
			_gl.viewport( vx, vy, width, height );
M
Mr.doob 已提交
5397

5398
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
5399

5400
		}
5401

5402
	};
M
Mr.doob 已提交
5403

5404
	function updateRenderTargetMipmap ( renderTarget ) {
M
Mr.doob 已提交
5405

A
alteredq 已提交
5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418
		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 已提交
5419 5420

	};
5421

5422
	// Fallback filters for non-power-of-2 textures
5423

5424
	function filterFallback ( f ) {
5425

5426 5427 5428 5429 5430 5431 5432 5433
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mr.doob 已提交
5434
			case THREE.LinearMipMapLinearFilter:
M
Mikael Emtinger 已提交
5435
			default:
5436

M
Mikael Emtinger 已提交
5437
				return _gl.LINEAR; break;
5438 5439

		}
5440

5441
	};
5442

5443 5444
	// Map three.js constants to WebGL constants

5445
	function paramThreeToGL ( p ) {
M
Mr.doob 已提交
5446

5447
		switch ( p ) {
M
Mr.doob 已提交
5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460

			case THREE.RepeatWrapping: return _gl.REPEAT; break;
			case THREE.ClampToEdgeWrapping: return _gl.CLAMP_TO_EDGE; break;
			case THREE.MirroredRepeatWrapping: return _gl.MIRRORED_REPEAT; break;

			case THREE.NearestFilter: return _gl.NEAREST; break;
			case THREE.NearestMipMapNearestFilter: return _gl.NEAREST_MIPMAP_NEAREST; break;
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST_MIPMAP_LINEAR; break;

			case THREE.LinearFilter: return _gl.LINEAR; break;
			case THREE.LinearMipMapNearestFilter: return _gl.LINEAR_MIPMAP_NEAREST; break;
			case THREE.LinearMipMapLinearFilter: return _gl.LINEAR_MIPMAP_LINEAR; break;

5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474
			case THREE.ByteType: return _gl.BYTE; break;
			case THREE.UnsignedByteType: return _gl.UNSIGNED_BYTE; break;
			case THREE.ShortType: return _gl.SHORT; break;
			case THREE.UnsignedShortType: return _gl.UNSIGNED_SHORT; break;
			case THREE.IntType: return _gl.INT; break;
			case THREE.UnsignedShortType: return _gl.UNSIGNED_INT; break;
			case THREE.FloatType: return _gl.FLOAT; break;

			case THREE.AlphaFormat: return _gl.ALPHA; break;
			case THREE.RGBFormat: return _gl.RGB; break;
			case THREE.RGBAFormat: return _gl.RGBA; break;
			case THREE.LuminanceFormat: return _gl.LUMINANCE; break;
			case THREE.LuminanceAlphaFormat: return _gl.LUMINANCE_ALPHA; break;

5475
		}
M
Mr.doob 已提交
5476

5477
		return 0;
M
Mr.doob 已提交
5478

5479 5480
	};

5481
	// Allocations
5482

5483
	function allocateBones ( object ) {
5484

5485 5486 5487 5488 5489 5490 5491
		// 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)
5492

5493
		var maxBones = 50;
5494

5495
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
5496

5497 5498 5499 5500 5501
			maxBones = object.bones.length;

		}

		return maxBones;
5502

5503
	};
5504

5505
	function allocateLights ( lights ) {
5506

5507 5508
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
5509

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

5512
			light = lights[ l ];
5513

5514 5515 5516
			if ( light instanceof THREE.SpotLight ) dirLights ++; // hack, not a proper spotlight
			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
			if ( light instanceof THREE.PointLight ) pointLights ++;
5517

5518
		}
5519

5520
		if ( ( pointLights + dirLights ) <= _maxLights ) {
5521

5522 5523
			maxDirLights = dirLights;
			maxPointLights = pointLights;
5524

5525
		} else {
5526

5527 5528
			maxDirLights = Math.ceil( _maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = _maxLights - maxDirLights;
5529 5530 5531

		}

5532
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
5533 5534

	};
M
Mr.doob 已提交
5535

5536
	function allocateShadows ( lights ) {
5537

M
Mr.doob 已提交
5538
		var l, ll, light, maxShadows = 0;
5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551

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

			light = lights[ l ];

			if ( light instanceof THREE.SpotLight && light.castShadow ) maxShadows ++;

		}

		return maxShadows;

	};

5552
	function maxVertexTextures () {
5553

5554 5555 5556
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
M
Mr.doob 已提交
5557

5558
	// Initialization
M
Mr.doob 已提交
5559

5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610
	function initGL () {

		var gl;

		try {

			if ( ! ( gl = _canvas.getContext( 'experimental-webgl', { antialias: _antialias, stencil: _stencil, preserveDrawingBuffer: _preserveDrawingBuffer } ) ) ) {

				throw 'Error creating WebGL context.';

			}

			console.log(
				navigator.userAgent + " | " +
				gl.getParameter( gl.VERSION ) + " | " +
				gl.getParameter( gl.VENDOR ) + " | " +
				gl.getParameter( gl.RENDERER ) + " | " +
				gl.getParameter( gl.SHADING_LANGUAGE_VERSION )
			);

		} catch ( error ) {

			console.error( error );

		}

		return gl;

	};

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

	};

5611 5612
	// default plugins (order is important)

A
alteredq 已提交
5613 5614 5615 5616 5617
	this.shadowMapPlugin = new THREE.ShadowMapPlugin();
	this.addPrePlugin( this.shadowMapPlugin );

	this.addPostPlugin( new THREE.SpritePlugin() );
	this.addPostPlugin( new THREE.LensFlarePlugin() );
5618

5619
};