WebGLRenderer.js 141.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
	parameters = parameters || {};
M
Mr.doob 已提交
13

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

M
Mr.doob 已提交
16
	_precision = parameters.precision !== undefined ? parameters.precision : 'mediump',
17

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

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

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

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

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

	// clearing
M
Mr.doob 已提交
35

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

41 42
	// scene graph

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

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

	// physically based shading

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

54 55 56
	// shadow map

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

63
	// morphs
64

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

68 69 70 71
	// flags

	this.autoScaleCubemaps = true;

72 73
	// custom render plugins

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

77
	// info
78

79
	this.info = {
80

81
		memory: {
82

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

87
		},
88

89
		render: {
90

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

		}

98
	};
M
Mr.doob 已提交
99

100
	// internal properties
101

102
	var _this = this,
103

104
	_gl,
105

106
	_programs = [],
107

108
	// internal state cache
109

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

117
	// GL state cache
118

119 120 121 122 123 124 125 126 127
	_oldDoubleSided = null,
	_oldFlipSided = null,
	_oldBlending = null,
	_oldDepthTest = null,
	_oldDepthWrite = null,
	_oldPolygonOffset = null,
	_oldPolygonOffsetFactor = null,
	_oldPolygonOffsetUnits = null,
	_oldLineWidth = null,
128

129 130 131 132
	_viewportX = 0,
	_viewportY = 0,
	_viewportWidth = 0,
	_viewportHeight = 0,
A
alteredq 已提交
133 134
	_currentWidth = 0,
	_currentHeight = 0,
135

A
alteredq 已提交
136
	// frustum
M
Mr.doob 已提交
137

A
alteredq 已提交
138
	_frustum = new THREE.Frustum(),
139

140
	 // camera matrices cache
M
Mikael Emtinger 已提交
141

142
	_projScreenMatrix = new THREE.Matrix4(),
M
Mr.doob 已提交
143

144
	_vector3 = new THREE.Vector4(),
M
Mikael Emtinger 已提交
145

146
	// light arrays cache
M
Mikael Emtinger 已提交
147

148 149
	_direction = new THREE.Vector3(),

150
	_lights = {
M
Mr.doob 已提交
151

152 153 154
		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 已提交
155

156
	};
M
Mr.doob 已提交
157

158
	// initialize
M
Mikael Emtinger 已提交
159

160
	_gl = initGL();
M
Mikael Emtinger 已提交
161

162
	setDefaultGLState();
M
Mikael Emtinger 已提交
163

164
	this.context = _gl;
M
Mikael Emtinger 已提交
165

166 167 168
	// GPU capabilities

	var _maxVertexTextures = _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ),
A
alteredq 已提交
169
	_maxTextureSize = _gl.getParameter( _gl.MAX_TEXTURE_SIZE ),
170
	_maxCubemapSize = _gl.getParameter( _gl.MAX_CUBE_MAP_TEXTURE_SIZE );
M
Mr.doob 已提交
171

172
	// API
M
Mr.doob 已提交
173

174
	this.getContext = function () {
M
Mr.doob 已提交
175

176
		return _gl;
M
Mr.doob 已提交
177

178
	};
M
Mr.doob 已提交
179

180
	this.supportsVertexTextures = function () {
M
Mikael Emtinger 已提交
181

182
		return _maxVertexTextures > 0;
M
Mikael Emtinger 已提交
183

184
	};
M
Mikael Emtinger 已提交
185

N
Nicolas Garcia Belmonte 已提交
186 187 188 189
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
190

191 192 193
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
194

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

197 198
		_viewportX = x;
		_viewportY = y;
199

200 201
		_viewportWidth = width;
		_viewportHeight = height;
202

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

N
Nicolas Garcia Belmonte 已提交
205
	};
206

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

209
		_gl.scissor( x, y, width, height );
210

211
	};
212

213
	this.enableScissorTest = function ( enable ) {
214

M
Mr.doob 已提交
215
		enable ? _gl.enable( _gl.SCISSOR_TEST ) : _gl.disable( _gl.SCISSOR_TEST );
216 217

	};
218

219 220
	// Clearing

221
	this.setClearColorHex = function ( hex, alpha ) {
222

223 224 225 226
		_clearColor.setHex( hex );
		_clearAlpha = alpha;

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

228
	};
A
alteredq 已提交
229

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

232 233 234 235
		_clearColor.copy( color );
		_clearAlpha = alpha;

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

	};
238

M
Mr.doob 已提交
239 240 241 242 243 244 245
	this.getClearColor = function () {

		return _clearColor;

	};

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

M
Mr.doob 已提交
247 248 249 250 251 252 253 254
		return _clearAlpha;

	};

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

		var bits = 0;

255 256 257
		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 已提交
258 259

		_gl.clear( bits );
N
Nicolas Garcia Belmonte 已提交
260 261 262

	};

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

A
alteredq 已提交
265
		this.setRenderTarget( renderTarget );
266
		this.clear( color, depth, stencil );
M
Mr.doob 已提交
267 268 269

	};

270 271
	// Plugins

A
alteredq 已提交
272
	this.addPostPlugin = function ( plugin ) {
273 274

		plugin.init( this );
A
alteredq 已提交
275
		this.renderPluginsPost.push( plugin );
276 277 278

	};

A
alteredq 已提交
279 280 281 282 283 284
	this.addPrePlugin = function ( plugin ) {

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

	};
285

286 287
	// Deallocation

288 289 290 291 292 293 294 295 296 297 298 299 300 301
	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 ) {

302
			for ( var g in object.geometry.geometryGroups ) {
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330

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

333 334
	};

335
	// Rendering
336

337
	this.updateShadowMap = function ( scene, camera ) {
338

A
alteredq 已提交
339 340 341 342 343 344 345 346
		_currentProgram = null;
		_oldBlending = -1;
		_oldDepthTest = -1;
		_oldDepthWrite = -1;
		_currentGeometryGroupHash = -1;
		_currentMaterialId = -1;

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

348
	};
M
Mr.doob 已提交
349

350
	// Internal functions
351

352
	// Buffer allocation
353

354
	function createParticleBuffers ( geometry ) {
355

356 357
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
358

359
		_this.info.geometries ++;
360

361
	};
362

363
	function createLineBuffers ( geometry ) {
364

365 366
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
367

368
		_this.info.memory.geometries ++;
369

370
	};
371

372
	function createRibbonBuffers ( geometry ) {
373

374 375
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
376

377
		_this.info.memory.geometries ++;
M
Mr.doob 已提交
378

379
	};
380

381
	function createMeshBuffers ( geometryGroup ) {
382

383 384 385 386 387 388
		geometryGroup.__webglVertexBuffer = _gl.createBuffer();
		geometryGroup.__webglNormalBuffer = _gl.createBuffer();
		geometryGroup.__webglTangentBuffer = _gl.createBuffer();
		geometryGroup.__webglColorBuffer = _gl.createBuffer();
		geometryGroup.__webglUVBuffer = _gl.createBuffer();
		geometryGroup.__webglUV2Buffer = _gl.createBuffer();
389

390 391 392 393
		geometryGroup.__webglSkinVertexABuffer = _gl.createBuffer();
		geometryGroup.__webglSkinVertexBBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinIndicesBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinWeightsBuffer = _gl.createBuffer();
394

395 396
		geometryGroup.__webglFaceBuffer = _gl.createBuffer();
		geometryGroup.__webglLineBuffer = _gl.createBuffer();
397

398
		if ( geometryGroup.numMorphTargets ) {
399

400
			var m, ml;
401

402
			geometryGroup.__webglMorphTargetsBuffers = [];
A
alteredq 已提交
403
			geometryGroup.__webglMorphNormalsBuffers = [];
404

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

407
				geometryGroup.__webglMorphTargetsBuffers.push( _gl.createBuffer() );
A
alteredq 已提交
408
				geometryGroup.__webglMorphNormalsBuffers.push( _gl.createBuffer() );
409

410
			}
411

412
		}
413

414
		_this.info.memory.geometries ++;
415

416
	};
417

418
	// Buffer deallocation
419

420
	function deleteParticleBuffers ( geometry ) {
421

422 423
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
424

425
		_this.info.memory.geometries --;
426

427
	};
428

429
	function deleteLineBuffers ( geometry ) {
430

431 432
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
433

M
Mr.doob 已提交
434 435
		_this.info.memory.geometries --;

436 437
	};

438
	function deleteRibbonBuffers ( geometry ) {
439 440 441 442

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

M
Mr.doob 已提交
443 444
		_this.info.memory.geometries --;

445 446
	};

447
	function deleteMeshBuffers ( geometryGroup ) {
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465

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

466
			for ( var m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
467 468

				_gl.deleteBuffer( geometryGroup.__webglMorphTargetsBuffers[ m ] );
A
alteredq 已提交
469
				_gl.deleteBuffer( geometryGroup.__webglMorphNormalsBuffers[ m ] );
470 471 472 473 474

			}

		}

475 476 477 478 479 480 481 482 483 484 485

		if ( geometryGroup.__webglCustomAttributesList ) {

			for ( var id in geometryGroup.__webglCustomAttributesList ) {

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

			}

		}

M
Mr.doob 已提交
486 487
		_this.info.memory.geometries --;

488 489
	};

490
	// Buffer initialization
491

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

494 495
		var nvertices = geometry.vertices.length;

496
		var material = object.material;
497

498
		if ( material.attributes ) {
499

500
			if ( geometry.__webglCustomAttributesList === undefined ) {
501

502
				geometry.__webglCustomAttributesList = [];
503

504
			}
505

506
			for ( var a in material.attributes ) {
507

508
				var attribute = material.attributes[ a ];
509

510
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
511

512
					attribute.__webglInitialized = true;
513

A
alteredq 已提交
514
					var size = 1;		// "f" and "i"
515

516 517 518 519
					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;
520

521
					attribute.size = size;
A
alteredq 已提交
522

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

525 526
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
527

528
					attribute.needsUpdate = true;
529

530
				}
531

532
				geometry.__webglCustomAttributesList.push( attribute );
533

534
			}
535

536
		}
537

538
	};
539

540
	function initParticleBuffers ( 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 548 549
		geometry.__sortArray = [];

		geometry.__webglParticleCount = nvertices;
A
alteredq 已提交
550 551 552 553 554

		initCustomAttributes ( geometry, object );

	};

555
	function initLineBuffers ( geometry, object ) {
A
alteredq 已提交
556 557 558 559 560 561

		var nvertices = geometry.vertices.length;

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

562
		geometry.__webglLineCount = nvertices;
A
alteredq 已提交
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578

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

581 582 583
		var geometry = object.geometry,
			faces3 = geometryGroup.faces3,
			faces4 = geometryGroup.faces4,
M
Mr.doob 已提交
584

585 586 587
			nvertices = faces3.length * 3 + faces4.length * 4,
			ntris     = faces3.length * 1 + faces4.length * 2,
			nlines    = faces3.length * 3 + faces4.length * 4,
588

589
			material = getBufferMaterial( object, geometryGroup ),
590

591 592 593
			uvType = bufferGuessUVType( material ),
			normalType = bufferGuessNormalType( material ),
			vertexColorType = bufferGuessVertexColorType( material );
A
alteredq 已提交
594

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

597
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
598

599
		if ( normalType ) {
M
Mr.doob 已提交
600

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

603
		}
604

605
		if ( geometry.hasTangents ) {
606

607
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
608

609
		}
610

611
		if ( vertexColorType ) {
612

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

615
		}
M
Mr.doob 已提交
616

617
		if ( uvType ) {
618

619
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
620

621 622 623 624 625
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

627 628 629 630 631 632 633 634 635 636 637 638 639 640 641
				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 );

		}

642
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
643
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
644

645 646
		if ( geometryGroup.numMorphTargets ) {

M
Mr.doob 已提交
647
			geometryGroup.__morphTargetsArrays = [];
A
alteredq 已提交
648
			geometryGroup.__morphNormalsArrays = [];
649

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

652
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );
A
alteredq 已提交
653
				geometryGroup.__morphNormalsArrays.push( new Float32Array( nvertices * 3 ) );
654

655 656 657
			}

		}
658

659
		geometryGroup.__webglFaceCount = ntris * 3;
660
		geometryGroup.__webglLineCount = nlines * 2;
661

M
Mr.doob 已提交
662

663
		// custom attributes
M
Mr.doob 已提交
664

665
		if ( material.attributes ) {
666

667
			if ( geometryGroup.__webglCustomAttributesList === undefined ) {
668

669
				geometryGroup.__webglCustomAttributesList = [];
670

671
			}
672

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

675 676
				// Do a shallow copy of the attribute object so different geometryGroup chunks use different
				// attribute buffers which are correctly indexed in the setMeshBuffers function
677

678
				var originalAttribute = material.attributes[ a ];
679

680
				var attribute = {};
681

682
				for ( var property in originalAttribute ) {
M
Mr.doob 已提交
683

684
					attribute[ property ] = originalAttribute[ property ];
685

686
				}
687

688
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
689

690
					attribute.__webglInitialized = true;
691

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

694 695 696 697
					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;
698

699
					attribute.size = size;
A
alteredq 已提交
700

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

703 704
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
705

706 707
					originalAttribute.needsUpdate = true;
					attribute.__original = originalAttribute;
708 709 710

				}

711 712
				geometryGroup.__webglCustomAttributesList.push( attribute );

713
			}
M
Mr.doob 已提交
714

715
		}
716

717 718
		geometryGroup.__inittedArrays = true;

719
	};
M
Mr.doob 已提交
720

721
	function getBufferMaterial( object, geometryGroup ) {
722

723
		if ( object.material && ! ( object.material instanceof THREE.MeshFaceMaterial ) ) {
724

725
			return object.material;
726

727
		} else if ( geometryGroup.materialIndex >= 0 ) {
728

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

731
		}
732

733
	};
M
Mr.doob 已提交
734

735
	function materialNeedsSmoothNormals ( material ) {
736

737
		return material && material.shading !== undefined && material.shading === THREE.SmoothShading;
738

739
	};
M
Mr.doob 已提交
740

741
	function bufferGuessNormalType ( material ) {
742

743
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
744

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

747
			return false;
748

749
		}
750

751
		if ( materialNeedsSmoothNormals( material ) ) {
752

753
			return THREE.SmoothShading;
M
Mr.doob 已提交
754

755
		} else {
756

757
			return THREE.FlatShading;
758

759
		}
760

761
	};
762

763
	function bufferGuessVertexColorType ( material ) {
764

765
		if ( material.vertexColors ) {
766

767
			return material.vertexColors;
768

769
		}
M
Mr.doob 已提交
770

771
		return false;
M
Mr.doob 已提交
772

773
	};
M
Mr.doob 已提交
774

775
	function bufferGuessUVType ( material ) {
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 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320
		// 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 );

		}

	};

1321
	function setMeshBuffers( geometryGroup, object, hint, dispose, material ) {
1322 1323 1324 1325 1326 1327 1328 1329

		if ( ! geometryGroup.__inittedArrays ) {

			// console.log( object );
			return;

		}

1330 1331 1332 1333 1334 1335
		var normalType = bufferGuessNormalType( material ),
		vertexColorType = bufferGuessVertexColorType( material ),
		uvType = bufferGuessUVType( material ),

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

1336 1337 1338 1339
		var f, fl, fi, face,
		vertexNormals, faceNormal, normal,
		vertexColors, faceColor,
		vertexTangents,
A
alteredq 已提交
1340
		uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4, n1, n2, n3, n4,
1341 1342 1343 1344 1345 1346 1347 1348
		c1, c2, c3, c4,
		sw1, sw2, sw3, sw4,
		si1, si2, si3, si4,
		sa1, sa2, sa3, sa4,
		sb1, sb2, sb3, sb4,
		m, ml, i, il,
		vn, uvi, uv2i,
		vk, vkl, vka,
A
alteredq 已提交
1349
		nka, chf, faceVertexNormals,
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
		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,
A
alteredq 已提交
1382
		morphNormalsArrays = geometryGroup.__morphNormalsArrays,
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

		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,

A
alteredq 已提交
1415 1416
		morphTargets = geometry.morphTargets,
		morphNormals = geometry.morphNormals;
1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438

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

1440
				offset += 9;
M
Mr.doob 已提交
1441

1442
			}
1443

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

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

A
alteredq 已提交
1448 1449 1450 1451
				v1 = vertices[ face.a ].position;
				v2 = vertices[ face.b ].position;
				v3 = vertices[ face.c ].position;
				v4 = vertices[ face.d ].position;
1452

A
alteredq 已提交
1453 1454 1455
				vertexArray[ offset ]     = v1.x;
				vertexArray[ offset + 1 ] = v1.y;
				vertexArray[ offset + 2 ] = v1.z;
1456

A
alteredq 已提交
1457 1458 1459
				vertexArray[ offset + 3 ] = v2.x;
				vertexArray[ offset + 4 ] = v2.y;
				vertexArray[ offset + 5 ] = v2.z;
1460

A
alteredq 已提交
1461 1462 1463
				vertexArray[ offset + 6 ] = v3.x;
				vertexArray[ offset + 7 ] = v3.y;
				vertexArray[ offset + 8 ] = v3.z;
1464

A
alteredq 已提交
1465 1466 1467
				vertexArray[ offset + 9 ]  = v4.x;
				vertexArray[ offset + 10 ] = v4.y;
				vertexArray[ offset + 11 ] = v4.z;
1468

A
alteredq 已提交
1469
				offset += 12;
1470

A
alteredq 已提交
1471
			}
1472

A
alteredq 已提交
1473 1474
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1475

A
alteredq 已提交
1476
		}
M
Mr.doob 已提交
1477

A
alteredq 已提交
1478
		if ( dirtyMorphTargets ) {
M
Mr.doob 已提交
1479

1480
			for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {
1481

1482
				offset_morphTarget = 0;
1483

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

A
alteredq 已提交
1486 1487 1488 1489
					chf = chunk_faces3[ f ];
					face = obj_faces[ chf ];

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

A
alteredq 已提交
1491 1492 1493
					v1 = morphTargets[ vk ].vertices[ face.a ].position;
					v2 = morphTargets[ vk ].vertices[ face.b ].position;
					v3 = morphTargets[ vk ].vertices[ face.c ].position;
M
Mr.doob 已提交
1494

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

A
alteredq 已提交
1497 1498 1499
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
M
Mr.doob 已提交
1500

A
alteredq 已提交
1501 1502 1503
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
M
Mr.doob 已提交
1504

A
alteredq 已提交
1505 1506 1507
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
M
Mr.doob 已提交
1508

A
alteredq 已提交
1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546
					// morph normals

					if ( material.morphNormals ) {

						if ( needsSmoothNormals ) {

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

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

						} else {

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

						}

						nka = morphNormalsArrays[ vk ];

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

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

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

					}

					//

1547
					offset_morphTarget += 9;
1548

1549
				}
1550

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

A
alteredq 已提交
1553 1554 1555 1556
					chf = chunk_faces4[ f ];
					face = obj_faces[ chf ];

					// morph positions
1557

1558 1559 1560
					v1 = morphTargets[ vk ].vertices[ face.a ].position;
					v2 = morphTargets[ vk ].vertices[ face.b ].position;
					v3 = morphTargets[ vk ].vertices[ face.c ].position;
A
alteredq 已提交
1561
					v4 = morphTargets[ vk ].vertices[ face.d ].position;
1562

1563
					vka = morphTargetsArrays[ vk ];
1564

1565 1566 1567
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
1568

1569 1570 1571
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
1572

1573 1574 1575
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
1576

A
alteredq 已提交
1577 1578 1579 1580
					vka[ offset_morphTarget + 9 ]  = v4.x;
					vka[ offset_morphTarget + 10 ] = v4.y;
					vka[ offset_morphTarget + 11 ] = v4.z;

A
alteredq 已提交
1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624
					// morph normals

					if ( material.morphNormals ) {

						if ( needsSmoothNormals ) {

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

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

						} else {

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

						}

						nka = morphNormalsArrays[ vk ];

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

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

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

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

					}

					//

1625
					offset_morphTarget += 12;
A
alteredq 已提交
1626

1627
				}
A
alteredq 已提交
1628 1629 1630

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

A
alteredq 已提交
1632 1633 1634 1635 1636 1637 1638
				if ( material.morphNormals ) {

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

				}

1639
			}
1640

A
alteredq 已提交
1641 1642 1643 1644 1645 1646 1647
		}

		if ( obj_skinWeights.length ) {

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

				face = obj_faces[ chunk_faces3[ f ]	];
1648

1649
				// weights
A
alteredq 已提交
1650

1651 1652 1653
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
A
alteredq 已提交
1654

1655 1656 1657 1658
				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 已提交
1659

1660 1661 1662 1663
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1664

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

1670
				// indices
A
alteredq 已提交
1671

1672 1673 1674
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
A
alteredq 已提交
1675

1676 1677 1678 1679
				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 已提交
1680

1681 1682 1683 1684
				skinIndexArray[ offset_skin + 4 ] = si2.x;
				skinIndexArray[ offset_skin + 5 ] = si2.y;
				skinIndexArray[ offset_skin + 6 ] = si2.z;
				skinIndexArray[ offset_skin + 7 ] = si2.w;
1685

1686 1687 1688 1689
				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 已提交
1690

1691
				// vertices A
A
alteredq 已提交
1692

1693 1694 1695
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
A
alteredq 已提交
1696

1697 1698 1699 1700
				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 已提交
1701

1702 1703 1704 1705
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1706

1707 1708 1709 1710
				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 已提交
1711

1712
				// vertices B
A
alteredq 已提交
1713

1714 1715 1716
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
A
alteredq 已提交
1717

1718 1719 1720 1721
				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 已提交
1722

1723 1724 1725 1726
				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
				skinVertexBArray[ offset_skin + 7 ] = 1;
1727

1728 1729 1730 1731
				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
				skinVertexBArray[ offset_skin + 11 ] = 1;
1732

1733
				offset_skin += 12;
1734

1735
			}
1736

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

A
alteredq 已提交
1739
				face = obj_faces[ chunk_faces4[ f ] ];
1740

A
alteredq 已提交
1741
				// weights
1742

A
alteredq 已提交
1743 1744 1745 1746
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
				sw4 = obj_skinWeights[ face.d ];
1747

A
alteredq 已提交
1748 1749 1750 1751
				skinWeightArray[ offset_skin ]     = sw1.x;
				skinWeightArray[ offset_skin + 1 ] = sw1.y;
				skinWeightArray[ offset_skin + 2 ] = sw1.z;
				skinWeightArray[ offset_skin + 3 ] = sw1.w;
1752

A
alteredq 已提交
1753 1754 1755 1756
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1757

A
alteredq 已提交
1758 1759 1760 1761
				skinWeightArray[ offset_skin + 8 ]  = sw3.x;
				skinWeightArray[ offset_skin + 9 ]  = sw3.y;
				skinWeightArray[ offset_skin + 10 ] = sw3.z;
				skinWeightArray[ offset_skin + 11 ] = sw3.w;
1762

A
alteredq 已提交
1763 1764 1765 1766
				skinWeightArray[ offset_skin + 12 ] = sw4.x;
				skinWeightArray[ offset_skin + 13 ] = sw4.y;
				skinWeightArray[ offset_skin + 14 ] = sw4.z;
				skinWeightArray[ offset_skin + 15 ] = sw4.w;
1767

A
alteredq 已提交
1768
				// indices
1769

A
alteredq 已提交
1770 1771 1772 1773
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
				si4 = obj_skinIndices[ face.d ];
1774

A
alteredq 已提交
1775 1776 1777 1778
				skinIndexArray[ offset_skin ]     = si1.x;
				skinIndexArray[ offset_skin + 1 ] = si1.y;
				skinIndexArray[ offset_skin + 2 ] = si1.z;
				skinIndexArray[ offset_skin + 3 ] = si1.w;
1779

A
alteredq 已提交
1780 1781 1782 1783
				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 已提交
1784

A
alteredq 已提交
1785 1786 1787 1788
				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 已提交
1789

A
alteredq 已提交
1790 1791 1792 1793
				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 已提交
1794

A
alteredq 已提交
1795
				// vertices A
M
Mr.doob 已提交
1796

A
alteredq 已提交
1797 1798 1799 1800
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
				sa4 = obj_skinVerticesA[ face.d ];
1801

A
alteredq 已提交
1802 1803 1804 1805
				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 已提交
1806

A
alteredq 已提交
1807 1808 1809 1810
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1811

A
alteredq 已提交
1812 1813 1814 1815
				skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
				skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
				skinVertexAArray[ offset_skin + 10 ] = sa3.z;
				skinVertexAArray[ offset_skin + 11 ] = 1;
1816

A
alteredq 已提交
1817 1818 1819 1820
				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 已提交
1821

A
alteredq 已提交
1822
				// vertices B
M
Mr.doob 已提交
1823

A
alteredq 已提交
1824 1825 1826 1827
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
				sb4 = obj_skinVerticesB[ face.d ];
M
Mr.doob 已提交
1828

A
alteredq 已提交
1829 1830 1831 1832
				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 已提交
1833

A
alteredq 已提交
1834 1835 1836 1837
				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
				skinVertexBArray[ offset_skin + 7 ] = 1;
1838

A
alteredq 已提交
1839 1840 1841 1842
				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
				skinVertexBArray[ offset_skin + 11 ] = 1;
1843

A
alteredq 已提交
1844 1845 1846 1847
				skinVertexBArray[ offset_skin + 12 ] = sb4.x;
				skinVertexBArray[ offset_skin + 13 ] = sb4.y;
				skinVertexBArray[ offset_skin + 14 ] = sb4.z;
				skinVertexBArray[ offset_skin + 15 ] = 1;
1848

A
alteredq 已提交
1849
				offset_skin += 16;
M
Mr.doob 已提交
1850

A
alteredq 已提交
1851
			}
M
Mr.doob 已提交
1852

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

A
alteredq 已提交
1855 1856
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );
M
Mr.doob 已提交
1857

A
alteredq 已提交
1858 1859 1860 1861 1862 1863 1864 1865
				_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 );
1866

1867
			}
1868

A
alteredq 已提交
1869
		}
M
Mr.doob 已提交
1870

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

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

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

A
alteredq 已提交
1877 1878
				vertexColors = face.vertexColors;
				faceColor = face.color;
1879

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

A
alteredq 已提交
1882 1883 1884
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
1885

A
alteredq 已提交
1886
				} else {
1887

A
alteredq 已提交
1888 1889 1890
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
1891

A
alteredq 已提交
1892
				}
1893

A
alteredq 已提交
1894 1895 1896
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
1897

A
alteredq 已提交
1898 1899 1900
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
1901

A
alteredq 已提交
1902 1903 1904
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
1905

A
alteredq 已提交
1906
				offset_color += 9;
M
Mr.doob 已提交
1907

A
alteredq 已提交
1908
			}
M
Mr.doob 已提交
1909

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

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

A
alteredq 已提交
1914 1915
				vertexColors = face.vertexColors;
				faceColor = face.color;
M
Mr.doob 已提交
1916

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

A
alteredq 已提交
1919 1920 1921 1922
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
					c4 = vertexColors[ 3 ];
1923

A
alteredq 已提交
1924
				} else {
M
Mr.doob 已提交
1925

A
alteredq 已提交
1926 1927 1928 1929
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
					c4 = faceColor;
M
Mr.doob 已提交
1930

A
alteredq 已提交
1931
				}
1932

A
alteredq 已提交
1933 1934 1935
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
1936

A
alteredq 已提交
1937 1938 1939
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
M
Mr.doob 已提交
1940

A
alteredq 已提交
1941 1942 1943
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
M
Mr.doob 已提交
1944

A
alteredq 已提交
1945 1946 1947
				colorArray[ offset_color + 9 ]  = c4.r;
				colorArray[ offset_color + 10 ] = c4.g;
				colorArray[ offset_color + 11 ] = c4.b;
M
Mr.doob 已提交
1948

A
alteredq 已提交
1949
				offset_color += 12;
1950

1951
			}
1952

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

A
alteredq 已提交
1955 1956
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
M
Mr.doob 已提交
1957

1958
			}
1959

A
alteredq 已提交
1960
		}
M
Mr.doob 已提交
1961

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

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

A
alteredq 已提交
1966
				face = obj_faces[ chunk_faces3[ f ]	];
1967

A
alteredq 已提交
1968
				vertexTangents = face.vertexTangents;
M
Mr.doob 已提交
1969

A
alteredq 已提交
1970 1971 1972
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
1973

A
alteredq 已提交
1974 1975 1976 1977
				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 已提交
1978

A
alteredq 已提交
1979 1980 1981 1982
				tangentArray[ offset_tangent + 4 ] = t2.x;
				tangentArray[ offset_tangent + 5 ] = t2.y;
				tangentArray[ offset_tangent + 6 ] = t2.z;
				tangentArray[ offset_tangent + 7 ] = t2.w;
1983

A
alteredq 已提交
1984 1985 1986 1987
				tangentArray[ offset_tangent + 8 ]  = t3.x;
				tangentArray[ offset_tangent + 9 ]  = t3.y;
				tangentArray[ offset_tangent + 10 ] = t3.z;
				tangentArray[ offset_tangent + 11 ] = t3.w;
1988

A
alteredq 已提交
1989
				offset_tangent += 12;
1990

1991
			}
1992

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

A
alteredq 已提交
1995
				face = obj_faces[ chunk_faces4[ f ] ];
1996

A
alteredq 已提交
1997
				vertexTangents = face.vertexTangents;
1998

A
alteredq 已提交
1999 2000 2001 2002
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
				t4 = vertexTangents[ 3 ];
2003

A
alteredq 已提交
2004 2005 2006 2007
				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 已提交
2008

A
alteredq 已提交
2009 2010 2011 2012
				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 已提交
2013

A
alteredq 已提交
2014 2015 2016 2017
				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 已提交
2018

A
alteredq 已提交
2019 2020 2021 2022
				tangentArray[ offset_tangent + 12 ] = t4.x;
				tangentArray[ offset_tangent + 13 ] = t4.y;
				tangentArray[ offset_tangent + 14 ] = t4.z;
				tangentArray[ offset_tangent + 15 ] = t4.w;
2023

A
alteredq 已提交
2024
				offset_tangent += 16;
2025

A
alteredq 已提交
2026
			}
2027

A
alteredq 已提交
2028 2029
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
2030

A
alteredq 已提交
2031
		}
2032

A
alteredq 已提交
2033
		if ( dirtyNormals && normalType ) {
2034

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

A
alteredq 已提交
2037
				face = obj_faces[ chunk_faces3[ f ]	];
2038

A
alteredq 已提交
2039 2040
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
2041

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

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

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

A
alteredq 已提交
2048 2049 2050
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
2051

A
alteredq 已提交
2052
						offset_normal += 3;
2053

A
alteredq 已提交
2054
					}
2055

A
alteredq 已提交
2056
				} else {
M
Mr.doob 已提交
2057

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

A
alteredq 已提交
2060 2061 2062
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
2063

A
alteredq 已提交
2064
						offset_normal += 3;
M
Mr.doob 已提交
2065

A
alteredq 已提交
2066
					}
2067

A
alteredq 已提交
2068
				}
2069

A
alteredq 已提交
2070
			}
2071

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

A
alteredq 已提交
2074
				face = obj_faces[ chunk_faces4[ f ] ];
2075

A
alteredq 已提交
2076 2077
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
2078

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

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

A
alteredq 已提交
2083
						vn = vertexNormals[ i ];
2084

A
alteredq 已提交
2085 2086 2087
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
2088

A
alteredq 已提交
2089
						offset_normal += 3;
2090

A
alteredq 已提交
2091
					}
M
Mr.doob 已提交
2092

A
alteredq 已提交
2093
				} else {
2094

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

A
alteredq 已提交
2097 2098 2099
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
2100

A
alteredq 已提交
2101
						offset_normal += 3;
M
Mr.doob 已提交
2102

A
alteredq 已提交
2103
					}
2104

A
alteredq 已提交
2105
				}
2106

A
alteredq 已提交
2107
			}
M
Mr.doob 已提交
2108

A
alteredq 已提交
2109 2110
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
2111

A
alteredq 已提交
2112
		}
M
Mr.doob 已提交
2113

A
alteredq 已提交
2114
		if ( dirtyUvs && obj_uvs && uvType ) {
2115

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

A
alteredq 已提交
2118
				fi = chunk_faces3[ f ];
2119

A
alteredq 已提交
2120 2121
				face = obj_faces[ fi ];
				uv = obj_uvs[ fi ];
2122

A
alteredq 已提交
2123
				if ( uv === undefined ) continue;
2124

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

A
alteredq 已提交
2127
					uvi = uv[ i ];
2128

A
alteredq 已提交
2129 2130
					uvArray[ offset_uv ]     = uvi.u;
					uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
2131

A
alteredq 已提交
2132
					offset_uv += 2;
M
Mr.doob 已提交
2133

A
alteredq 已提交
2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154
				}

			}

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

2156 2157
				}

2158
			}
2159

A
alteredq 已提交
2160
			if ( offset_uv > 0 ) {
2161

A
alteredq 已提交
2162 2163
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
2164

A
alteredq 已提交
2165
			}
2166

A
alteredq 已提交
2167
		}
2168

A
alteredq 已提交
2169
		if ( dirtyUvs && obj_uvs2 && uvType ) {
2170

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

A
alteredq 已提交
2173
				fi = chunk_faces3[ f ];
2174

A
alteredq 已提交
2175 2176
				face = obj_faces[ fi ];
				uv2 = obj_uvs2[ fi ];
2177

A
alteredq 已提交
2178 2179 2180 2181 2182 2183 2184 2185 2186 2187
				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;
2188

2189 2190
				}

A
alteredq 已提交
2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211
			}

			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;

				}
2212

2213
			}
2214

A
alteredq 已提交
2215
			if ( offset_uv2 > 0 ) {
2216

A
alteredq 已提交
2217 2218
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );
2219

A
alteredq 已提交
2220
			}
2221

A
alteredq 已提交
2222
		}
2223

A
alteredq 已提交
2224
		if ( dirtyElements ) {
2225

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

A
alteredq 已提交
2228
				face = obj_faces[ chunk_faces3[ f ]	];
2229

A
alteredq 已提交
2230 2231 2232
				faceArray[ offset_face ] 	 = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 2;
2233

A
alteredq 已提交
2234
				offset_face += 3;
2235

A
alteredq 已提交
2236 2237
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2238

A
alteredq 已提交
2239 2240
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 2;
2241

A
alteredq 已提交
2242 2243
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
2244

A
alteredq 已提交
2245
				offset_line += 6;
2246

A
alteredq 已提交
2247
				vertexIndex += 3;
2248

A
alteredq 已提交
2249
			}
2250

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

A
alteredq 已提交
2253
				face = obj_faces[ chunk_faces4[ f ] ];
2254

A
alteredq 已提交
2255 2256 2257
				faceArray[ offset_face ]     = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 3;
2258

A
alteredq 已提交
2259 2260 2261
				faceArray[ offset_face + 3 ] = vertexIndex + 1;
				faceArray[ offset_face + 4 ] = vertexIndex + 2;
				faceArray[ offset_face + 5 ] = vertexIndex + 3;
2262

A
alteredq 已提交
2263
				offset_face += 6;
2264

A
alteredq 已提交
2265 2266
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2267

A
alteredq 已提交
2268 2269
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 3;
2270

A
alteredq 已提交
2271 2272
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
2273

A
alteredq 已提交
2274 2275
				lineArray[ offset_line + 6 ] = vertexIndex + 2;
				lineArray[ offset_line + 7 ] = vertexIndex + 3;
2276

A
alteredq 已提交
2277
				offset_line += 8;
2278

A
alteredq 已提交
2279
				vertexIndex += 4;
2280

2281
			}
2282

A
alteredq 已提交
2283 2284
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
2285

A
alteredq 已提交
2286 2287
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
2288

A
alteredq 已提交
2289
		}
2290

A
alteredq 已提交
2291
		if ( customAttributes ) {
2292

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

2295
				customAttribute = customAttributes[ i ];
2296

2297
				if ( ! customAttribute.__original.needsUpdate ) continue;
2298

2299 2300
				offset_custom = 0;
				offset_customSrc = 0;
2301

2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334
				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 ++ ) {

2335
							value = customAttribute.value[ chunk_faces3[ f ] ];
2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346

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

2347
							value = customAttribute.value[ chunk_faces4[ f ] ];
2348 2349 2350 2351 2352 2353 2354 2355 2356

							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;

						}
2357

2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376
					}

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

2378 2379
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2380

2381
							offset_custom += 6;
A
alteredq 已提交
2382

2383
						}
A
alteredq 已提交
2384

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

2387
							face = obj_faces[ chunk_faces4[ f ] ];
A
alteredq 已提交
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 ];
A
alteredq 已提交
2393

2394 2395
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2396

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

2400 2401
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2402

2403 2404
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
A
alteredq 已提交
2405

2406
							offset_custom += 8;
A
alteredq 已提交
2407

2408
						}
A
alteredq 已提交
2409

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

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

2414
							value = customAttribute.value[ chunk_faces3[ f ] ];
A
alteredq 已提交
2415

2416 2417 2418
							v1 = value;
							v2 = value;
							v3 = value;
A
alteredq 已提交
2419

2420 2421
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2422

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

2426 2427
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2428

2429
							offset_custom += 6;
A
alteredq 已提交
2430

2431
						}
A
alteredq 已提交
2432

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

2435
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2436

2437 2438 2439 2440
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2441

2442 2443
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2444

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

2448 2449
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2450

2451 2452
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
2453

2454
							offset_custom += 8;
M
Mr.doob 已提交
2455

2456
						}
M
Mr.doob 已提交
2457

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

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

2462
					var pp;
2463

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

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

2468
					} else {
M
Mr.doob 已提交
2469

2470
						pp = [ "x", "y", "z" ];
2471

2472
					}
2473

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

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

2478
							face = obj_faces[ chunk_faces3[ f ]	];
2479

2480 2481 2482
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
2483

2484 2485 2486
							customAttribute.array[ offset_custom ] 	   = v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
2487

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

2492 2493 2494
							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 已提交
2495

2496
							offset_custom += 9;
M
Mr.doob 已提交
2497

2498
						}
M
Mr.doob 已提交
2499

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

2502
							face = obj_faces[ chunk_faces4[ f ] ];
M
Mr.doob 已提交
2503

2504 2505 2506 2507
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
M
Mr.doob 已提交
2508

2509 2510 2511
							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 已提交
2512

2513 2514 2515
							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 已提交
2516

2517 2518 2519
							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 已提交
2520

2521 2522 2523
							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 已提交
2524

2525
							offset_custom += 12;
M
Mr.doob 已提交
2526

2527
						}
M
Mr.doob 已提交
2528

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

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

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

2535 2536 2537
							v1 = value;
							v2 = value;
							v3 = value;
M
Mr.doob 已提交
2538

2539 2540 2541
							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 已提交
2542

2543 2544 2545
							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 已提交
2546

2547 2548 2549
							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 已提交
2550

2551
							offset_custom += 9;
M
Mr.doob 已提交
2552

2553
						}
2554

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

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

2559 2560 2561 2562
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
2563

2564 2565 2566
							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
2567

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

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

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

2580
							offset_custom += 12;
2581

2582
						}
2583

A
alteredq 已提交
2584
					}
M
Mr.doob 已提交
2585

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

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

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

2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653
							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 ++ ) {

2654
							value = customAttribute.value[ chunk_faces3[ f ] ];
2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671

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

2675
							offset_custom += 12;
A
alteredq 已提交
2676

2677 2678
						}

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

2681
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2682

2683 2684 2685 2686
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2687

2688 2689 2690 2691
							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;
2692

2693 2694 2695 2696
							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;
2697

2698 2699 2700 2701
							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;
2702

2703 2704 2705 2706
							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;
2707

2708
							offset_custom += 16;
A
alteredq 已提交
2709

2710
						}
A
alteredq 已提交
2711 2712 2713 2714 2715

					}

				}

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

A
alteredq 已提交
2719 2720 2721 2722
			}

		}

2723
		if ( dispose ) {
2724

2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737
			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 已提交
2738

2739
		}
A
alteredq 已提交
2740

2741
	};
A
alteredq 已提交
2742

2743
	// Buffer rendering
A
alteredq 已提交
2744

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

2747 2748
		if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
A
alteredq 已提交
2749

2750
		if ( object.hasPos ) {
A
alteredq 已提交
2751

2752 2753 2754 2755
			_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 已提交
2756 2757 2758

		}

2759
		if ( object.hasNormal ) {
A
alteredq 已提交
2760

2761
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
A
alteredq 已提交
2762

2763
			if ( shading === THREE.FlatShading ) {
2764

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

2770
				for( i = 0; i < il; i += 9 ) {
2771

2772
					normalArray = object.normalArray;
2773

2774 2775 2776
					nax  = normalArray[ i ];
					nay  = normalArray[ i + 1 ];
					naz  = normalArray[ i + 2 ];
2777

2778 2779 2780
					nbx  = normalArray[ i + 3 ];
					nby  = normalArray[ i + 4 ];
					nbz  = normalArray[ i + 5 ];
2781

2782 2783 2784
					ncx  = normalArray[ i + 6 ];
					ncy  = normalArray[ i + 7 ];
					ncz  = normalArray[ i + 8 ];
2785

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

2790 2791 2792
					normalArray[ i ] 	 = nx;
					normalArray[ i + 1 ] = ny;
					normalArray[ i + 2 ] = nz;
2793

2794 2795 2796
					normalArray[ i + 3 ] = nx;
					normalArray[ i + 4 ] = ny;
					normalArray[ i + 5 ] = nz;
2797

2798 2799 2800
					normalArray[ i + 6 ] = nx;
					normalArray[ i + 7 ] = ny;
					normalArray[ i + 8 ] = nz;
2801

2802
				}
2803

2804
			}
2805

2806 2807 2808
			_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 );
2809

2810
		}
2811

2812
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );
2813

2814
		object.count = 0;
2815

2816
	};
2817

2818 2819 2820 2821
	this.renderBufferDirect = function ( camera, lights, fog, material, geometryGroup, object ) {

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

2822
		var program, attributes, linewidth, primitives, a, attribute;
2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844

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

		attributes = program.attributes;

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

		if ( geometryGroupHash !== _currentGeometryGroupHash ) {

			_currentGeometryGroupHash = geometryGroupHash;
			updateBuffers = true;

		}

		// render mesh

		if ( object instanceof THREE.Mesh ) {

			var offsets = geometryGroup.offsets;

2845
			for ( var i = 0, il = offsets.length; i < il; ++ i ) {
2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909

				if ( updateBuffers ) {

					// vertices

					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.vertexPositionBuffer );
					_gl.vertexAttribPointer( attributes.position, geometryGroup.vertexPositionBuffer.itemSize, _gl.FLOAT, false, 0, offsets[ i ].index * 4 * 3 );

					// normals

					if ( attributes.normal >= 0 && geometryGroup.vertexNormalBuffer ) {

						_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.vertexNormalBuffer );
						_gl.vertexAttribPointer( attributes.normal, geometryGroup.vertexNormalBuffer.itemSize, _gl.FLOAT, false, 0, offsets[ i ].index * 4 * 3 );

					}

					// uvs

					if ( attributes.uv >= 0 && geometryGroup.vertexUvBuffer ) {

						if ( geometryGroup.vertexUvBuffer ) {

							_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.vertexUvBuffer );
							_gl.vertexAttribPointer(  attributes.uv, geometryGroup.vertexUvBuffer.itemSize, _gl.FLOAT, false, 0, offsets[ i ].index * 4 * 2 );

							_gl.enableVertexAttribArray( attributes.uv );

						} else {

							_gl.disableVertexAttribArray( attributes.uv );

						}

					}

					// colors

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

						_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.vertexColorBuffer );
						_gl.vertexAttribPointer( attributes.color, geometryGroup.vertexColorBuffer.itemSize, _gl.FLOAT, false, 0, offsets[ i ].index * 4 * 4 );


					}

					_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.vertexIndexBuffer );

				}

				// render indexed triangles

				_gl.drawElements( _gl.TRIANGLES, offsets[ i ].count, _gl.UNSIGNED_SHORT, offsets[ i ].start * 2 ); // 2 = Uint16

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

			}

		}

	};

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

2912
		if ( material.opacity === 0 ) return;
2913

2914
		var program, attributes, linewidth, primitives, a, attribute, i, il;
2915

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

2918
		attributes = program.attributes;
2919

2920 2921 2922
		var updateBuffers = false,
			wireframeBit = material.wireframe ? 1 : 0,
			geometryGroupHash = ( geometryGroup.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit;
2923

2924
		if ( geometryGroupHash !== _currentGeometryGroupHash ) {
A
alteredq 已提交
2925

2926 2927
			_currentGeometryGroupHash = geometryGroupHash;
			updateBuffers = true;
2928

2929
		}
2930

2931
		// vertices
2932

2933
		if ( !material.morphTargets && attributes.position >= 0 ) {
2934

2935
			if ( updateBuffers ) {
2936

2937 2938
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
				_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
2939

2940
			}
2941

2942
		} else {
2943

2944
			if ( object.morphTargetBase ) {
2945

2946
				setupMorphTargets( material, geometryGroup, object );
2947

2948
			}
2949

2950
		}
2951

2952

2953
		if ( updateBuffers ) {
2954

2955
			// custom attributes
2956

2957
			// Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
2958

2959
			if ( geometryGroup.__webglCustomAttributesList ) {
2960

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

2963
					attribute = geometryGroup.__webglCustomAttributesList[ i ];
2964

2965
					if( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
2966

2967 2968
						_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
						_gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 );
2969

2970
					}
2971

2972
				}
2973

2974
			}
2975 2976


2977
			// colors
2978

2979
			if ( attributes.color >= 0 ) {
2980

2981 2982
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
2983

2984
			}
2985

2986
			// normals
2987

2988
			if ( attributes.normal >= 0 ) {
2989

2990 2991
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
				_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
2992

2993
			}
2994

2995
			// tangents
2996

2997
			if ( attributes.tangent >= 0 ) {
2998

2999 3000
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
				_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
3001

3002
			}
3003

3004
			// uvs
3005

3006
			if ( attributes.uv >= 0 ) {
3007

3008
				if ( geometryGroup.__webglUVBuffer ) {
3009

3010 3011
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
					_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
3012

3013
					_gl.enableVertexAttribArray( attributes.uv );
3014

3015
				} else {
3016

3017
					_gl.disableVertexAttribArray( attributes.uv );
3018 3019 3020 3021 3022

				}

			}

3023
			if ( attributes.uv2 >= 0 ) {
3024

3025
				if ( geometryGroup.__webglUV2Buffer ) {
3026

3027 3028
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
					_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
3029

3030
					_gl.enableVertexAttribArray( attributes.uv2 );
3031

3032
				} else {
3033

3034
					_gl.disableVertexAttribArray( attributes.uv2 );
3035 3036

				}
3037 3038

			}
3039

3040 3041 3042
			if ( material.skinning &&
				 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
				 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
A
alteredq 已提交
3043

3044 3045
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3046

3047 3048
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
				_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3049

3050 3051
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
				_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3052

3053 3054
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
				_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
3055

A
alteredq 已提交
3056
			}
3057

3058
		}
3059

3060
		// render mesh
3061

3062
		if ( object instanceof THREE.Mesh ) {
3063

3064
			// wireframe
3065

3066
			if ( material.wireframe ) {
3067

3068
				setLineWidth( material.wireframeLinewidth );
3069

3070 3071
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
3072

3073
			// triangles
3074

3075
			} else {
3076

3077 3078
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3079

3080
			}
3081

3082 3083 3084
			_this.info.render.calls ++;
			_this.info.render.vertices += geometryGroup.__webglFaceCount;
			_this.info.render.faces += geometryGroup.__webglFaceCount / 3;
3085

3086
		// render lines
3087

3088
		} else if ( object instanceof THREE.Line ) {
3089

3090
			primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
3091

3092
			setLineWidth( material.linewidth );
3093

3094
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
3095

3096
			_this.info.render.calls ++;
3097

3098
		// render particles
3099

3100
		} else if ( object instanceof THREE.ParticleSystem ) {
3101

3102
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
3103

3104
			_this.info.render.calls ++;
3105
			_this.info.render.points += geometryGroup.__webglParticleCount;
3106

3107
		// render ribbon
3108

3109
		} else if ( object instanceof THREE.Ribbon ) {
3110

3111
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
3112

3113
			_this.info.render.calls ++;
3114

3115
		}
3116

3117
	};
3118

3119
	function setupMorphTargets ( material, geometryGroup, object ) {
3120

3121
		// set base
3122

3123
		var attributes = material.program.attributes;
3124

3125
		if ( object.morphTargetBase !== - 1 ) {
3126

3127 3128
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3129

3130
		} else if ( attributes.position >= 0 ) {
3131

3132 3133
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3134

3135
		}
3136

3137
		if ( object.morphTargetForcedOrder.length ) {
3138

3139
			// set forced order
3140

3141 3142 3143 3144 3145
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;

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

3147 3148 3149
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ order[ m ] ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );

A
alteredq 已提交
3150 3151 3152 3153 3154 3155 3156
				if ( material.morphNormals ) {

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

				}

3157 3158 3159
				object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ] ];

				m ++;
3160 3161
			}

3162 3163 3164 3165 3166 3167 3168 3169 3170 3171
		} else {

			// find most influencing

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

3173
			if ( object.morphTargetBase !== - 1 ) {
3174

3175
				used[ object.morphTargetBase ] = true;
3176

3177
			}
3178

3179
			while ( m < material.numSupportedMorphTargets ) {
3180

3181
				for ( i = 0; i < il; i ++ ) {
3182

3183
					if ( !used[ i ] && influences[ i ] > candidateInfluence ) {
3184

3185 3186
						candidate = i;
						candidateInfluence = influences[ candidate ];
3187

3188
					}
3189

3190
				}
3191

3192 3193
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
3194

A
alteredq 已提交
3195 3196 3197 3198 3199 3200 3201
				if ( material.morphNormals ) {

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

				}

3202
				object.__webglMorphTargetInfluences[ m ] = candidateInfluence;
3203

3204 3205 3206
				used[ candidate ] = 1;
				candidateInfluence = -1;
				m ++;
3207 3208 3209 3210 3211

			}

		}

3212
		// load updated influences uniform
3213

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

3216
			_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
3217

3218
		}
3219

3220
	};
3221 3222


3223
	function painterSort ( a, b ) {
3224

3225
		return b.z - a.z;
3226

3227
	};
3228

3229
	// Rendering
3230

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

3233 3234 3235 3236 3237 3238 3239 3240
		var i, il,

		program, material,
		webglObject, object,
		renderList,

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

3242
		_currentMaterialId = -1;
3243

3244
		if ( this.autoUpdateObjects ) this.initWebGLObjects( scene );
3245

3246
		if ( camera.parent === undefined ) {
3247

3248 3249
			console.warn( 'DEPRECATED: Camera hasn\'t been added to a Scene. Adding it...' );
			scene.add( camera );
3250

3251
		}
3252

3253
		if ( this.autoUpdateScene ) scene.updateMatrixWorld();
3254

A
alteredq 已提交
3255 3256
		// custom render plugins (pre pass)

A
alteredq 已提交
3257
		renderPlugins( this.renderPluginsPre, scene, camera );
A
alteredq 已提交
3258 3259 3260 3261

		_this.info.render.calls = 0;
		_this.info.render.vertices = 0;
		_this.info.render.faces = 0;
3262
		_this.info.render.points = 0;
A
alteredq 已提交
3263

3264
		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
A
alteredq 已提交
3265 3266 3267 3268 3269 3270

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

3272
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
A
alteredq 已提交
3273
		_frustum.setFromMatrix( _projScreenMatrix );
3274

A
alteredq 已提交
3275
		this.setRenderTarget( renderTarget );
3276

3277
		if ( this.autoClear || forceClear ) {
3278

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

3281
		}
M
Mr.doob 已提交
3282

3283
		// set matrices for regular objects (frustum culled)
3284

3285
		renderList = scene.__webglObjects;
3286

3287
		for ( i = 0, il = renderList.length; i < il; i ++ ) {
3288

3289
			webglObject = renderList[ i ];
3290
			object = webglObject.object;
3291

A
alteredq 已提交
3292 3293
			webglObject.render = false;

3294
			if ( object.visible ) {
3295

3296
				if ( ! ( object instanceof THREE.Mesh || object instanceof THREE.ParticleSystem ) || ! ( object.frustumCulled ) || _frustum.contains( object ) ) {
M
Mr.doob 已提交
3297

3298
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
3299

A
alteredq 已提交
3300
					setupMatrices( object, camera );
3301

3302
					unrollBufferMaterial( webglObject );
3303

3304
					webglObject.render = true;
3305

3306
					if ( this.sortObjects ) {
3307

3308
						if ( object.renderDepth ) {
3309

3310
							webglObject.z = object.renderDepth;
M
Mr.doob 已提交
3311

3312
						} else {
M
Mr.doob 已提交
3313

3314 3315
							_vector3.copy( object.position );
							_projScreenMatrix.multiplyVector3( _vector3 );
3316

3317
							webglObject.z = _vector3.z;
3318

3319
						}
M
Mr.doob 已提交
3320

3321
					}
M
Mr.doob 已提交
3322

3323
				}
3324 3325

			}
3326 3327 3328

		}

3329
		if ( this.sortObjects ) {
M
Mr.doob 已提交
3330

3331
			renderList.sort( painterSort );
3332

3333
		}
3334

3335
		// set matrices for immediate objects
3336

3337
		renderList = scene.__webglObjectsImmediate;
3338

3339 3340 3341
		for ( i = 0, il = renderList.length; i < il; i ++ ) {

			webglObject = renderList[ i ];
3342
			object = webglObject.object;
3343

3344
			if ( object.visible ) {
3345

3346
				if( object.matrixAutoUpdate ) {
3347

3348
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3349

3350
				}
M
Mr.doob 已提交
3351

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

3354
				unrollImmediateBufferMaterial( webglObject );
M
Mr.doob 已提交
3355

3356
			}
M
Mr.doob 已提交
3357

3358
		}
3359

3360
		if ( scene.overrideMaterial ) {
3361

3362
			this.setBlending( scene.overrideMaterial.blending );
A
alteredq 已提交
3363
			this.setDepthTest( scene.overrideMaterial.depthTest );
3364
			this.setDepthWrite( scene.overrideMaterial.depthWrite );
3365
			setPolygonOffset( scene.overrideMaterial.polygonOffset, scene.overrideMaterial.polygonOffsetFactor, scene.overrideMaterial.polygonOffsetUnits );
3366

3367 3368
			renderObjects( scene.__webglObjects, false, "", camera, lights, fog, true, scene.overrideMaterial );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "", camera, lights, fog, false, scene.overrideMaterial );
M
Mr.doob 已提交
3369

3370
		} else {
3371

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

3374
			this.setBlending( THREE.NormalBlending );
3375

3376 3377
			renderObjects( scene.__webglObjects, true, "opaque", camera, lights, fog, false );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "opaque", camera, lights, fog, false );
3378

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

3381 3382
			renderObjects( scene.__webglObjects, false, "transparent", camera, lights, fog, true );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "transparent", camera, lights, fog, true );
3383

3384
		}
3385

A
alteredq 已提交
3386
		// custom render plugins (post pass)
3387

A
alteredq 已提交
3388
		renderPlugins( this.renderPluginsPost, scene, camera );
3389 3390


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

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

3395
			updateRenderTargetMipmap( renderTarget );
3396

3397
		}
3398

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

		this.setDepthTest( true );
3402
		this.setDepthWrite( true );
3403

3404
		// _gl.finish();
3405

3406
	};
3407

A
alteredq 已提交
3408 3409 3410 3411 3412 3413 3414
	function renderPlugins( plugins, scene, camera ) {

		if ( ! plugins.length ) return;

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

			_currentProgram = null;
3415
			_currentCamera = null;
A
alteredq 已提交
3416 3417 3418 3419 3420 3421
			_oldBlending = -1;
			_oldDepthTest = -1;
			_oldDepthWrite = -1;
			_currentGeometryGroupHash = -1;
			_currentMaterialId = -1;

A
alteredq 已提交
3422
			plugins[ i ].render( scene, camera, _currentWidth, _currentHeight );
A
alteredq 已提交
3423 3424

			_currentProgram = null;
3425
			_currentCamera = null;
A
alteredq 已提交
3426 3427 3428 3429 3430 3431 3432 3433 3434 3435
			_oldBlending = -1;
			_oldDepthTest = -1;
			_oldDepthWrite = -1;
			_currentGeometryGroupHash = -1;
			_currentMaterialId = -1;

		}

	};

3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471
	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;

3472
					if ( useBlending ) _this.setBlending( material.blending );
3473

A
alteredq 已提交
3474
					_this.setDepthTest( material.depthTest );
3475
					_this.setDepthWrite( material.depthWrite );
3476 3477 3478 3479
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

A
alteredq 已提交
3480
				_this.setObjectFaces( object );
3481 3482 3483 3484 3485 3486 3487 3488 3489 3490

				if ( buffer instanceof THREE.BufferGeometry ) {

					_this.renderBufferDirect( camera, lights, fog, material, buffer, object );

				} else {

					_this.renderBuffer( camera, lights, fog, material, buffer, object );

				}
3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518

			}

		}

	};

	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 已提交
3519
					if ( useBlending ) _this.setBlending( material.blending );
3520

A
alteredq 已提交
3521
					_this.setDepthTest( material.depthTest );
3522
					_this.setDepthWrite( material.depthWrite );
3523 3524 3525 3526
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

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

A
alteredq 已提交
3529
			}
3530

A
alteredq 已提交
3531
		}
3532

A
alteredq 已提交
3533
	};
3534

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

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

A
alteredq 已提交
3539
		_currentGeometryGroupHash = -1;
3540

A
alteredq 已提交
3541 3542 3543 3544 3545 3546 3547 3548 3549
		_this.setObjectFaces( object );

		if ( object.immediateRenderCallback ) {

			object.immediateRenderCallback( program, _gl, _frustum );

		} else {

			object.render( function( object ) { _this.renderBufferImmediate( object, program, material.shading ); } );
3550 3551 3552 3553 3554

		}

	};

3555
	function unrollImmediateBufferMaterial ( globject ) {
3556

3557 3558
		var object = globject.object,
			material = object.material;
3559

3560
		if ( material.transparent ) {
3561

3562 3563
			globject.transparent = material;
			globject.opaque = null;
3564

3565
		} else {
3566

3567 3568
			globject.opaque = material;
			globject.transparent = null;
3569

3570
		}
A
alteredq 已提交
3571

3572
	};
A
alteredq 已提交
3573

3574
	function unrollBufferMaterial ( globject ) {
A
alteredq 已提交
3575

3576 3577 3578
		var object = globject.object,
			buffer = globject.buffer,
			material, materialIndex, meshMaterial;
3579

3580
		meshMaterial = object.material;
3581

3582
		if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
M
Mr.doob 已提交
3583

3584
			materialIndex = buffer.materialIndex;
3585

3586
			if ( materialIndex >= 0 ) {
3587

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

3590
				if ( material.transparent ) {
M
Mr.doob 已提交
3591

3592 3593
					globject.transparent = material;
					globject.opaque = null;
3594

3595
				} else {
3596

3597 3598
					globject.opaque = material;
					globject.transparent = null;
3599

3600
				}
3601

3602
			}
3603

3604
		} else {
3605

3606
			material = meshMaterial;
3607

3608
			if ( material ) {
3609

3610
				if ( material.transparent ) {
M
Mr.doob 已提交
3611

3612 3613
					globject.transparent = material;
					globject.opaque = null;
A
alteredq 已提交
3614

3615
				} else {
3616

3617 3618
					globject.opaque = material;
					globject.transparent = null;
3619

3620
				}
3621

3622
			}
3623

3624
		}
3625

3626
	};
3627

3628
	// Geometry splitting
3629

3630
	function sortFacesByMaterial ( geometry ) {
3631

3632 3633 3634
		var f, fl, face, materialIndex, vertices,
			materialHash, groupHash,
			hash_map = {};
3635

3636
		var numMorphTargets = geometry.morphTargets.length;
3637

3638
		geometry.geometryGroups = {};
3639

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

3642 3643
			face = geometry.faces[ f ];
			materialIndex = face.materialIndex;
3644

3645
			materialHash = ( materialIndex !== undefined ) ? materialIndex : -1;
3646

3647
			if ( hash_map[ materialHash ] === undefined ) {
3648

3649
				hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 };
3650 3651 3652

			}

3653
			groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
3654

3655
			if ( geometry.geometryGroups[ groupHash ] === undefined ) {
3656

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

3659
			}
A
alteredq 已提交
3660

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

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

3665 3666
				hash_map[ materialHash ].counter += 1;
				groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
A
alteredq 已提交
3667

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

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

3672
				}
3673

3674
			}
3675

3676
			if ( face instanceof THREE.Face3 ) {
3677

3678
				geometry.geometryGroups[ groupHash ].faces3.push( f );
3679

3680
			} else {
3681

3682
				geometry.geometryGroups[ groupHash ].faces4.push( f );
3683

A
alteredq 已提交
3684
			}
3685

3686
			geometry.geometryGroups[ groupHash ].vertices += vertices;
3687

3688
		}
3689

3690
		geometry.geometryGroupsList = [];
3691

3692
		for ( var g in geometry.geometryGroups ) {
3693

3694
			geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;
3695

3696
			geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );
3697

3698
		}
3699

3700
	};
3701

3702 3703 3704 3705 3706 3707 3708 3709 3710
	// Objects refresh

	this.initWebGLObjects = function ( scene ) {

		if ( !scene.__webglObjects ) {

			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
			scene.__webglSprites = [];
3711
			scene.__webglFlares = [];
3712 3713

		}
3714

3715
		while ( scene.__objectsAdded.length ) {
3716

3717 3718
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
3719

3720
		}
A
alteredq 已提交
3721

3722
		while ( scene.__objectsRemoved.length ) {
3723

3724 3725
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
3726

3727
		}
3728

3729
		// update must be called after objects adding / removal
3730

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

3733
			updateObject( scene.__webglObjects[ o ].object );
M
Mr.doob 已提交
3734 3735 3736 3737 3738

		}

	};

3739
	// Objects adding
M
Mr.doob 已提交
3740

3741
	function addObject ( object, scene ) {
A
alteredq 已提交
3742

3743
		var g, geometry, geometryGroup;
3744

3745
		if ( ! object.__webglInit ) {
M
Mr.doob 已提交
3746

3747
			object.__webglInit = true;
M
Mr.doob 已提交
3748

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

3751 3752 3753
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
M
Mr.doob 已提交
3754

3755
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3756

3757
			if ( object instanceof THREE.Mesh ) {
M
Mr.doob 已提交
3758

3759
				geometry = object.geometry;
M
Mr.doob 已提交
3760

3761
				if ( geometry instanceof THREE.Geometry ) {
M
Mr.doob 已提交
3762

3763
					if ( geometry.geometryGroups === undefined ) {
M
Mr.doob 已提交
3764

3765
						sortFacesByMaterial( geometry );
M
Mr.doob 已提交
3766

3767 3768 3769
					}

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

3771
					for ( g in geometry.geometryGroups ) {
M
Mr.doob 已提交
3772

3773
						geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
3774

3775
						// initialise VBO on the first access
M
Mr.doob 已提交
3776

3777
						if ( ! geometryGroup.__webglVertexBuffer ) {
3778

3779 3780
							createMeshBuffers( geometryGroup );
							initMeshBuffers( geometryGroup, object );
M
Mr.doob 已提交
3781

3782 3783 3784 3785 3786 3787 3788 3789 3790
							geometry.__dirtyVertices = true;
							geometry.__dirtyMorphTargets = true;
							geometry.__dirtyElements = true;
							geometry.__dirtyUvs = true;
							geometry.__dirtyNormals = true;
							geometry.__dirtyTangents = true;
							geometry.__dirtyColors = true;

						}
M
Mr.doob 已提交
3791

3792
					}
M
Mr.doob 已提交
3793

3794
				}
M
Mr.doob 已提交
3795

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

3798
				geometry = object.geometry;
M
Mr.doob 已提交
3799

3800
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
3801

3802 3803
					createRibbonBuffers( geometry );
					initRibbonBuffers( geometry );
M
Mr.doob 已提交
3804

3805 3806
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
3807

3808
				}
M
Mr.doob 已提交
3809

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

3812
				geometry = object.geometry;
M
Mr.doob 已提交
3813

3814
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
3815

3816 3817
					createLineBuffers( geometry );
					initLineBuffers( geometry, object );
M
Mr.doob 已提交
3818

3819 3820
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
3821

3822
				}
3823

3824
			} else if ( object instanceof THREE.ParticleSystem ) {
3825

3826
				geometry = object.geometry;
3827

3828
				if ( ! geometry.__webglVertexBuffer ) {
3829

3830 3831
					createParticleBuffers( geometry );
					initParticleBuffers( geometry, object );
3832

3833 3834
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
3835

3836
				}
3837

3838
			}
3839

3840
		}
3841

3842
		if ( ! object.__webglActive ) {
3843

3844
			if ( object instanceof THREE.Mesh ) {
3845

3846
				geometry = object.geometry;
3847

3848 3849 3850 3851 3852 3853 3854 3855 3856
				if ( geometry instanceof THREE.BufferGeometry ) {

					addBuffer( scene.__webglObjects, geometry, object );

				} else {

					for ( g in geometry.geometryGroups ) {

						geometryGroup = geometry.geometryGroups[ g ];
3857

3858
						addBuffer( scene.__webglObjects, geometryGroup, object );
3859

3860
					}
3861

3862
				}
3863

3864 3865 3866
			} else if ( object instanceof THREE.Ribbon ||
						object instanceof THREE.Line ||
						object instanceof THREE.ParticleSystem ) {
3867

3868 3869
				geometry = object.geometry;
				addBuffer( scene.__webglObjects, geometry, object );
3870

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

3873
				addBufferImmediate( scene.__webglObjectsImmediate, object );
3874

3875
			} else if ( object instanceof THREE.Sprite ) {
3876

3877
				scene.__webglSprites.push( object );
3878

3879 3880 3881 3882
			} else if ( object instanceof THREE.LensFlare ) {

				scene.__webglFlares.push( object );

3883 3884
			}

3885
			object.__webglActive = true;
3886

3887
		}
3888

3889
	};
3890

3891
	function addBuffer ( objlist, buffer, object ) {
3892

3893 3894 3895 3896 3897 3898 3899 3900
		objlist.push(
			{
				buffer: buffer,
				object: object,
				opaque: null,
				transparent: null
			}
		);
3901

3902
	};
3903

3904
	function addBufferImmediate ( objlist, object ) {
3905

3906 3907 3908 3909 3910
		objlist.push(
			{
				object: object,
				opaque: null,
				transparent: null
3911
			}
3912
		);
3913

3914
	};
3915

3916
	// Objects updates
3917

3918
	function updateObject ( object ) {
3919

3920 3921
		var geometry = object.geometry,
			geometryGroup, customAttributesDirty, material;
3922

3923
		if ( object instanceof THREE.Mesh ) {
3924

3925 3926
			if ( geometry instanceof THREE.BufferGeometry ) {

3927
				/*
3928 3929 3930
				if ( geometry.__dirtyVertices || geometry.__dirtyElements ||
					 geometry.__dirtyUvs || geometry.__dirtyNormals ||
					 geometry.__dirtyColors  ) {
3931

3932 3933
					// TODO
					// set buffers from typed arrays
3934

3935
				}
3936
				*/
3937

3938 3939 3940 3941 3942
				geometry.__dirtyVertices = false;
				geometry.__dirtyElements = false;
				geometry.__dirtyUvs = false;
				geometry.__dirtyNormals = false;
				geometry.__dirtyColors = false;
3943

3944
			} else {
3945

3946
				// check all geometry groups
3947

3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962
				for( var i = 0, il = geometry.geometryGroupsList.length; i < il; i ++ ) {

					geometryGroup = geometry.geometryGroupsList[ i ];

					material = getBufferMaterial( object, geometryGroup );

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

					if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
						 geometry.__dirtyUvs || geometry.__dirtyNormals ||
						 geometry.__dirtyColors || geometry.__dirtyTangents || customAttributesDirty ) {

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

					}
3963

3964
				}
M
Mr.doob 已提交
3965

3966 3967 3968 3969 3970 3971 3972
				geometry.__dirtyVertices = false;
				geometry.__dirtyMorphTargets = false;
				geometry.__dirtyElements = false;
				geometry.__dirtyUvs = false;
				geometry.__dirtyNormals = false;
				geometry.__dirtyColors = false;
				geometry.__dirtyTangents = false;
3973

3974
				material.attributes && clearCustomAttributes( material );
3975

3976
			}
3977

3978
		} else if ( object instanceof THREE.Ribbon ) {
3979

3980
			if ( geometry.__dirtyVertices || geometry.__dirtyColors ) {
3981

3982
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
3983

3984
			}
3985

3986 3987
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
3988

3989
		} else if ( object instanceof THREE.Line ) {
3990

3991
			material = getBufferMaterial( object, geometryGroup );
A
alteredq 已提交
3992

3993
			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
A
alteredq 已提交
3994

3995
			if ( geometry.__dirtyVertices ||  geometry.__dirtyColors || customAttributesDirty ) {
A
alteredq 已提交
3996

3997
				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
3998

3999
			}
4000

4001 4002
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
4003

4004
			material.attributes && clearCustomAttributes( material );
4005

4006
		} else if ( object instanceof THREE.ParticleSystem ) {
4007

4008
			material = getBufferMaterial( object, geometryGroup );
4009

4010
			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
4011

4012
			if ( geometry.__dirtyVertices || geometry.__dirtyColors || object.sortParticles || customAttributesDirty ) {
4013

4014
				setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
4015

4016
			}
4017

4018 4019
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
4020

4021
			material.attributes && clearCustomAttributes( material );
4022

4023
		}
4024

4025
	};
4026

4027
	// Objects updates - custom attributes check
4028

4029
	function areCustomAttributesDirty ( material ) {
4030

4031
		for ( var a in material.attributes ) {
4032

4033
			if ( material.attributes[ a ].needsUpdate ) return true;
4034

4035
		}
4036

4037
		return false;
4038

4039
	};
4040

4041 4042 4043
	function clearCustomAttributes ( material ) {

		for ( var a in material.attributes ) {
4044

4045
			material.attributes[ a ].needsUpdate = false;
4046

4047
		}
4048

4049
	};
4050

4051
	// Objects removal
4052

4053
	function removeObject ( object, scene ) {
4054

4055 4056 4057 4058
		if ( object instanceof THREE.Mesh  ||
			 object instanceof THREE.ParticleSystem ||
			 object instanceof THREE.Ribbon ||
			 object instanceof THREE.Line ) {
4059

4060
			removeInstances( scene.__webglObjects, object );
4061

4062
		} else if ( object instanceof THREE.Sprite ) {
4063

4064
			removeInstancesDirect( scene.__webglSprites, object );
4065

4066 4067 4068 4069
		} else if ( object instanceof THREE.LensFlare ) {

			removeInstancesDirect( scene.__webglFlares, object );

4070
		} else if ( object instanceof THREE.MarchingCubes || object.immediateRenderCallback ) {
4071

4072
			removeInstances( scene.__webglObjectsImmediate, object );
4073

4074
		}
4075

4076
		object.__webglActive = false;
4077

4078
	};
4079

4080
	function removeInstances ( objlist, object ) {
4081

4082
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4083

4084
			if ( objlist[ o ].object === object ) {
4085

4086
				objlist.splice( o, 1 );
4087

4088
			}
4089

4090
		}
4091

4092
	};
4093

4094
	function removeInstancesDirect ( objlist, object ) {
4095

4096
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4097

4098
			if ( objlist[ o ] === object ) {
4099

4100
				objlist.splice( o, 1 );
4101

4102
			}
4103

4104
		}
4105

4106
	};
4107

4108
	// Materials
4109

4110
	this.initMaterial = function ( material, lights, fog, object ) {
4111

4112
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
4113

4114
		if ( material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
4115

4116
			shaderID = 'depth';
4117

4118
		} else if ( material instanceof THREE.MeshNormalMaterial ) {
4119

4120
			shaderID = 'normal';
M
Mr.doob 已提交
4121

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

4124
			shaderID = 'basic';
M
Mr.doob 已提交
4125

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

4128
			shaderID = 'lambert';
M
Mr.doob 已提交
4129

4130
		} else if ( material instanceof THREE.MeshPhongMaterial ) {
4131

4132
			shaderID = 'phong';
4133

4134
		} else if ( material instanceof THREE.LineBasicMaterial ) {
4135

4136
			shaderID = 'basic';
4137

4138
		} else if ( material instanceof THREE.ParticleBasicMaterial ) {
4139

4140
			shaderID = 'particle_basic';
4141 4142 4143

		}

4144
		if ( shaderID ) {
4145

4146
			setMaterialShaders( material, THREE.ShaderLib[ shaderID ] );
4147

4148
		}
4149

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

4153
		maxLightCount = allocateLights( lights );
4154

4155
		maxShadows = allocateShadows( lights );
4156

4157
		maxBones = allocateBones( object );
4158

4159
		parameters = {
4160

4161 4162 4163 4164 4165 4166
			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,
A
alteredq 已提交
4167
			morphNormals: material.morphNormals,
4168
			maxMorphTargets: this.maxMorphTargets,
A
alteredq 已提交
4169
			maxMorphNormals: this.maxMorphNormals,
4170 4171 4172 4173
			maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
			maxBones: maxBones,
			shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
			shadowMapSoft: this.shadowMapSoft,
A
alteredq 已提交
4174 4175
			shadowMapDebug: this.shadowMapDebug,
			shadowMapCascade: this.shadowMapCascade,
4176 4177 4178
			maxShadows: maxShadows,
			alphaTest: material.alphaTest,
			metal: material.metal,
4179 4180
			perPixel: material.perPixel,
			wrapAround: material.wrapAround
4181

4182
		};
M
Mr.doob 已提交
4183

4184
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
4185

4186
		var attributes = material.program.attributes;
4187

4188 4189 4190 4191
		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 );
4192

4193 4194 4195
		if ( material.skinning &&
			 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
M
Mr.doob 已提交
4196

4197 4198 4199 4200
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
M
Mr.doob 已提交
4201 4202

		}
4203

4204
		if ( material.attributes ) {
A
alteredq 已提交
4205

4206
			for ( a in material.attributes ) {
M
Mr.doob 已提交
4207

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

4210
			}
M
Mr.doob 已提交
4211

4212
		}
M
Mr.doob 已提交
4213

4214
		if ( material.morphTargets ) {
M
Mr.doob 已提交
4215

4216
			material.numSupportedMorphTargets = 0;
4217

4218
			var id, base = "morphTarget";
4219

4220
			for ( i = 0; i < this.maxMorphTargets; i ++ ) {
4221

4222
				id = base + i;
M
Mr.doob 已提交
4223

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

4226 4227
					_gl.enableVertexAttribArray( attributes[ id ] );
					material.numSupportedMorphTargets ++;
4228

4229
				}
4230

4231
			}
4232

4233
		}
4234

A
alteredq 已提交
4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255
		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

			var id, base = "morphNormal";

			for ( i = 0; i < this.maxMorphNormals; i ++ ) {

				id = base + i;

				if ( attributes[ id ] >= 0 ) {

					_gl.enableVertexAttribArray( attributes[ id ] );
					material.numSupportedMorphNormals ++;

				}

			}

		}

4256
		material.uniformsList = [];
4257

4258
		for ( u in material.uniforms ) {
4259

4260
			material.uniformsList.push( [ material.uniforms[ u ], u ] );
4261

4262
		}
M
Mr.doob 已提交
4263

4264
	};
M
Mr.doob 已提交
4265

4266
	function setMaterialShaders ( material, shaders ) {
M
Mr.doob 已提交
4267

4268 4269 4270
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
M
Mr.doob 已提交
4271

4272
	};
M
Mr.doob 已提交
4273

4274
	function setProgram ( camera, lights, fog, material, object ) {
4275

4276
		if ( ! material.program ) {
4277

4278
			_this.initMaterial( material, lights, fog, object );
4279

4280
		}
4281

4282
		if ( material.morphTargets ) {
4283

4284
			if ( ! object.__webglMorphTargetInfluences ) {
4285

4286
				object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );
4287

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

4290
					object.__webglMorphTargetInfluences[ i ] = 0;
4291

4292
				}
4293

4294
			}
4295

4296
		}
4297

4298
		var refreshMaterial = false;
4299

4300 4301 4302
		var program = material.program,
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
4303

4304
		if ( program !== _currentProgram ) {
4305

4306 4307
			_gl.useProgram( program );
			_currentProgram = program;
4308

4309
			refreshMaterial = true;
4310

4311
		}
4312

4313
		if ( material.id !== _currentMaterialId ) {
4314

4315 4316
			_currentMaterialId = material.id;
			refreshMaterial = true;
4317

4318
		}
4319

4320
		if ( refreshMaterial || camera !== _currentCamera ) {
4321

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

4324 4325 4326 4327 4328 4329
			if ( camera !== _currentCamera ) _currentCamera = camera;

		}

		if ( refreshMaterial ) {

4330
			// refresh uniforms common to several materials
4331

4332
			if ( fog && material.fog ) {
4333

4334
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
4335

4336
			}
M
Mr.doob 已提交
4337

4338 4339 4340
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material.lights ) {
4341

4342 4343
				setupLights( program, lights );
				refreshUniformsLights( m_uniforms, _lights );
4344

4345
			}
M
Mr.doob 已提交
4346

4347 4348 4349
			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
4350

4351
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
4352 4353 4354

			}

4355
			// refresh single material specific uniforms
M
Mr.doob 已提交
4356

4357
			if ( material instanceof THREE.LineBasicMaterial ) {
4358

4359
				refreshUniformsLine( m_uniforms, material );
M
Mr.doob 已提交
4360

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

4363
				refreshUniformsParticle( m_uniforms, material );
M
Mr.doob 已提交
4364

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

4367
				refreshUniformsPhong( m_uniforms, material );
M
Mr.doob 已提交
4368

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

4371
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
4372

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

4375 4376 4377
				m_uniforms.mNear.value = camera.near;
				m_uniforms.mFar.value = camera.far;
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4378

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

4381
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4382

4383
			}
M
Mr.doob 已提交
4384

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

4387
				refreshUniformsShadow( m_uniforms, lights );
M
Mr.doob 已提交
4388

4389
			}
M
Mr.doob 已提交
4390

4391
			// load common uniforms
M
Mr.doob 已提交
4392

4393
			loadUniformsGeneric( program, material.uniformsList );
M
Mr.doob 已提交
4394

4395 4396
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)
4397

4398 4399 4400
			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
				 material.envMap ) {
4401

4402
				if ( p_uniforms.cameraPosition !== null ) {
4403

4404 4405
					var position = camera.matrixWorld.getPosition();
					_gl.uniform3f( p_uniforms.cameraPosition, position.x, position.y, position.z );
4406

4407
				}
4408 4409 4410

			}

4411 4412 4413 4414
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {
4415

4416
				if ( p_uniforms.viewMatrix !== null ) {
4417

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

4420
				}
4421

4422
			}
M
Mr.doob 已提交
4423

4424
			if ( material.skinning ) {
4425

A
alteredq 已提交
4426
				_gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.boneMatrices );
4427

4428
			}
4429

4430
		}
M
Mr.doob 已提交
4431

4432
		loadUniformsMatrices( p_uniforms, object );
M
Mr.doob 已提交
4433

4434 4435 4436 4437
		if ( material instanceof THREE.ShaderMaterial ||
			 material.envMap ||
			 material.skinning ||
			 object.receiveShadow ) {
M
Mr.doob 已提交
4438

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

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

4443
			}
4444

4445
		}
4446

4447
		return program;
4448

4449
	};
4450

4451
	// Uniforms (refresh uniforms objects)
A
alteredq 已提交
4452

4453
	function refreshUniformsCommon ( uniforms, material ) {
4454

4455
		uniforms.opacity.value = material.opacity;
4456

4457
		if ( _this.gammaInput ) {
4458

4459
			uniforms.diffuse.value.copyGammaToLinear( material.color );
4460

4461
		} else {
4462

4463
			uniforms.diffuse.value = material.color;
4464

4465
		}
4466

4467
		uniforms.map.texture = material.map;
4468

4469
		if ( material.map ) {
4470

4471
			uniforms.offsetRepeat.value.set( material.map.offset.x, material.map.offset.y, material.map.repeat.x, material.map.repeat.y );
M
Mr.doob 已提交
4472

4473
		}
M
Mr.doob 已提交
4474

4475
		uniforms.lightMap.texture = material.lightMap;
4476

4477 4478
		uniforms.envMap.texture = material.envMap;
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
4479

4480
		if ( _this.gammaInput ) {
4481

4482 4483
			//uniforms.reflectivity.value = material.reflectivity * material.reflectivity;
			uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
4484

4485
		} else {
4486

4487
			uniforms.reflectivity.value = material.reflectivity;
4488

4489
		}
4490

4491 4492 4493
		uniforms.refractionRatio.value = material.refractionRatio;
		uniforms.combine.value = material.combine;
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
M
Mr.doob 已提交
4494

4495
	};
M
Mr.doob 已提交
4496

4497
	function refreshUniformsLine ( uniforms, material ) {
M
Mr.doob 已提交
4498

4499 4500
		uniforms.diffuse.value = material.color;
		uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4501

4502
	};
M
Mr.doob 已提交
4503

4504
	function refreshUniformsParticle ( uniforms, material ) {
4505

4506 4507 4508 4509
		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.
4510

4511
		uniforms.map.texture = material.map;
4512

4513
	};
4514

4515
	function refreshUniformsFog ( uniforms, fog ) {
4516

4517
		uniforms.fogColor.value = fog.color;
4518

4519
		if ( fog instanceof THREE.Fog ) {
4520

4521 4522
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
4523

4524
		} else if ( fog instanceof THREE.FogExp2 ) {
M
Mikael Emtinger 已提交
4525

4526
			uniforms.fogDensity.value = fog.density;
M
Mikael Emtinger 已提交
4527

4528
		}
M
Mikael Emtinger 已提交
4529

4530
	};
M
Mikael Emtinger 已提交
4531

4532
	function refreshUniformsPhong ( uniforms, material ) {
M
Mikael Emtinger 已提交
4533

4534
		uniforms.shininess.value = material.shininess;
4535

4536
		if ( _this.gammaInput ) {
M
Mikael Emtinger 已提交
4537

4538 4539
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
			uniforms.specular.value.copyGammaToLinear( material.specular );
4540

4541
		} else {
4542

4543 4544
			uniforms.ambient.value = material.ambient;
			uniforms.specular.value = material.specular;
4545

4546
		}
4547

4548 4549 4550 4551 4552 4553
		if ( material.wrapAround ) {

			uniforms.wrapRGB.value.copy( material.wrapRGB );

		}

4554
	};
4555

4556
	function refreshUniformsLambert ( uniforms, material ) {
4557

4558
		if ( _this.gammaInput ) {
4559

4560
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
M
Mr.doob 已提交
4561

4562
		} else {
4563

4564
			uniforms.ambient.value = material.ambient;
4565

4566
		}
4567

4568 4569 4570 4571 4572 4573
		if ( material.wrapAround ) {

			uniforms.wrapRGB.value.copy( material.wrapRGB );

		}

4574
	};
4575

4576
	function refreshUniformsLights ( uniforms, lights ) {
4577

4578
		uniforms.ambientLightColor.value = lights.ambient;
4579

4580 4581
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
4582

4583 4584 4585
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
		uniforms.pointLightDistance.value = lights.point.distances;
4586

4587
	};
4588

4589
	function refreshUniformsShadow ( uniforms, lights ) {
M
Mr.doob 已提交
4590

4591
		if ( uniforms.shadowMatrix ) {
4592

4593
			var j = 0;
4594

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

4597
				var light = lights[ i ];
4598

A
alteredq 已提交
4599 4600
				if ( ! light.castShadow ) continue;

4601
				if ( light instanceof THREE.SpotLight || ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) ) {
4602 4603 4604

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

4606 4607 4608 4609 4610 4611 4612 4613 4614 4615
					uniforms.shadowMatrix.value[ j ] = light.shadowMatrix;

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

					j ++;

				}

			}
4616

4617 4618
		}

4619
	};
4620

4621
	// Uniforms (load to GPU)
4622

4623
	function loadUniformsMatrices ( uniforms, object ) {
4624

4625
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
4626

4627
		if ( uniforms.normalMatrix ) {
4628

4629
			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );
4630

4631
		}
4632

4633
	};
4634

4635
	function loadUniformsGeneric ( program, uniforms ) {
4636

4637
		var uniform, value, type, location, texture, i, il, j, jl, offset;
4638

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

4641 4642
			location = program.uniforms[ uniforms[ j ][ 1 ] ];
			if ( !location ) continue;
4643

4644
			uniform = uniforms[ j ][ 0 ];
4645

4646 4647
			type = uniform.type;
			value = uniform.value;
4648

4649
			// single integer
4650

4651
			if( type === "i" ) {
4652

4653
				_gl.uniform1i( location, value );
4654

4655
			// single float
4656

4657
			} else if( type === "f" ) {
4658

4659
				_gl.uniform1f( location, value );
4660

4661
			// single THREE.Vector2
4662

4663
			} else if( type === "v2" ) {
4664

4665
				_gl.uniform2f( location, value.x, value.y );
4666

4667
			// single THREE.Vector3
4668

4669
			} else if( type === "v3" ) {
4670

4671
				_gl.uniform3f( location, value.x, value.y, value.z );
4672

4673
			// single THREE.Vector4
4674

4675
			} else if( type === "v4" ) {
4676

4677
				_gl.uniform4f( location, value.x, value.y, value.z, value.w );
4678

4679
			// single THREE.Color
4680

4681
			} else if( type === "c" ) {
4682

4683
				_gl.uniform3f( location, value.r, value.g, value.b );
4684

4685
			// flat array of floats (JS or typed array)
4686

4687
			} else if( type === "fv1" ) {
4688

4689
				_gl.uniform1fv( location, value );
4690

4691
			// flat array of floats with 3 x N size (JS or typed array)
4692

4693
			} else if( type === "fv" ) {
4694

4695
				_gl.uniform3fv( location, value );
4696

4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717
			// array of THREE.Vector2

			} else if( type === "v2v" ) {

				if ( ! uniform._array ) {

					uniform._array = new Float32Array( 2 * value.length );

				}

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

					offset = i * 2;

					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;

				}

				_gl.uniform2fv( location, uniform._array );

4718
			// array of THREE.Vector3
4719

4720
			} else if( type === "v3v" ) {
4721

4722
				if ( ! uniform._array ) {
4723

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

4726
				}
A
alteredq 已提交
4727

4728
				for ( i = 0, il = value.length; i < il; i ++ ) {
A
alteredq 已提交
4729

4730
					offset = i * 3;
4731

4732 4733 4734
					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;
					uniform._array[ offset + 2 ] = value[ i ].z;
4735

4736
				}
4737

4738
				_gl.uniform3fv( location, uniform._array );
A
alteredq 已提交
4739

4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761
			// array of THREE.Vector4

			} else if( type == "v4v" ) {

				if ( ! uniform._array ) {

					uniform._array = new Float32Array( 4 * value.length );

				}

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

					offset = i * 4;

					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;
					uniform._array[ offset + 2 ] = value[ i ].z;
					uniform._array[ offset + 3 ] = value[ i ].w;

				}

				_gl.uniform4fv( location, uniform._array );
4762

4763
			// single THREE.Matrix4
4764

4765
			} else if( type === "m4" ) {
M
Mr.doob 已提交
4766

4767
				if ( ! uniform._array ) {
A
alteredq 已提交
4768

4769
					uniform._array = new Float32Array( 16 );
4770

4771
				}
4772

4773 4774
				value.flattenToArray( uniform._array );
				_gl.uniformMatrix4fv( location, false, uniform._array );
4775

4776
			// array of THREE.Matrix4
4777

4778
			} else if( type === "m4v" ) {
A
alteredq 已提交
4779

4780 4781 4782
				if ( ! uniform._array ) {

					uniform._array = new Float32Array( 16 * value.length );
A
alteredq 已提交
4783

M
Mr.doob 已提交
4784
				}
M
Mr.doob 已提交
4785

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

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

4790
				}
A
alteredq 已提交
4791

4792
				_gl.uniformMatrix4fv( location, false, uniform._array );
M
Mr.doob 已提交
4793

4794

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

4797
			} else if( type === "t" ) {
A
alteredq 已提交
4798

4799
				_gl.uniform1i( location, value );
4800

4801
				texture = uniform.texture;
A
alteredq 已提交
4802

4803
				if ( !texture ) continue;
A
alteredq 已提交
4804

4805
				if ( texture.image instanceof Array && texture.image.length === 6 ) {
A
alteredq 已提交
4806

4807
					setCubeTexture( texture, value );
A
alteredq 已提交
4808

4809
				} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
M
Mr.doob 已提交
4810

4811 4812 4813 4814
					setCubeTextureDynamic( texture, value );

				} else {

4815
					_this.setTexture( texture, value );
4816

M
Mr.doob 已提交
4817
				}
M
Mr.doob 已提交
4818

4819
			// array of THREE.Texture (2d)
M
Mr.doob 已提交
4820

4821
			} else if( type === "tv" ) {
M
Mr.doob 已提交
4822

4823
				if ( ! uniform._array ) {
M
Mr.doob 已提交
4824

4825
					uniform._array = [];
A
alteredq 已提交
4826

4827 4828 4829 4830 4831
					for( i = 0, il = uniform.texture.length; i < il; i ++ ) {

						uniform._array[ i ] = value + i;

					}
A
alteredq 已提交
4832

M
Mr.doob 已提交
4833
				}
A
alteredq 已提交
4834

4835
				_gl.uniform1iv( location, uniform._array );
A
alteredq 已提交
4836

4837
				for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
4838

4839
					texture = uniform.texture[ i ];
4840

4841
					if ( !texture ) continue;
M
Mr.doob 已提交
4842

4843
					_this.setTexture( texture, uniform._array[ i ] );
M
Mr.doob 已提交
4844

M
Mr.doob 已提交
4845
				}
M
Mr.doob 已提交
4846

M
Mr.doob 已提交
4847
			}
M
Mr.doob 已提交
4848

M
Mr.doob 已提交
4849
		}
M
Mr.doob 已提交
4850

4851
	};
M
Mr.doob 已提交
4852

A
alteredq 已提交
4853
	function setupMatrices ( object, camera ) {
M
Mr.doob 已提交
4854

4855
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
M
Mr.doob 已提交
4856

4857
		var inverseMatrix = THREE.Matrix4.makeInvert3x3( object._modelViewMatrix );
4858

4859
		if ( inverseMatrix ) {
4860

4861
			inverseMatrix.transposeIntoArray( object._normalMatrixArray );
M
Mr.doob 已提交
4862

4863
		}
M
Mr.doob 已提交
4864

A
alteredq 已提交
4865
	};
M
Mr.doob 已提交
4866

4867
	function setupLights ( program, lights ) {
M
Mr.doob 已提交
4868

4869 4870 4871
		var l, ll, light, n,
		r = 0, g = 0, b = 0,
		color, position, intensity, distance,
M
Mr.doob 已提交
4872

4873
		zlights = _lights,
A
alteredq 已提交
4874

4875 4876
		dcolors = zlights.directional.colors,
		dpositions = zlights.directional.positions,
A
alteredq 已提交
4877

4878 4879 4880
		pcolors = zlights.point.colors,
		ppositions = zlights.point.positions,
		pdistances = zlights.point.distances,
4881

4882 4883
		dlength = 0,
		plength = 0,
4884

4885 4886
		doffset = 0,
		poffset = 0;
4887

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

4890
			light = lights[ l ];
A
alteredq 已提交
4891

A
alteredq 已提交
4892 4893 4894
			if ( light.onlyShadow ) continue;

			color = light.color;
4895 4896
			intensity = light.intensity;
			distance = light.distance;
A
alteredq 已提交
4897

4898
			if ( light instanceof THREE.AmbientLight ) {
4899

4900
				if ( _this.gammaInput ) {
4901

4902 4903 4904
					r += color.r * color.r;
					g += color.g * color.g;
					b += color.b * color.b;
4905

4906
				} else {
4907

4908 4909 4910
					r += color.r;
					g += color.g;
					b += color.b;
4911

4912
				}
4913

4914
			} else if ( light instanceof THREE.DirectionalLight ) {
4915

4916
				doffset = dlength * 3;
4917

4918
				if ( _this.gammaInput ) {
4919

4920 4921 4922
					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;
4923

4924
				} else {
4925

4926 4927 4928
					dcolors[ doffset ]     = color.r * intensity;
					dcolors[ doffset + 1 ] = color.g * intensity;
					dcolors[ doffset + 2 ] = color.b * intensity;
A
alteredq 已提交
4929

4930
				}
A
alteredq 已提交
4931

4932 4933 4934
				_direction.copy( light.matrixWorld.getPosition() );
				_direction.subSelf( light.target.matrixWorld.getPosition() );
				_direction.normalize();
A
alteredq 已提交
4935

4936 4937 4938
				dpositions[ doffset ]     = _direction.x;
				dpositions[ doffset + 1 ] = _direction.y;
				dpositions[ doffset + 2 ] = _direction.z;
A
alteredq 已提交
4939

4940
				dlength += 1;
A
alteredq 已提交
4941

4942
			} else if( light instanceof THREE.PointLight || light instanceof THREE.SpotLight ) {
M
Mr.doob 已提交
4943

4944
				poffset = plength * 3;
M
Mr.doob 已提交
4945

4946
				if ( _this.gammaInput ) {
4947

4948 4949 4950
					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 已提交
4951

4952
				} else {
A
alteredq 已提交
4953

4954 4955 4956
					pcolors[ poffset ]     = color.r * intensity;
					pcolors[ poffset + 1 ] = color.g * intensity;
					pcolors[ poffset + 2 ] = color.b * intensity;
A
alteredq 已提交
4957

4958
				}
A
alteredq 已提交
4959

A
alteredq 已提交
4960 4961
				position = light.matrixWorld.getPosition();

4962 4963 4964
				ppositions[ poffset ]     = position.x;
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
A
alteredq 已提交
4965

4966
				pdistances[ plength ] = distance;
A
alteredq 已提交
4967

4968
				plength += 1;
4969

4970
			}
4971

4972
		}
A
alteredq 已提交
4973

4974 4975
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
A
alteredq 已提交
4976

4977 4978
		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 已提交
4979

4980 4981
		zlights.point.length = plength;
		zlights.directional.length = dlength;
A
alteredq 已提交
4982

4983 4984 4985
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
4986

4987
	};
M
Mr.doob 已提交
4988

4989
	// GL state setting
M
Mr.doob 已提交
4990

4991
	this.setFaceCulling = function ( cullFace, frontFace ) {
M
Mr.doob 已提交
4992

4993
		if ( cullFace ) {
M
Mr.doob 已提交
4994

4995
			if ( !frontFace || frontFace === "ccw" ) {
4996

4997
				_gl.frontFace( _gl.CCW );
4998

4999
			} else {
5000

5001
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
5002

5003
			}
M
Mr.doob 已提交
5004

5005
			if( cullFace === "back" ) {
5006

5007
				_gl.cullFace( _gl.BACK );
5008

5009
			} else if( cullFace === "front" ) {
5010

5011
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
5012

5013
			} else {
5014

5015
				_gl.cullFace( _gl.FRONT_AND_BACK );
5016

5017
			}
5018

5019
			_gl.enable( _gl.CULL_FACE );
5020

5021
		} else {
5022

5023
			_gl.disable( _gl.CULL_FACE );
5024 5025 5026 5027 5028

		}

	};

A
alteredq 已提交
5029
	this.setObjectFaces = function ( object ) {
5030

5031
		if ( _oldDoubleSided !== object.doubleSided ) {
M
Mr.doob 已提交
5032

5033
			if( object.doubleSided ) {
M
Mr.doob 已提交
5034

5035
				_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
5036

5037
			} else {
5038

5039
				_gl.enable( _gl.CULL_FACE );
5040

5041
			}
5042

5043
			_oldDoubleSided = object.doubleSided;
5044

5045
		}
5046

5047
		if ( _oldFlipSided !== object.flipSided ) {
5048

5049
			if( object.flipSided ) {
5050

5051
				_gl.frontFace( _gl.CW );
5052

5053
			} else {
5054

5055
				_gl.frontFace( _gl.CCW );
5056

5057
			}
5058

5059
			_oldFlipSided = object.flipSided;
5060

5061
		}
5062

5063
	};
5064

A
alteredq 已提交
5065
	this.setDepthTest = function ( depthTest ) {
5066

5067
		if ( _oldDepthTest !== depthTest ) {
5068

5069
			if ( depthTest ) {
5070

5071
				_gl.enable( _gl.DEPTH_TEST );
5072

5073
			} else {
5074

5075
				_gl.disable( _gl.DEPTH_TEST );
5076 5077 5078

			}

5079
			_oldDepthTest = depthTest;
5080

5081
		}
5082

5083
	};
5084

5085
	this.setDepthWrite = function ( depthWrite ) {
A
alteredq 已提交
5086

5087
		if ( _oldDepthWrite !== depthWrite ) {
A
alteredq 已提交
5088

5089 5090
			_gl.depthMask( depthWrite );
			_oldDepthWrite = depthWrite;
A
alteredq 已提交
5091 5092 5093 5094 5095

		}

	};

5096
	function setLineWidth ( width ) {
5097

5098
		if ( width !== _oldLineWidth ) {
5099

5100 5101 5102
			_gl.lineWidth( width );

			_oldLineWidth = width;
5103 5104 5105

		}

5106
	};
5107

5108
	function setPolygonOffset ( polygonoffset, factor, units ) {
5109

5110
		if ( _oldPolygonOffset !== polygonoffset ) {
M
Mr.doob 已提交
5111

5112
			if ( polygonoffset ) {
5113

5114
				_gl.enable( _gl.POLYGON_OFFSET_FILL );
5115

5116
			} else {
5117

5118
				_gl.disable( _gl.POLYGON_OFFSET_FILL );
5119

5120
			}
5121

5122
			_oldPolygonOffset = polygonoffset;
5123

5124
		}
5125

5126
		if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
5127

5128
			_gl.polygonOffset( factor, units );
M
Mr.doob 已提交
5129

5130 5131
			_oldPolygonOffsetFactor = factor;
			_oldPolygonOffsetUnits = units;
M
Mr.doob 已提交
5132

5133
		}
M
Mr.doob 已提交
5134

5135
	};
M
Mr.doob 已提交
5136

5137
	this.setBlending = function ( blending ) {
M
Mr.doob 已提交
5138

5139
		if ( blending !== _oldBlending ) {
M
Mr.doob 已提交
5140

5141
			switch ( blending ) {
M
Mr.doob 已提交
5142

5143
				case THREE.AdditiveBlending:
M
Mr.doob 已提交
5144

5145 5146
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
M
Mr.doob 已提交
5147

5148
					break;
M
Mr.doob 已提交
5149

5150
				case THREE.SubtractiveBlending:
M
Mr.doob 已提交
5151

5152
					// TODO: Find blendFuncSeparate() combination
M
Mr.doob 已提交
5153

5154 5155
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
M
Mr.doob 已提交
5156

5157
					break;
M
Mr.doob 已提交
5158

5159
				case THREE.MultiplyBlending:
M
Mr.doob 已提交
5160

5161
					// TODO: Find blendFuncSeparate() combination
M
Mr.doob 已提交
5162

5163 5164
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
M
Mr.doob 已提交
5165

5166
					break;
5167

5168
				default:
N
Nicolas Garcia Belmonte 已提交
5169

5170 5171
					_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 );
5172

5173
					break;
5174

5175
			}
5176

5177
			_oldBlending = blending;
5178

5179
		}
5180 5181

	};
5182

5183 5184 5185
	// Shaders

	function buildProgram ( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
5186

5187
		var p, pl, program, code;
5188
		var chunks = [];
5189 5190 5191

		// Generate code

5192 5193 5194 5195 5196 5197 5198 5199 5200 5201
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

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

		}
5202 5203 5204

		for ( p in parameters ) {

5205 5206
			chunks.push( p );
			chunks.push( parameters[ p ] );
5207 5208 5209

		}

5210 5211
		code = chunks.join();

5212 5213 5214 5215
		// Check if code has been already compiled

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

5216
			if ( _programs[ p ].code === code ) {
5217 5218

				// console.log( "Code already compiled." /*: \n\n" + code*/ );
5219

5220 5221 5222 5223 5224
				return _programs[ p ].program;

			}

		}
5225

5226
		//console.log( "building new program " );
5227 5228 5229

		//

5230
		program = _gl.createProgram();
M
Mr.doob 已提交
5231

5232
		var prefix_vertex = [
M
Mr.doob 已提交
5233

5234
			( _maxVertexTextures > 0 ) ? "#define VERTEX_TEXTURES" : "",
5235

5236 5237 5238 5239
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

5240 5241 5242
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

5243 5244
			"#define MAX_SHADOWS " + parameters.maxShadows,

5245 5246
			"#define MAX_BONES " + parameters.maxBones,

5247
			parameters.map ? "#define USE_MAP" : "",
5248 5249 5250
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5251
			parameters.skinning ? "#define USE_SKINNING" : "",
5252
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
A
alteredq 已提交
5253
			parameters.morphNormals ? "#define USE_MORPHNORMALS" : "",
A
alteredq 已提交
5254
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
5255
			parameters.wrapAround ? "#define WRAP_AROUND" : "",
5256

5257
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5258
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
A
alteredq 已提交
5259 5260
			parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
			parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
5261

5262 5263
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
5264 5265 5266
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
5267 5268
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
5269
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
5270

M
Mr.doob 已提交
5271 5272 5273
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
5274
			"attribute vec2 uv2;",
5275

5276
			"#ifdef USE_COLOR",
5277

5278
				"attribute vec3 color;",
5279

5280 5281
			"#endif",

5282
			"#ifdef USE_MORPHTARGETS",
5283

5284 5285 5286 5287
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
A
alteredq 已提交
5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303

				"#ifdef USE_MORPHNORMALS",

					"attribute vec3 morphNormal0;",
					"attribute vec3 morphNormal1;",
					"attribute vec3 morphNormal2;",
					"attribute vec3 morphNormal3;",

				"#else",

					"attribute vec3 morphTarget4;",
					"attribute vec3 morphTarget5;",
					"attribute vec3 morphTarget6;",
					"attribute vec3 morphTarget7;",

				"#endif",
5304

5305 5306 5307
			"#endif",

			"#ifdef USE_SKINNING",
5308

5309 5310 5311 5312
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
5313

5314
			"#endif",
5315

M
Mr.doob 已提交
5316
			""
A
alteredq 已提交
5317

M
Mr.doob 已提交
5318
		].join("\n");
5319

M
Mr.doob 已提交
5320 5321
		var prefix_fragment = [

5322
			"precision " + _precision + " float;",
M
Mr.doob 已提交
5323 5324 5325 5326

			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

5327 5328
			"#define MAX_SHADOWS " + parameters.maxShadows,

5329 5330
			parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",

5331 5332 5333 5334
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

M
Mr.doob 已提交
5335 5336
			( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
			( parameters.useFog && parameters.fog instanceof THREE.FogExp2 ) ? "#define FOG_EXP2" : "",
M
Mr.doob 已提交
5337 5338 5339 5340 5341

			parameters.map ? "#define USE_MAP" : "",
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5342

5343 5344
			parameters.metal ? "#define METAL" : "",
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
5345
			parameters.wrapAround ? "#define WRAP_AROUND" : "",
5346

5347
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5348
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
A
alteredq 已提交
5349 5350
			parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
			parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
M
Mr.doob 已提交
5351 5352 5353 5354 5355 5356 5357

			"uniform mat4 viewMatrix;",
			"uniform vec3 cameraPosition;",
			""

		].join("\n");

5358 5359
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
5360

M
Mr.doob 已提交
5361
		_gl.linkProgram( program );
N
Nicolas Garcia Belmonte 已提交
5362

M
Mr.doob 已提交
5363
		if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
N
Nicolas Garcia Belmonte 已提交
5364

5365
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
5366

N
Nicolas Garcia Belmonte 已提交
5367
		}
5368

5369 5370
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
5371

M
Mr.doob 已提交
5372
		program.uniforms = {};
5373
		program.attributes = {};
M
Mr.doob 已提交
5374

5375 5376 5377 5378
		var identifiers, u, a, i;

		// cache uniform locations

5379
		identifiers = [
5380

5381
			'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
A
alteredq 已提交
5382
			'boneGlobalMatrices', 'morphTargetInfluences'
M
Mr.doob 已提交
5383

5384
		];
M
Mr.doob 已提交
5385

5386
		for ( u in uniforms ) {
M
Mr.doob 已提交
5387

5388
			identifiers.push( u );
M
Mr.doob 已提交
5389

5390
		}
M
Mr.doob 已提交
5391

5392
		cacheUniformLocations( program, identifiers );
M
Mr.doob 已提交
5393

5394
		// cache attributes locations
M
Mr.doob 已提交
5395

5396
		identifiers = [
A
alteredq 已提交
5397

5398 5399
			"position", "normal", "uv", "uv2", "tangent", "color",
			"skinVertexA", "skinVertexB", "skinIndex", "skinWeight"
A
alteredq 已提交
5400

5401
		];
M
Mr.doob 已提交
5402

5403
		for ( i = 0; i < parameters.maxMorphTargets; i ++ ) {
M
Mr.doob 已提交
5404

5405
			identifiers.push( "morphTarget" + i );
M
Mr.doob 已提交
5406

5407
		}
5408

A
alteredq 已提交
5409 5410 5411 5412 5413 5414
		for ( i = 0; i < parameters.maxMorphNormals; i ++ ) {

			identifiers.push( "morphNormal" + i );

		}

5415
		for ( a in attributes ) {
5416

5417
			identifiers.push( a );
5418

5419
		}
5420

5421
		cacheAttributeLocations( program, identifiers );
5422

5423
		program.id = _programs.length;
5424

5425
		_programs.push( { program: program, code: code } );
5426

5427
		_this.info.memory.programs = _programs.length;
5428

5429
		return program;
5430

5431
	};
5432

5433
	// Shader parameters cache
5434

5435
	function cacheUniformLocations ( program, identifiers ) {
5436

5437
		var i, l, id;
5438

5439
		for( i = 0, l = identifiers.length; i < l; i ++ ) {
5440

5441 5442
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
5443

5444
		}
M
Mr.doob 已提交
5445

5446
	};
M
Mr.doob 已提交
5447

5448
	function cacheAttributeLocations ( program, identifiers ) {
A
alteredq 已提交
5449

5450
		var i, l, id;
A
alteredq 已提交
5451

5452
		for( i = 0, l = identifiers.length; i < l; i ++ ) {
A
alteredq 已提交
5453

5454 5455
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
A
alteredq 已提交
5456

5457
		}
5458

5459
	};
A
alteredq 已提交
5460

5461
	function getShader ( type, string ) {
A
alteredq 已提交
5462

5463
		var shader;
5464

5465
		if ( type === "fragment" ) {
A
alteredq 已提交
5466

5467
			shader = _gl.createShader( _gl.FRAGMENT_SHADER );
A
alteredq 已提交
5468

5469
		} else if ( type === "vertex" ) {
A
alteredq 已提交
5470

5471
			shader = _gl.createShader( _gl.VERTEX_SHADER );
A
alteredq 已提交
5472

5473
		}
A
alteredq 已提交
5474

5475 5476
		_gl.shaderSource( shader, string );
		_gl.compileShader( shader );
5477

5478
		if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {
5479

5480 5481 5482
			console.error( _gl.getShaderInfoLog( shader ) );
			console.error( string );
			return null;
5483

A
alteredq 已提交
5484 5485
		}

5486 5487
		return shader;

A
alteredq 已提交
5488
	};
5489

5490 5491
	// Textures

5492 5493 5494 5495 5496 5497 5498

	function isPowerOfTwo ( value ) {

		return ( value & ( value - 1 ) ) === 0;

	};

5499
	function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {
5500

5501
		if ( isImagePowerOfTwo ) {
M
Mr.doob 已提交
5502

5503 5504
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
5505

5506 5507
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
5508

5509
		} else {
M
Mr.doob 已提交
5510

5511 5512
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
5513

5514 5515
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
5516

5517
		}
M
Mr.doob 已提交
5518

5519
	};
5520

5521
	this.setTexture = function ( texture, slot ) {
5522

5523
		if ( texture.needsUpdate ) {
A
alteredq 已提交
5524

5525
			if ( ! texture.__webglInit ) {
M
Mr.doob 已提交
5526

5527
				texture.__webglInit = true;
5528
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5529

M
Mr.doob 已提交
5530 5531
				_this.info.memory.textures ++;

5532
			}
M
Mr.doob 已提交
5533

5534
			_gl.activeTexture( _gl.TEXTURE0 + slot );
5535 5536
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );

5537 5538
			var image = texture.image,
			isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
5539 5540
			glFormat = paramThreeToGL( texture.format ),
			glType = paramThreeToGL( texture.type );
5541

5542 5543
			setTextureParameters( _gl.TEXTURE_2D, texture, isImagePowerOfTwo );

5544
			if ( texture instanceof THREE.DataTexture ) {
5545

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

A
alteredq 已提交
5548
			} else {
M
Mr.doob 已提交
5549

5550
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, texture.image );
M
Mr.doob 已提交
5551 5552 5553

			}

5554
			if ( texture.generateMipmaps && isImagePowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
M
Mr.doob 已提交
5555

A
alteredq 已提交
5556
			texture.needsUpdate = false;
5557

5558 5559
			if ( texture.onUpdated ) texture.onUpdated();

5560
		} else {
5561

5562 5563
			_gl.activeTexture( _gl.TEXTURE0 + slot );
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
5564 5565

		}
M
Mr.doob 已提交
5566

5567
	};
M
Mr.doob 已提交
5568

5569 5570 5571 5572 5573 5574 5575 5576 5577 5578
	function clampToMaxSize ( image, maxSize ) {

		if ( image.width <= maxSize && image.height <= maxSize ) {

			return image;

		}

		// Warning: Scaling through the canvas will only work with images that use
		// premultiplied alpha.
5579

5580 5581 5582 5583 5584 5585 5586
		var maxDimension = Math.max( image.width, image.height );
		var newWidth = Math.floor( image.width * maxSize / maxDimension );
		var newHeight = Math.floor( image.height * maxSize / maxDimension );

		var canvas = document.createElement( 'canvas' );
		canvas.width = newWidth;
		canvas.height = newHeight;
5587

5588
		var ctx = canvas.getContext( "2d" );
5589 5590
		ctx.drawImage( image, 0, 0, image.width, image.height, 0, 0, newWidth, newHeight );

5591 5592 5593 5594
		return canvas;

	}

5595
	function setCubeTexture ( texture, slot ) {
5596

5597
		if ( texture.image.length === 6 ) {
5598 5599 5600

			if ( texture.needsUpdate ) {

A
alteredq 已提交
5601
				if ( ! texture.image.__webglTextureCube ) {
5602 5603

					texture.image.__webglTextureCube = _gl.createTexture();
5604

A
alteredq 已提交
5605
				}
5606

A
alteredq 已提交
5607 5608
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5609

5610
				var cubeImage = [];
5611

A
alteredq 已提交
5612
				for ( var i = 0; i < 6; i ++ ) {
5613

5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625
					if ( _this.autoScaleCubemaps ) {

						cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize );

					} else {

						cubeImage[ i ] = texture.image[ i ];

					}

				}

5626 5627
				var image = cubeImage[ 0 ],
				isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
5628 5629
				glFormat = paramThreeToGL( texture.format ),
				glType = paramThreeToGL( texture.type );
5630

5631 5632
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo );

A
alteredq 已提交
5633
				for ( var i = 0; i < 6; i ++ ) {
5634

5635
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
5636

A
alteredq 已提交
5637
				}
5638

5639
				if ( texture.generateMipmaps && isImagePowerOfTwo )	_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
5640

A
alteredq 已提交
5641
				texture.needsUpdate = false;
5642

5643 5644
				if ( texture.onUpdated ) texture.onUpdated();

A
alteredq 已提交
5645
			} else {
5646

A
alteredq 已提交
5647 5648
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5649

A
alteredq 已提交
5650
			}
5651

A
alteredq 已提交
5652
		}
5653

A
alteredq 已提交
5654
	};
5655

5656
	function setCubeTextureDynamic ( texture, slot ) {
5657

A
alteredq 已提交
5658 5659
		_gl.activeTexture( _gl.TEXTURE0 + slot );
		_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
5660 5661 5662

	};

5663 5664 5665
	// Render targets

	function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
5666

5667 5668
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
A
alteredq 已提交
5669

5670
	};
M
Mr.doob 已提交
5671

5672
	function setupRenderBuffer ( renderbuffer, renderTarget  ) {
M
Mikael Emtinger 已提交
5673

5674
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
5675

5676
		if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
M
Mr.doob 已提交
5677

5678 5679
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5680

5681 5682
		/* For some reason this is not working. Defaulting to RGBA4.
		} else if( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
A
alteredq 已提交
5683

5684 5685 5686 5687
			_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 已提交
5688

5689 5690
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5691

5692
		} else {
A
alteredq 已提交
5693

5694
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
A
alteredq 已提交
5695

5696
		}
A
alteredq 已提交
5697

5698
	};
A
alteredq 已提交
5699

A
alteredq 已提交
5700
	this.setRenderTarget = function ( renderTarget ) {
A
alteredq 已提交
5701

5702
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
A
alteredq 已提交
5703

5704
		if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
A
alteredq 已提交
5705

5706 5707
			if( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
			if( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
A
alteredq 已提交
5708

5709
			renderTarget.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5710

5711
			// Setup texture, create render and frame buffers
5712

5713 5714
			var isTargetPowerOfTwo = isPowerOfTwo( renderTarget.width ) && isPowerOfTwo( renderTarget.height ),
				glFormat = paramThreeToGL( renderTarget.format ),
5715 5716
				glType = paramThreeToGL( renderTarget.type );

5717
			if ( isCube ) {
M
Mr.doob 已提交
5718

5719 5720
				renderTarget.__webglFramebuffer = [];
				renderTarget.__webglRenderbuffer = [];
M
Mikael Emtinger 已提交
5721

5722
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
5723
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, isTargetPowerOfTwo );
A
alteredq 已提交
5724

5725
				for ( var i = 0; i < 6; i ++ ) {
A
alteredq 已提交
5726

5727 5728
					renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
					renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
A
alteredq 已提交
5729

5730
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
A
alteredq 已提交
5731

5732 5733
					setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
					setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
A
alteredq 已提交
5734

5735
				}
5736

5737
			} else {
5738

5739 5740
				renderTarget.__webglFramebuffer = _gl.createFramebuffer();
				renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
5741

5742
				_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
5743
				setTextureParameters( _gl.TEXTURE_2D, renderTarget, isTargetPowerOfTwo );
5744

5745
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
5746

5747 5748
				setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
				setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
5749

M
Mikael Emtinger 已提交
5750
			}
5751

5752
			// Release everything
M
Mr.doob 已提交
5753

A
alteredq 已提交
5754 5755 5756 5757 5758 5759 5760 5761 5762 5763
			if ( isCube ) {

				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

			} else {

				_gl.bindTexture( _gl.TEXTURE_2D, null );

			}

5764 5765
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
5766

5767 5768
		}

5769
		var framebuffer, width, height, vx, vy;
M
Mr.doob 已提交
5770

5771
		if ( renderTarget ) {
M
Mr.doob 已提交
5772

A
alteredq 已提交
5773 5774
			if ( isCube ) {

5775
				framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
A
alteredq 已提交
5776 5777 5778

			} else {

5779
				framebuffer = renderTarget.__webglFramebuffer;
A
alteredq 已提交
5780 5781 5782

			}

5783 5784
			width = renderTarget.width;
			height = renderTarget.height;
M
Mr.doob 已提交
5785

5786 5787 5788
			vx = 0;
			vy = 0;

5789
		} else {
M
Mr.doob 已提交
5790

5791
			framebuffer = null;
5792

5793 5794
			width = _viewportWidth;
			height = _viewportHeight;
5795

5796 5797
			vx = _viewportX;
			vy = _viewportY;
M
Mr.doob 已提交
5798

5799
		}
M
Mr.doob 已提交
5800

5801
		if ( framebuffer !== _currentFramebuffer ) {
M
Mr.doob 已提交
5802

5803
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
5804
			_gl.viewport( vx, vy, width, height );
M
Mr.doob 已提交
5805

5806
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
5807

5808
		}
5809

A
alteredq 已提交
5810 5811 5812
		_currentWidth = width;
		_currentHeight = height;

5813
	};
M
Mr.doob 已提交
5814

5815
	function updateRenderTargetMipmap ( renderTarget ) {
M
Mr.doob 已提交
5816

A
alteredq 已提交
5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829
		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 已提交
5830 5831

	};
5832

5833
	// Fallback filters for non-power-of-2 textures
5834

5835
	function filterFallback ( f ) {
5836

5837 5838 5839 5840 5841 5842 5843 5844
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mr.doob 已提交
5845
			case THREE.LinearMipMapLinearFilter:
M
Mikael Emtinger 已提交
5846
			default:
5847

M
Mikael Emtinger 已提交
5848
				return _gl.LINEAR; break;
5849 5850

		}
5851

5852
	};
5853

5854 5855
	// Map three.js constants to WebGL constants

5856
	function paramThreeToGL ( p ) {
M
Mr.doob 已提交
5857

5858
		switch ( p ) {
M
Mr.doob 已提交
5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871

			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;

5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885
			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;

5886
		}
M
Mr.doob 已提交
5887

5888
		return 0;
M
Mr.doob 已提交
5889

5890 5891
	};

5892
	// Allocations
5893

5894
	function allocateBones ( object ) {
5895

5896 5897 5898 5899 5900 5901 5902
		// 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)
5903

5904
		var maxBones = 50;
5905

5906
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
5907

5908 5909 5910 5911 5912
			maxBones = object.bones.length;

		}

		return maxBones;
5913

5914
	};
5915

5916
	function allocateLights ( lights ) {
5917

5918 5919
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
5920

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

5923
			light = lights[ l ];
5924

A
alteredq 已提交
5925 5926
			if ( light.onlyShadow ) continue;

5927 5928
			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
			if ( light instanceof THREE.PointLight ) pointLights ++;
5929
			if ( light instanceof THREE.SpotLight ) pointLights ++;
5930

5931
		}
5932

5933
		if ( ( pointLights + dirLights ) <= _maxLights ) {
5934

5935 5936
			maxDirLights = dirLights;
			maxPointLights = pointLights;
5937

5938
		} else {
5939

5940 5941
			maxDirLights = Math.ceil( _maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = _maxLights - maxDirLights;
5942 5943 5944

		}

5945
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
5946 5947

	};
M
Mr.doob 已提交
5948

5949
	function allocateShadows ( lights ) {
5950

M
Mr.doob 已提交
5951
		var l, ll, light, maxShadows = 0;
5952 5953 5954 5955 5956

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

			light = lights[ l ];

A
alteredq 已提交
5957 5958
			if ( ! light.castShadow ) continue;

5959 5960
			if ( light instanceof THREE.SpotLight ) maxShadows ++;
			if ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) maxShadows ++;
5961 5962 5963 5964 5965 5966 5967

		}

		return maxShadows;

	};

5968
	// Initialization
M
Mr.doob 已提交
5969

5970 5971 5972 5973 5974 5975
	function initGL () {

		var gl;

		try {

5976
			if ( ! ( gl = _canvas.getContext( 'experimental-webgl', { alpha: _alpha, premultipliedAlpha: _premultipliedAlpha, antialias: _antialias, stencil: _stencil, preserveDrawingBuffer: _preserveDrawingBuffer } ) ) ) {
5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020

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

	};

6021 6022
	// default plugins (order is important)

A
alteredq 已提交
6023 6024 6025 6026 6027
	this.shadowMapPlugin = new THREE.ShadowMapPlugin();
	this.addPrePlugin( this.shadowMapPlugin );

	this.addPostPlugin( new THREE.SpritePlugin() );
	this.addPostPlugin( new THREE.LensFlarePlugin() );
6028

6029
};