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

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

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

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

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

M
Mr.doob 已提交
16
	_precision = parameters.precision !== undefined ? parameters.precision : 'mediump',
17
	_antialias = parameters.antialias !== undefined ? parameters.antialias : false,
18
	_stencil = parameters.stencil !== undefined ? parameters.stencil : true,
19 20
	_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,

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

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

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

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

	// clearing
M
Mr.doob 已提交
32

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

38 39
	// scene graph

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

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

	// physically based shading

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

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

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

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

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

66
	// morphs
67

68
	this.maxMorphTargets = 8;
69

70 71
	// custom render plugins

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

75
	// info
76

77
	this.info = {
78

79
		memory: {
80

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

85
		},
86

87
		render: {
88

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

		}

96
	};
M
Mr.doob 已提交
97

98
	// internal properties
99

100
	var _this = this,
101

102
	_gl,
103

104
	_programs = [],
105

106
	// internal state cache
107

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

114
	// GL state cache
115

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

126 127 128 129
	_viewportX = 0,
	_viewportY = 0,
	_viewportWidth = 0,
	_viewportHeight = 0,
A
alteredq 已提交
130 131
	_currentWidth = 0,
	_currentHeight = 0,
132

A
alteredq 已提交
133
	// frustum
M
Mr.doob 已提交
134

A
alteredq 已提交
135
	_frustum = new THREE.Frustum(),
136

137
	 // camera matrices cache
M
Mikael Emtinger 已提交
138

139
	_projScreenMatrix = new THREE.Matrix4(),
M
Mr.doob 已提交
140

141
	_vector3 = new THREE.Vector4(),
M
Mikael Emtinger 已提交
142

143
	// light arrays cache
M
Mikael Emtinger 已提交
144

145
	_lights = {
M
Mr.doob 已提交
146

147 148 149
		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 已提交
150

151
	};
M
Mr.doob 已提交
152

153
	// initialize
M
Mikael Emtinger 已提交
154

155
	_gl = initGL();
M
Mikael Emtinger 已提交
156

157
	setDefaultGLState();
M
Mikael Emtinger 已提交
158

159
	this.context = _gl;
M
Mikael Emtinger 已提交
160

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

163
	// API
M
Mr.doob 已提交
164

165
	this.getContext = function () {
M
Mr.doob 已提交
166

167
		return _gl;
M
Mr.doob 已提交
168

169
	};
M
Mr.doob 已提交
170

171
	this.supportsVertexTextures = function () {
M
Mikael Emtinger 已提交
172

173
		return _supportsVertexTextures;
M
Mikael Emtinger 已提交
174

175
	};
M
Mikael Emtinger 已提交
176

N
Nicolas Garcia Belmonte 已提交
177 178 179 180
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
181

182 183 184
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
185

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

188 189
		_viewportX = x;
		_viewportY = y;
190

191 192
		_viewportWidth = width;
		_viewportHeight = height;
193

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

N
Nicolas Garcia Belmonte 已提交
196
	};
197

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

200
		_gl.scissor( x, y, width, height );
201

202
	};
203

204
	this.enableScissorTest = function ( enable ) {
205

M
Mr.doob 已提交
206
		enable ? _gl.enable( _gl.SCISSOR_TEST ) : _gl.disable( _gl.SCISSOR_TEST );
207 208

	};
209

210 211
	// Clearing

212
	this.setClearColorHex = function ( hex, alpha ) {
213

214 215 216 217
		_clearColor.setHex( hex );
		_clearAlpha = alpha;

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

219
	};
A
alteredq 已提交
220

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

223 224 225 226
		_clearColor.copy( color );
		_clearAlpha = alpha;

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

	};
229

M
Mr.doob 已提交
230 231 232 233 234 235 236
	this.getClearColor = function () {

		return _clearColor;

	};

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

M
Mr.doob 已提交
238 239 240 241 242 243 244 245
		return _clearAlpha;

	};

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

		var bits = 0;

246 247 248
		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 已提交
249 250

		_gl.clear( bits );
N
Nicolas Garcia Belmonte 已提交
251 252 253

	};

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

A
alteredq 已提交
256
		this.setRenderTarget( renderTarget );
257
		this.clear( color, depth, stencil );
M
Mr.doob 已提交
258 259 260

	};

261 262
	// Plugins

A
alteredq 已提交
263
	this.addPostPlugin = function ( plugin ) {
264 265

		plugin.init( this );
A
alteredq 已提交
266
		this.renderPluginsPost.push( plugin );
267 268 269

	};

A
alteredq 已提交
270 271 272 273 274 275
	this.addPrePlugin = function ( plugin ) {

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

	};
276

277 278
	// Deallocation

279 280 281 282 283 284 285 286 287 288 289 290 291 292
	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 ) {

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

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

324 325
	};

326
	// Rendering
327

328
	this.updateShadowMap = function ( scene, camera ) {
329

A
alteredq 已提交
330 331 332 333 334 335 336 337
		_currentProgram = null;
		_oldBlending = -1;
		_oldDepthTest = -1;
		_oldDepthWrite = -1;
		_currentGeometryGroupHash = -1;
		_currentMaterialId = -1;

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

339
	};
M
Mr.doob 已提交
340

341
	// Internal functions
342

343
	// Buffer allocation
344

345
	function createParticleBuffers ( geometry ) {
346

347 348
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
349

350
		_this.info.geometries ++;
351

352
	};
353

354
	function createLineBuffers ( geometry ) {
355

356 357
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
358

359
		_this.info.memory.geometries ++;
360

361
	};
362

363
	function createRibbonBuffers ( geometry ) {
364

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

368
		_this.info.memory.geometries ++;
M
Mr.doob 已提交
369

370
	};
371

372
	function createMeshBuffers ( geometryGroup ) {
373

374 375 376 377 378 379
		geometryGroup.__webglVertexBuffer = _gl.createBuffer();
		geometryGroup.__webglNormalBuffer = _gl.createBuffer();
		geometryGroup.__webglTangentBuffer = _gl.createBuffer();
		geometryGroup.__webglColorBuffer = _gl.createBuffer();
		geometryGroup.__webglUVBuffer = _gl.createBuffer();
		geometryGroup.__webglUV2Buffer = _gl.createBuffer();
380

381 382 383 384
		geometryGroup.__webglSkinVertexABuffer = _gl.createBuffer();
		geometryGroup.__webglSkinVertexBBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinIndicesBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinWeightsBuffer = _gl.createBuffer();
385

386 387
		geometryGroup.__webglFaceBuffer = _gl.createBuffer();
		geometryGroup.__webglLineBuffer = _gl.createBuffer();
388

389
		if ( geometryGroup.numMorphTargets ) {
390

391
			var m, ml;
392

393
			geometryGroup.__webglMorphTargetsBuffers = [];
394

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

397
				geometryGroup.__webglMorphTargetsBuffers.push( _gl.createBuffer() );
398

399
			}
400

401
		}
402

403
		_this.info.memory.geometries ++;
404

405
	};
406

407
	// Buffer deallocation
408

409
	function deleteParticleBuffers ( geometry ) {
410

411 412
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
413

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

416
	};
417

418
	function deleteLineBuffers ( geometry ) {
419

420 421
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
422

M
Mr.doob 已提交
423 424
		_this.info.memory.geometries --;

425 426
	};

427
	function deleteRibbonBuffers ( geometry ) {
428 429 430 431

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

M
Mr.doob 已提交
432 433
		_this.info.memory.geometries --;

434 435
	};

436
	function deleteMeshBuffers ( geometryGroup ) {
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454

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

455
			for ( var m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
456 457 458 459 460 461 462

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

			}

		}

463 464 465 466 467 468 469 470 471 472 473

		if ( geometryGroup.__webglCustomAttributesList ) {

			for ( var id in geometryGroup.__webglCustomAttributesList ) {

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

			}

		}

M
Mr.doob 已提交
474 475
		_this.info.memory.geometries --;

476 477
	};

478
	// Buffer initialization
479

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

482 483
		var nvertices = geometry.vertices.length;

484
		var material = object.material;
485

486
		if ( material.attributes ) {
487

488
			if ( geometry.__webglCustomAttributesList === undefined ) {
489

490
				geometry.__webglCustomAttributesList = [];
491

492
			}
493

494
			for ( var a in material.attributes ) {
495

496
				var attribute = material.attributes[ a ];
497

498
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
499

500
					attribute.__webglInitialized = true;
501

A
alteredq 已提交
502
					var size = 1;		// "f" and "i"
503

504 505 506 507
					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;
508

509
					attribute.size = size;
A
alteredq 已提交
510

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

513 514
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
515

516
					attribute.needsUpdate = true;
517

518
				}
519

520
				geometry.__webglCustomAttributesList.push( attribute );
521

522
			}
523

524
		}
525

526
	};
527

528
	function initParticleBuffers ( geometry, object ) {
A
alteredq 已提交
529 530 531 532 533 534

		var nvertices = geometry.vertices.length;

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

535 536 537
		geometry.__sortArray = [];

		geometry.__webglParticleCount = nvertices;
A
alteredq 已提交
538 539 540 541 542

		initCustomAttributes ( geometry, object );

	};

543
	function initLineBuffers ( geometry, object ) {
A
alteredq 已提交
544 545 546 547 548 549

		var nvertices = geometry.vertices.length;

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

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

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

569 570 571
		var geometry = object.geometry,
			faces3 = geometryGroup.faces3,
			faces4 = geometryGroup.faces4,
M
Mr.doob 已提交
572

573 574 575
			nvertices = faces3.length * 3 + faces4.length * 4,
			ntris     = faces3.length * 1 + faces4.length * 2,
			nlines    = faces3.length * 3 + faces4.length * 4,
576

577
			material = getBufferMaterial( object, geometryGroup ),
578

579 580 581
			uvType = bufferGuessUVType( material ),
			normalType = bufferGuessNormalType( material ),
			vertexColorType = bufferGuessVertexColorType( material );
A
alteredq 已提交
582

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

585
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
586

587
		if ( normalType ) {
M
Mr.doob 已提交
588

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

591
		}
592

593
		if ( geometry.hasTangents ) {
594

595
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
596

597
		}
598

599
		if ( vertexColorType ) {
600

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

603
		}
M
Mr.doob 已提交
604

605
		if ( uvType ) {
606

607
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
608

609 610 611 612 613
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

615 616 617 618 619 620 621 622 623 624 625 626 627 628 629
				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 );

		}

630
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
631
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
632

633 634
		if ( geometryGroup.numMorphTargets ) {

M
Mr.doob 已提交
635
			geometryGroup.__morphTargetsArrays = [];
636

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

639 640
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );

641 642 643
			}

		}
644

645
		geometryGroup.__webglFaceCount = ntris * 3;
646
		geometryGroup.__webglLineCount = nlines * 2;
647

M
Mr.doob 已提交
648

649
		// custom attributes
M
Mr.doob 已提交
650

651
		if ( material.attributes ) {
652

653
			if ( geometryGroup.__webglCustomAttributesList === undefined ) {
654

655
				geometryGroup.__webglCustomAttributesList = [];
656

657
			}
658

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

661 662
				// Do a shallow copy of the attribute object so different geometryGroup chunks use different
				// attribute buffers which are correctly indexed in the setMeshBuffers function
663

664
				var originalAttribute = material.attributes[ a ];
665

666
				var attribute = {};
667

668
				for ( var property in originalAttribute ) {
M
Mr.doob 已提交
669

670
					attribute[ property ] = originalAttribute[ property ];
671

672
				}
673

674
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
675

676
					attribute.__webglInitialized = true;
677

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

680 681 682 683
					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;
684

685
					attribute.size = size;
A
alteredq 已提交
686

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

689 690
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
691

692 693
					originalAttribute.needsUpdate = true;
					attribute.__original = originalAttribute;
694 695 696

				}

697 698
				geometryGroup.__webglCustomAttributesList.push( attribute );

699
			}
M
Mr.doob 已提交
700

701
		}
702

703 704
		geometryGroup.__inittedArrays = true;

705
	};
M
Mr.doob 已提交
706

707
	function getBufferMaterial( object, geometryGroup ) {
708

709
		if ( object.material && ! ( object.material instanceof THREE.MeshFaceMaterial ) ) {
710

711
			return object.material;
712

713
		} else if ( geometryGroup.materialIndex >= 0 ) {
714

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

717
		}
718

719
	};
M
Mr.doob 已提交
720

721
	function materialNeedsSmoothNormals ( material ) {
722

723
		return material && material.shading !== undefined && material.shading === THREE.SmoothShading;
724

725
	};
M
Mr.doob 已提交
726

727
	function bufferGuessNormalType ( material ) {
728

729
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
730

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

733
			return false;
734

735
		}
736

737
		if ( materialNeedsSmoothNormals( material ) ) {
738

739
			return THREE.SmoothShading;
M
Mr.doob 已提交
740

741
		} else {
742

743
			return THREE.FlatShading;
744

745
		}
746

747
	};
748

749
	function bufferGuessVertexColorType ( material ) {
750

751
		if ( material.vertexColors ) {
752

753
			return material.vertexColors;
754

755
		}
M
Mr.doob 已提交
756

757
		return false;
M
Mr.doob 已提交
758

759
	};
M
Mr.doob 已提交
760

761
	function bufferGuessUVType ( material ) {
762

763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306
		// 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 );

		}

	};

1307
	function setMeshBuffers( geometryGroup, object, hint, dispose, material ) {
1308 1309 1310 1311 1312 1313 1314 1315

		if ( ! geometryGroup.__inittedArrays ) {

			// console.log( object );
			return;

		}

1316 1317 1318 1319 1320 1321
		var normalType = bufferGuessNormalType( material ),
		vertexColorType = bufferGuessVertexColorType( material ),
		uvType = bufferGuessUVType( material ),

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

1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421
		var f, fl, fi, face,
		vertexNormals, faceNormal, normal,
		vertexColors, faceColor,
		vertexTangents,
		uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4,
		c1, c2, c3, c4,
		sw1, sw2, sw3, sw4,
		si1, si2, si3, si4,
		sa1, sa2, sa3, sa4,
		sb1, sb2, sb3, sb4,
		m, ml, i, il,
		vn, uvi, uv2i,
		vk, vkl, vka,
		a,

		vertexIndex = 0,

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

		value,

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

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

		morphTargetsArrays = geometryGroup.__morphTargetsArrays,

		customAttributes = geometryGroup.__webglCustomAttributesList,
		customAttribute,

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

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

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

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

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

		obj_colors = geometry.colors,

		obj_skinVerticesA = geometry.skinVerticesA,
		obj_skinVerticesB = geometry.skinVerticesB,
		obj_skinIndices = geometry.skinIndices,
		obj_skinWeights = geometry.skinWeights,

		morphTargets = geometry.morphTargets;

		if ( dirtyVertices ) {

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

				face = obj_faces[ chunk_faces3[ f ] ];

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

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

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

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

1423
				offset += 9;
M
Mr.doob 已提交
1424

1425
			}
1426

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

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

A
alteredq 已提交
1431 1432 1433 1434
				v1 = vertices[ face.a ].position;
				v2 = vertices[ face.b ].position;
				v3 = vertices[ face.c ].position;
				v4 = vertices[ face.d ].position;
1435

A
alteredq 已提交
1436 1437 1438
				vertexArray[ offset ]     = v1.x;
				vertexArray[ offset + 1 ] = v1.y;
				vertexArray[ offset + 2 ] = v1.z;
1439

A
alteredq 已提交
1440 1441 1442
				vertexArray[ offset + 3 ] = v2.x;
				vertexArray[ offset + 4 ] = v2.y;
				vertexArray[ offset + 5 ] = v2.z;
1443

A
alteredq 已提交
1444 1445 1446
				vertexArray[ offset + 6 ] = v3.x;
				vertexArray[ offset + 7 ] = v3.y;
				vertexArray[ offset + 8 ] = v3.z;
1447

A
alteredq 已提交
1448 1449 1450
				vertexArray[ offset + 9 ]  = v4.x;
				vertexArray[ offset + 10 ] = v4.y;
				vertexArray[ offset + 11 ] = v4.z;
1451

A
alteredq 已提交
1452
				offset += 12;
1453

A
alteredq 已提交
1454
			}
1455

A
alteredq 已提交
1456 1457
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1458

A
alteredq 已提交
1459
		}
M
Mr.doob 已提交
1460

A
alteredq 已提交
1461
		if ( dirtyMorphTargets ) {
M
Mr.doob 已提交
1462

1463
			for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {
1464

1465
				offset_morphTarget = 0;
1466

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

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

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

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

A
alteredq 已提交
1477 1478 1479
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
M
Mr.doob 已提交
1480

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

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

1489
					offset_morphTarget += 9;
1490

1491
				}
1492

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

1495
					face = obj_faces[ chunk_faces4[ f ] ];
1496

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

1502
					vka = morphTargetsArrays[ vk ];
1503

1504 1505 1506
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
1507

1508 1509 1510
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
1511

1512 1513 1514
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
1515

A
alteredq 已提交
1516 1517 1518 1519
					vka[ offset_morphTarget + 9 ]  = v4.x;
					vka[ offset_morphTarget + 10 ] = v4.y;
					vka[ offset_morphTarget + 11 ] = v4.z;

1520
					offset_morphTarget += 12;
A
alteredq 已提交
1521

1522
				}
A
alteredq 已提交
1523 1524 1525

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

1527
			}
1528

A
alteredq 已提交
1529 1530 1531 1532 1533 1534 1535
		}

		if ( obj_skinWeights.length ) {

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

				face = obj_faces[ chunk_faces3[ f ]	];
1536

1537
				// weights
A
alteredq 已提交
1538

1539 1540 1541
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
A
alteredq 已提交
1542

1543 1544 1545 1546
				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 已提交
1547

1548 1549 1550 1551
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1552

1553 1554 1555 1556
				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 已提交
1557

1558
				// indices
A
alteredq 已提交
1559

1560 1561 1562
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
A
alteredq 已提交
1563

1564 1565 1566 1567
				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 已提交
1568

1569 1570 1571 1572
				skinIndexArray[ offset_skin + 4 ] = si2.x;
				skinIndexArray[ offset_skin + 5 ] = si2.y;
				skinIndexArray[ offset_skin + 6 ] = si2.z;
				skinIndexArray[ offset_skin + 7 ] = si2.w;
1573

1574 1575 1576 1577
				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 已提交
1578

1579
				// vertices A
A
alteredq 已提交
1580

1581 1582 1583
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
A
alteredq 已提交
1584

1585 1586 1587 1588
				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 已提交
1589

1590 1591 1592 1593
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1594

1595 1596 1597 1598
				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 已提交
1599

1600
				// vertices B
A
alteredq 已提交
1601

1602 1603 1604
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
A
alteredq 已提交
1605

1606 1607 1608 1609
				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 已提交
1610

1611 1612 1613 1614
				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
				skinVertexBArray[ offset_skin + 7 ] = 1;
1615

1616 1617 1618 1619
				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
				skinVertexBArray[ offset_skin + 11 ] = 1;
1620

1621
				offset_skin += 12;
1622

1623
			}
1624

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

A
alteredq 已提交
1627
				face = obj_faces[ chunk_faces4[ f ] ];
1628

A
alteredq 已提交
1629
				// weights
1630

A
alteredq 已提交
1631 1632 1633 1634
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
				sw4 = obj_skinWeights[ face.d ];
1635

A
alteredq 已提交
1636 1637 1638 1639
				skinWeightArray[ offset_skin ]     = sw1.x;
				skinWeightArray[ offset_skin + 1 ] = sw1.y;
				skinWeightArray[ offset_skin + 2 ] = sw1.z;
				skinWeightArray[ offset_skin + 3 ] = sw1.w;
1640

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

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

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

A
alteredq 已提交
1656
				// indices
1657

A
alteredq 已提交
1658 1659 1660 1661
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
				si4 = obj_skinIndices[ face.d ];
1662

A
alteredq 已提交
1663 1664 1665 1666
				skinIndexArray[ offset_skin ]     = si1.x;
				skinIndexArray[ offset_skin + 1 ] = si1.y;
				skinIndexArray[ offset_skin + 2 ] = si1.z;
				skinIndexArray[ offset_skin + 3 ] = si1.w;
1667

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

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

A
alteredq 已提交
1678 1679 1680 1681
				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 已提交
1682

A
alteredq 已提交
1683
				// vertices A
M
Mr.doob 已提交
1684

A
alteredq 已提交
1685 1686 1687 1688
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
				sa4 = obj_skinVerticesA[ face.d ];
1689

A
alteredq 已提交
1690 1691 1692 1693
				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 已提交
1694

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

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

A
alteredq 已提交
1705 1706 1707 1708
				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 已提交
1709

A
alteredq 已提交
1710
				// vertices B
M
Mr.doob 已提交
1711

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

A
alteredq 已提交
1717 1718 1719 1720
				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 已提交
1721

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

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

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

A
alteredq 已提交
1737
				offset_skin += 16;
M
Mr.doob 已提交
1738

A
alteredq 已提交
1739
			}
M
Mr.doob 已提交
1740

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

A
alteredq 已提交
1743 1744
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );
M
Mr.doob 已提交
1745

A
alteredq 已提交
1746 1747 1748 1749 1750 1751 1752 1753
				_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 );
1754

1755
			}
1756

A
alteredq 已提交
1757
		}
M
Mr.doob 已提交
1758

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

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

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

A
alteredq 已提交
1765 1766
				vertexColors = face.vertexColors;
				faceColor = face.color;
1767

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

A
alteredq 已提交
1770 1771 1772
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
1773

A
alteredq 已提交
1774
				} else {
1775

A
alteredq 已提交
1776 1777 1778
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
1779

A
alteredq 已提交
1780
				}
1781

A
alteredq 已提交
1782 1783 1784
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
1785

A
alteredq 已提交
1786 1787 1788
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
1789

A
alteredq 已提交
1790 1791 1792
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
1793

A
alteredq 已提交
1794
				offset_color += 9;
M
Mr.doob 已提交
1795

A
alteredq 已提交
1796
			}
M
Mr.doob 已提交
1797

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

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

A
alteredq 已提交
1802 1803
				vertexColors = face.vertexColors;
				faceColor = face.color;
M
Mr.doob 已提交
1804

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

A
alteredq 已提交
1807 1808 1809 1810
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
					c4 = vertexColors[ 3 ];
1811

A
alteredq 已提交
1812
				} else {
M
Mr.doob 已提交
1813

A
alteredq 已提交
1814 1815 1816 1817
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
					c4 = faceColor;
M
Mr.doob 已提交
1818

A
alteredq 已提交
1819
				}
1820

A
alteredq 已提交
1821 1822 1823
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
1824

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

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

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

A
alteredq 已提交
1837
				offset_color += 12;
1838

1839
			}
1840

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

A
alteredq 已提交
1843 1844
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
M
Mr.doob 已提交
1845

1846
			}
1847

A
alteredq 已提交
1848
		}
M
Mr.doob 已提交
1849

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

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

A
alteredq 已提交
1854
				face = obj_faces[ chunk_faces3[ f ]	];
1855

A
alteredq 已提交
1856
				vertexTangents = face.vertexTangents;
M
Mr.doob 已提交
1857

A
alteredq 已提交
1858 1859 1860
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
1861

A
alteredq 已提交
1862 1863 1864 1865
				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 已提交
1866

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

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

A
alteredq 已提交
1877
				offset_tangent += 12;
1878

1879
			}
1880

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

A
alteredq 已提交
1883
				face = obj_faces[ chunk_faces4[ f ] ];
1884

A
alteredq 已提交
1885
				vertexTangents = face.vertexTangents;
1886

A
alteredq 已提交
1887 1888 1889 1890
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
				t4 = vertexTangents[ 3 ];
1891

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

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

A
alteredq 已提交
1902 1903 1904 1905
				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 已提交
1906

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

A
alteredq 已提交
1912
				offset_tangent += 16;
1913

A
alteredq 已提交
1914
			}
1915

A
alteredq 已提交
1916 1917
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
1918

A
alteredq 已提交
1919
		}
1920

A
alteredq 已提交
1921
		if ( dirtyNormals && normalType ) {
1922

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

A
alteredq 已提交
1925
				face = obj_faces[ chunk_faces3[ f ]	];
1926

A
alteredq 已提交
1927 1928
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
1929

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

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

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

A
alteredq 已提交
1936 1937 1938
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
1939

A
alteredq 已提交
1940
						offset_normal += 3;
1941

A
alteredq 已提交
1942
					}
1943

A
alteredq 已提交
1944
				} else {
M
Mr.doob 已提交
1945

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

A
alteredq 已提交
1948 1949 1950
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
1951

A
alteredq 已提交
1952
						offset_normal += 3;
M
Mr.doob 已提交
1953

A
alteredq 已提交
1954
					}
1955

A
alteredq 已提交
1956
				}
1957

A
alteredq 已提交
1958
			}
1959

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

A
alteredq 已提交
1962
				face = obj_faces[ chunk_faces4[ f ] ];
1963

A
alteredq 已提交
1964 1965
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
1966

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

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

A
alteredq 已提交
1971
						vn = vertexNormals[ i ];
1972

A
alteredq 已提交
1973 1974 1975
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
1976

A
alteredq 已提交
1977
						offset_normal += 3;
1978

A
alteredq 已提交
1979
					}
M
Mr.doob 已提交
1980

A
alteredq 已提交
1981
				} else {
1982

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

A
alteredq 已提交
1985 1986 1987
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1988

A
alteredq 已提交
1989
						offset_normal += 3;
M
Mr.doob 已提交
1990

A
alteredq 已提交
1991
					}
1992

A
alteredq 已提交
1993
				}
1994

A
alteredq 已提交
1995
			}
M
Mr.doob 已提交
1996

A
alteredq 已提交
1997 1998
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
1999

A
alteredq 已提交
2000
		}
M
Mr.doob 已提交
2001

A
alteredq 已提交
2002
		if ( dirtyUvs && obj_uvs && uvType ) {
2003

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

A
alteredq 已提交
2006
				fi = chunk_faces3[ f ];
2007

A
alteredq 已提交
2008 2009
				face = obj_faces[ fi ];
				uv = obj_uvs[ fi ];
2010

A
alteredq 已提交
2011
				if ( uv === undefined ) continue;
2012

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

A
alteredq 已提交
2015
					uvi = uv[ i ];
2016

A
alteredq 已提交
2017 2018
					uvArray[ offset_uv ]     = uvi.u;
					uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
2019

A
alteredq 已提交
2020
					offset_uv += 2;
M
Mr.doob 已提交
2021

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

			}

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

2044 2045
				}

2046
			}
2047

A
alteredq 已提交
2048
			if ( offset_uv > 0 ) {
2049

A
alteredq 已提交
2050 2051
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
2052

A
alteredq 已提交
2053
			}
2054

A
alteredq 已提交
2055
		}
2056

A
alteredq 已提交
2057
		if ( dirtyUvs && obj_uvs2 && uvType ) {
2058

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

A
alteredq 已提交
2061
				fi = chunk_faces3[ f ];
2062

A
alteredq 已提交
2063 2064
				face = obj_faces[ fi ];
				uv2 = obj_uvs2[ fi ];
2065

A
alteredq 已提交
2066 2067 2068 2069 2070 2071 2072 2073 2074 2075
				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;
2076

2077 2078
				}

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

			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;

				}
2100

2101
			}
2102

A
alteredq 已提交
2103
			if ( offset_uv2 > 0 ) {
2104

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

A
alteredq 已提交
2108
			}
2109

A
alteredq 已提交
2110
		}
2111

A
alteredq 已提交
2112
		if ( dirtyElements ) {
2113

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

A
alteredq 已提交
2116
				face = obj_faces[ chunk_faces3[ f ]	];
2117

A
alteredq 已提交
2118 2119 2120
				faceArray[ offset_face ] 	 = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 2;
2121

A
alteredq 已提交
2122
				offset_face += 3;
2123

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

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

A
alteredq 已提交
2130 2131
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
2132

A
alteredq 已提交
2133
				offset_line += 6;
2134

A
alteredq 已提交
2135
				vertexIndex += 3;
2136

A
alteredq 已提交
2137
			}
2138

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

A
alteredq 已提交
2141
				face = obj_faces[ chunk_faces4[ f ] ];
2142

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

A
alteredq 已提交
2147 2148 2149
				faceArray[ offset_face + 3 ] = vertexIndex + 1;
				faceArray[ offset_face + 4 ] = vertexIndex + 2;
				faceArray[ offset_face + 5 ] = vertexIndex + 3;
2150

A
alteredq 已提交
2151
				offset_face += 6;
2152

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

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

A
alteredq 已提交
2159 2160
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
2161

A
alteredq 已提交
2162 2163
				lineArray[ offset_line + 6 ] = vertexIndex + 2;
				lineArray[ offset_line + 7 ] = vertexIndex + 3;
2164

A
alteredq 已提交
2165
				offset_line += 8;
2166

A
alteredq 已提交
2167
				vertexIndex += 4;
2168

2169
			}
2170

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

A
alteredq 已提交
2174 2175
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
2176

A
alteredq 已提交
2177
		}
2178

A
alteredq 已提交
2179
		if ( customAttributes ) {
2180

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

2183
				customAttribute = customAttributes[ i ];
2184

2185
				if ( ! customAttribute.__original.needsUpdate ) continue;
2186

2187 2188
				offset_custom = 0;
				offset_customSrc = 0;
2189

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

2223
							value = customAttribute.value[ chunk_faces3[ f ] ];
2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234

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

2235
							value = customAttribute.value[ chunk_faces4[ f ] ];
2236 2237 2238 2239 2240 2241 2242 2243 2244

							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;

						}
2245

2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264
					}

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

2266 2267
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2268

2269
							offset_custom += 6;
A
alteredq 已提交
2270

2271
						}
A
alteredq 已提交
2272

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

2275
							face = obj_faces[ chunk_faces4[ f ] ];
A
alteredq 已提交
2276

2277 2278 2279 2280
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
A
alteredq 已提交
2281

2282 2283
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2284

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

2288 2289
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2290

2291 2292
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
A
alteredq 已提交
2293

2294
							offset_custom += 8;
A
alteredq 已提交
2295

2296
						}
A
alteredq 已提交
2297

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

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

2302
							value = customAttribute.value[ chunk_faces3[ f ] ];
A
alteredq 已提交
2303

2304 2305 2306
							v1 = value;
							v2 = value;
							v3 = value;
A
alteredq 已提交
2307

2308 2309
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2310

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

2314 2315
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2316

2317
							offset_custom += 6;
A
alteredq 已提交
2318

2319
						}
A
alteredq 已提交
2320

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

2323
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2324

2325 2326 2327 2328
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2329

2330 2331
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2332

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

2336 2337
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2338

2339 2340
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
2341

2342
							offset_custom += 8;
M
Mr.doob 已提交
2343

2344
						}
M
Mr.doob 已提交
2345

M
Mr.doob 已提交
2346
					}
M
Mr.doob 已提交
2347

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

2350
					var pp;
2351

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

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

2356
					} else {
M
Mr.doob 已提交
2357

2358
						pp = [ "x", "y", "z" ];
2359

2360
					}
2361

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

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

2366
							face = obj_faces[ chunk_faces3[ f ]	];
2367

2368 2369 2370
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
2371

2372 2373 2374
							customAttribute.array[ offset_custom ] 	   = v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
2375

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

2380 2381 2382
							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 已提交
2383

2384
							offset_custom += 9;
M
Mr.doob 已提交
2385

2386
						}
M
Mr.doob 已提交
2387

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

2390
							face = obj_faces[ chunk_faces4[ f ] ];
M
Mr.doob 已提交
2391

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

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

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

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

2409 2410 2411
							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 已提交
2412

2413
							offset_custom += 12;
M
Mr.doob 已提交
2414

2415
						}
M
Mr.doob 已提交
2416

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

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

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

2423 2424 2425
							v1 = value;
							v2 = value;
							v3 = value;
M
Mr.doob 已提交
2426

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

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

2435 2436 2437
							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 已提交
2438

2439
							offset_custom += 9;
M
Mr.doob 已提交
2440

2441
						}
2442

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

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

2447 2448 2449 2450
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
2451

2452 2453 2454
							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
2455

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

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

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

2468
							offset_custom += 12;
2469

2470
						}
2471

A
alteredq 已提交
2472
					}
M
Mr.doob 已提交
2473

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

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

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

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

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

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

2563
							offset_custom += 12;
A
alteredq 已提交
2564

2565 2566
						}

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

2569
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2570

2571 2572 2573 2574
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2575

2576 2577 2578 2579
							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;
2580

2581 2582 2583 2584
							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;
2585

2586 2587 2588 2589
							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;
2590

2591 2592 2593 2594
							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;
2595

2596
							offset_custom += 16;
A
alteredq 已提交
2597

2598
						}
A
alteredq 已提交
2599 2600 2601 2602 2603

					}

				}

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

A
alteredq 已提交
2607 2608 2609 2610
			}

		}

2611
		if ( dispose ) {
2612

2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625
			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 已提交
2626

2627
		}
A
alteredq 已提交
2628

2629
	};
A
alteredq 已提交
2630

2631
	// Buffer rendering
A
alteredq 已提交
2632

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

2635 2636
		if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
A
alteredq 已提交
2637

2638
		if ( object.hasPos ) {
A
alteredq 已提交
2639

2640 2641 2642 2643
			_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 已提交
2644 2645 2646

		}

2647
		if ( object.hasNormal ) {
A
alteredq 已提交
2648

2649
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
A
alteredq 已提交
2650

2651
			if ( shading === THREE.FlatShading ) {
2652

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

2658
				for( i = 0; i < il; i += 9 ) {
2659

2660
					normalArray = object.normalArray;
2661

2662 2663 2664
					nax  = normalArray[ i ];
					nay  = normalArray[ i + 1 ];
					naz  = normalArray[ i + 2 ];
2665

2666 2667 2668
					nbx  = normalArray[ i + 3 ];
					nby  = normalArray[ i + 4 ];
					nbz  = normalArray[ i + 5 ];
2669

2670 2671 2672
					ncx  = normalArray[ i + 6 ];
					ncy  = normalArray[ i + 7 ];
					ncz  = normalArray[ i + 8 ];
2673

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

2678 2679 2680
					normalArray[ i ] 	 = nx;
					normalArray[ i + 1 ] = ny;
					normalArray[ i + 2 ] = nz;
2681

2682 2683 2684
					normalArray[ i + 3 ] = nx;
					normalArray[ i + 4 ] = ny;
					normalArray[ i + 5 ] = nz;
2685

2686 2687 2688
					normalArray[ i + 6 ] = nx;
					normalArray[ i + 7 ] = ny;
					normalArray[ i + 8 ] = nz;
2689

2690
				}
2691

2692
			}
2693

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

2698
		}
2699

2700
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );
2701

2702
		object.count = 0;
2703

2704
	};
2705

2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797
	this.renderBufferDirect = function ( camera, lights, fog, material, geometryGroup, object ) {

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

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

		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;

			for ( var i = 0; i < offsets.length; ++ i ) {

				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 已提交
2798
	this.renderBuffer = function ( camera, lights, fog, material, geometryGroup, object ) {
2799

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

2802
		var program, attributes, linewidth, primitives, a, attribute, i, il;
2803

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

2806
		attributes = program.attributes;
2807

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

2812
		if ( geometryGroupHash !== _currentGeometryGroupHash ) {
A
alteredq 已提交
2813

2814 2815
			_currentGeometryGroupHash = geometryGroupHash;
			updateBuffers = true;
2816

2817
		}
2818

2819
		// vertices
2820

2821
		if ( !material.morphTargets && attributes.position >= 0 ) {
2822

2823
			if ( updateBuffers ) {
2824

2825 2826
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
				_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
2827

2828
			}
2829

2830
		} else {
2831

2832
			if ( object.morphTargetBase ) {
2833

2834
				setupMorphTargets( material, geometryGroup, object );
2835

2836
			}
2837

2838
		}
2839

2840

2841
		if ( updateBuffers ) {
2842

2843
			// custom attributes
2844

2845
			// Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
2846

2847
			if ( geometryGroup.__webglCustomAttributesList ) {
2848

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

2851
					attribute = geometryGroup.__webglCustomAttributesList[ i ];
2852

2853
					if( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
2854

2855 2856
						_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
						_gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 );
2857

2858
					}
2859

2860
				}
2861

2862
			}
2863 2864


2865
			// colors
2866

2867
			if ( attributes.color >= 0 ) {
2868

2869 2870
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
2871

2872
			}
2873

2874
			// normals
2875

2876
			if ( attributes.normal >= 0 ) {
2877

2878 2879
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
				_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
2880

2881
			}
2882

2883
			// tangents
2884

2885
			if ( attributes.tangent >= 0 ) {
2886

2887 2888
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
				_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
2889

2890
			}
2891

2892
			// uvs
2893

2894
			if ( attributes.uv >= 0 ) {
2895

2896
				if ( geometryGroup.__webglUVBuffer ) {
2897

2898 2899
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
					_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
2900

2901
					_gl.enableVertexAttribArray( attributes.uv );
2902

2903
				} else {
2904

2905
					_gl.disableVertexAttribArray( attributes.uv );
2906 2907 2908 2909 2910

				}

			}

2911
			if ( attributes.uv2 >= 0 ) {
2912

2913
				if ( geometryGroup.__webglUV2Buffer ) {
2914

2915 2916
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
					_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
2917

2918
					_gl.enableVertexAttribArray( attributes.uv2 );
2919

2920
				} else {
2921

2922
					_gl.disableVertexAttribArray( attributes.uv2 );
2923 2924

				}
2925 2926

			}
2927

2928 2929 2930
			if ( material.skinning &&
				 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
				 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
A
alteredq 已提交
2931

2932 2933
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
2934

2935 2936
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
				_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
2937

2938 2939
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
				_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
2940

2941 2942
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
				_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
2943

A
alteredq 已提交
2944
			}
2945

2946
		}
2947

2948
		// render mesh
2949

2950
		if ( object instanceof THREE.Mesh ) {
2951

2952
			// wireframe
2953

2954
			if ( material.wireframe ) {
2955

2956
				setLineWidth( material.wireframeLinewidth );
2957

2958 2959
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
2960

2961
			// triangles
2962

2963
			} else {
2964

2965 2966
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
2967

2968
			}
2969

2970 2971 2972
			_this.info.render.calls ++;
			_this.info.render.vertices += geometryGroup.__webglFaceCount;
			_this.info.render.faces += geometryGroup.__webglFaceCount / 3;
2973

2974
		// render lines
2975

2976
		} else if ( object instanceof THREE.Line ) {
2977

2978
			primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
2979

2980
			setLineWidth( material.linewidth );
2981

2982
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
2983

2984
			_this.info.render.calls ++;
2985

2986
		// render particles
2987

2988
		} else if ( object instanceof THREE.ParticleSystem ) {
2989

2990
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
2991

2992
			_this.info.render.calls ++;
2993
			_this.info.render.points += geometryGroup.__webglParticleCount;
2994

2995
		// render ribbon
2996

2997
		} else if ( object instanceof THREE.Ribbon ) {
2998

2999
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
3000

3001
			_this.info.render.calls ++;
3002

3003
		}
3004

3005
	};
3006

3007
	function setupMorphTargets ( material, geometryGroup, object ) {
3008

3009
		// set base
3010

3011
		var attributes = material.program.attributes;
3012

3013
		if ( object.morphTargetBase !== - 1 ) {
3014

3015 3016
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3017

3018
		} else if ( attributes.position >= 0 ) {
3019

3020 3021
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3022

3023
		}
3024

3025
		if ( object.morphTargetForcedOrder.length ) {
3026

3027
			// set forced order
3028

3029 3030 3031 3032 3033
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;

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

3035 3036 3037 3038 3039 3040
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ order[ m ] ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );

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

				m ++;
3041 3042
			}

3043 3044 3045 3046 3047 3048 3049 3050 3051 3052
		} else {

			// find most influencing

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

3054
			if ( object.morphTargetBase !== - 1 ) {
3055

3056
				used[ object.morphTargetBase ] = true;
3057

3058
			}
3059

3060
			while ( m < material.numSupportedMorphTargets ) {
3061

3062
				for ( i = 0; i < il; i ++ ) {
3063

3064
					if ( !used[ i ] && influences[ i ] > candidateInfluence ) {
3065

3066 3067
						candidate = i;
						candidateInfluence = influences[ candidate ];
3068

3069
					}
3070

3071
				}
3072

3073 3074
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
3075

3076
				object.__webglMorphTargetInfluences[ m ] = candidateInfluence;
3077

3078 3079 3080
				used[ candidate ] = 1;
				candidateInfluence = -1;
				m ++;
3081 3082 3083 3084 3085

			}

		}

3086
		// load updated influences uniform
3087

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

3090
			_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
3091

3092
		}
3093

3094
	};
3095 3096


3097
	function painterSort ( a, b ) {
3098

3099
		return b.z - a.z;
3100

3101
	};
3102

3103
	// Rendering
3104

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

3107 3108 3109 3110 3111 3112 3113 3114
		var i, il,

		program, material,
		webglObject, object,
		renderList,

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

3116
		_currentMaterialId = -1;
3117

3118
		if ( this.autoUpdateObjects ) this.initWebGLObjects( scene );
3119

3120
		if ( camera.parent === undefined ) {
3121

3122 3123
			console.warn( 'DEPRECATED: Camera hasn\'t been added to a Scene. Adding it...' );
			scene.add( camera );
3124

3125
		}
3126

3127
		if ( this.autoUpdateScene ) scene.updateMatrixWorld();
3128

A
alteredq 已提交
3129 3130
		// custom render plugins (pre pass)

A
alteredq 已提交
3131
		renderPlugins( this.renderPluginsPre, scene, camera );
A
alteredq 已提交
3132 3133 3134 3135

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

3138
		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
A
alteredq 已提交
3139 3140 3141 3142 3143 3144

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

3146
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
A
alteredq 已提交
3147
		_frustum.setFromMatrix( _projScreenMatrix );
3148

A
alteredq 已提交
3149
		this.setRenderTarget( renderTarget );
3150

3151
		if ( this.autoClear || forceClear ) {
3152

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

3155
		}
M
Mr.doob 已提交
3156

3157
		// set matrices for regular objects (frustum culled)
3158

3159
		renderList = scene.__webglObjects;
3160

3161
		for ( i = 0, il = renderList.length; i < il; i ++ ) {
3162

3163
			webglObject = renderList[ i ];
3164
			object = webglObject.object;
3165

A
alteredq 已提交
3166 3167
			webglObject.render = false;

3168
			if ( object.visible ) {
3169

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

3172
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
3173

A
alteredq 已提交
3174
					setupMatrices( object, camera );
3175

3176
					unrollBufferMaterial( webglObject );
3177

3178
					webglObject.render = true;
3179

3180
					if ( this.sortObjects ) {
3181

3182
						if ( object.renderDepth ) {
3183

3184
							webglObject.z = object.renderDepth;
M
Mr.doob 已提交
3185

3186
						} else {
M
Mr.doob 已提交
3187

3188 3189
							_vector3.copy( object.position );
							_projScreenMatrix.multiplyVector3( _vector3 );
3190

3191
							webglObject.z = _vector3.z;
3192

3193
						}
M
Mr.doob 已提交
3194

3195
					}
M
Mr.doob 已提交
3196

3197
				}
3198 3199

			}
3200 3201 3202

		}

3203
		if ( this.sortObjects ) {
M
Mr.doob 已提交
3204

3205
			renderList.sort( painterSort );
3206

3207
		}
3208

3209
		// set matrices for immediate objects
3210

3211
		renderList = scene.__webglObjectsImmediate;
3212

3213 3214 3215
		for ( i = 0, il = renderList.length; i < il; i ++ ) {

			webglObject = renderList[ i ];
3216
			object = webglObject.object;
3217

3218
			if ( object.visible ) {
3219

3220
				if( object.matrixAutoUpdate ) {
3221

3222
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3223

3224
				}
M
Mr.doob 已提交
3225

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

3228
				unrollImmediateBufferMaterial( webglObject );
M
Mr.doob 已提交
3229

3230
			}
M
Mr.doob 已提交
3231

3232
		}
3233

3234
		if ( scene.overrideMaterial ) {
3235

3236
			this.setBlending( scene.overrideMaterial.blending );
A
alteredq 已提交
3237
			this.setDepthTest( scene.overrideMaterial.depthTest );
3238 3239
			setDepthWrite( scene.overrideMaterial.depthWrite );
			setPolygonOffset( scene.overrideMaterial.polygonOffset, scene.overrideMaterial.polygonOffsetFactor, scene.overrideMaterial.polygonOffsetUnits );
3240

3241 3242
			renderObjects( scene.__webglObjects, false, "", camera, lights, fog, true, scene.overrideMaterial );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "", camera, lights, fog, false, scene.overrideMaterial );
M
Mr.doob 已提交
3243

3244
		} else {
3245

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

3248
			this.setBlending( THREE.NormalBlending );
3249

3250 3251
			renderObjects( scene.__webglObjects, true, "opaque", camera, lights, fog, false );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "opaque", camera, lights, fog, false );
3252

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

3255 3256
			renderObjects( scene.__webglObjects, false, "transparent", camera, lights, fog, true );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "transparent", camera, lights, fog, true );
3257

3258
		}
3259

A
alteredq 已提交
3260
		// custom render plugins (post pass)
3261

A
alteredq 已提交
3262
		renderPlugins( this.renderPluginsPost, scene, camera );
3263 3264


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

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

3269
			updateRenderTargetMipmap( renderTarget );
3270

3271
		}
3272

3273
		//_gl.finish();
3274

3275
	};
3276

A
alteredq 已提交
3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289
	function renderPlugins( plugins, scene, camera ) {

		if ( ! plugins.length ) return;

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

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

A
alteredq 已提交
3290
			plugins[ i ].render( scene, camera, _currentWidth, _currentHeight );
A
alteredq 已提交
3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302

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

		}

	};

3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338
	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;

3339
					if ( useBlending ) _this.setBlending( material.blending );
3340

A
alteredq 已提交
3341
					_this.setDepthTest( material.depthTest );
3342 3343 3344 3345 3346
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

A
alteredq 已提交
3347
				_this.setObjectFaces( object );
3348 3349 3350 3351 3352 3353 3354 3355 3356 3357

				if ( buffer instanceof THREE.BufferGeometry ) {

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

				} else {

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

				}
3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385

			}

		}

	};

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

A
alteredq 已提交
3388
					_this.setDepthTest( material.depthTest );
3389 3390 3391 3392 3393
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

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

A
alteredq 已提交
3396
			}
3397

A
alteredq 已提交
3398
		}
3399

A
alteredq 已提交
3400
	};
3401

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

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

A
alteredq 已提交
3406
		_currentGeometryGroupHash = -1;
3407

A
alteredq 已提交
3408 3409 3410 3411 3412 3413 3414 3415 3416
		_this.setObjectFaces( object );

		if ( object.immediateRenderCallback ) {

			object.immediateRenderCallback( program, _gl, _frustum );

		} else {

			object.render( function( object ) { _this.renderBufferImmediate( object, program, material.shading ); } );
3417 3418 3419 3420 3421

		}

	};

3422
	function unrollImmediateBufferMaterial ( globject ) {
3423

3424 3425
		var object = globject.object,
			material = object.material;
3426

3427
		if ( material.transparent ) {
3428

3429 3430
			globject.transparent = material;
			globject.opaque = null;
3431

3432
		} else {
3433

3434 3435
			globject.opaque = material;
			globject.transparent = null;
3436

3437
		}
A
alteredq 已提交
3438

3439
	};
A
alteredq 已提交
3440

3441
	function unrollBufferMaterial ( globject ) {
A
alteredq 已提交
3442

3443 3444 3445
		var object = globject.object,
			buffer = globject.buffer,
			material, materialIndex, meshMaterial;
3446

3447
		meshMaterial = object.material;
3448

3449
		if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
M
Mr.doob 已提交
3450

3451
			materialIndex = buffer.materialIndex;
3452

3453
			if ( materialIndex >= 0 ) {
3454

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

3457
				if ( material.transparent ) {
M
Mr.doob 已提交
3458

3459 3460
					globject.transparent = material;
					globject.opaque = null;
3461

3462
				} else {
3463

3464 3465
					globject.opaque = material;
					globject.transparent = null;
3466

3467
				}
3468

3469
			}
3470

3471
		} else {
3472

3473
			material = meshMaterial;
3474

3475
			if ( material ) {
3476

3477
				if ( material.transparent ) {
M
Mr.doob 已提交
3478

3479 3480
					globject.transparent = material;
					globject.opaque = null;
A
alteredq 已提交
3481

3482
				} else {
3483

3484 3485
					globject.opaque = material;
					globject.transparent = null;
3486

3487
				}
3488

3489
			}
3490

3491
		}
3492

3493
	};
3494

3495
	// Geometry splitting
3496

3497
	function sortFacesByMaterial ( geometry ) {
3498

3499 3500 3501
		var f, fl, face, materialIndex, vertices,
			materialHash, groupHash,
			hash_map = {};
3502

3503
		var numMorphTargets = geometry.morphTargets.length;
3504

3505
		geometry.geometryGroups = {};
3506

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

3509 3510
			face = geometry.faces[ f ];
			materialIndex = face.materialIndex;
3511

3512
			materialHash = ( materialIndex !== undefined ) ? materialIndex : -1;
3513

3514
			if ( hash_map[ materialHash ] === undefined ) {
3515

3516
				hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 };
3517 3518 3519

			}

3520
			groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
3521

3522
			if ( geometry.geometryGroups[ groupHash ] === undefined ) {
3523

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

3526
			}
A
alteredq 已提交
3527

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

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

3532 3533
				hash_map[ materialHash ].counter += 1;
				groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
A
alteredq 已提交
3534

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

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

3539
				}
3540

3541
			}
3542

3543
			if ( face instanceof THREE.Face3 ) {
3544

3545
				geometry.geometryGroups[ groupHash ].faces3.push( f );
3546

3547
			} else {
3548

3549
				geometry.geometryGroups[ groupHash ].faces4.push( f );
3550

A
alteredq 已提交
3551
			}
3552

3553
			geometry.geometryGroups[ groupHash ].vertices += vertices;
3554

3555
		}
3556

3557
		geometry.geometryGroupsList = [];
3558

3559
		for ( var g in geometry.geometryGroups ) {
3560

3561
			geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;
3562

3563
			geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );
3564

3565
		}
3566

3567
	};
3568

3569 3570 3571 3572 3573 3574 3575 3576 3577
	// Objects refresh

	this.initWebGLObjects = function ( scene ) {

		if ( !scene.__webglObjects ) {

			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
			scene.__webglSprites = [];
3578
			scene.__webglFlares = [];
3579 3580

		}
3581

3582
		while ( scene.__objectsAdded.length ) {
3583

3584 3585
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
3586

3587
		}
A
alteredq 已提交
3588

3589
		while ( scene.__objectsRemoved.length ) {
3590

3591 3592
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
3593

3594
		}
3595

3596
		// update must be called after objects adding / removal
3597

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

3600
			updateObject( scene.__webglObjects[ o ].object );
M
Mr.doob 已提交
3601 3602 3603 3604 3605

		}

	};

3606
	// Objects adding
M
Mr.doob 已提交
3607

3608
	function addObject ( object, scene ) {
A
alteredq 已提交
3609

3610
		var g, geometry, geometryGroup;
3611

3612
		if ( ! object.__webglInit ) {
M
Mr.doob 已提交
3613

3614
			object.__webglInit = true;
M
Mr.doob 已提交
3615

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

3618 3619 3620
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
M
Mr.doob 已提交
3621

3622
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3623

3624
			if ( object instanceof THREE.Mesh ) {
M
Mr.doob 已提交
3625

3626
				geometry = object.geometry;
M
Mr.doob 已提交
3627

3628
				if ( geometry instanceof THREE.Geometry ) {
M
Mr.doob 已提交
3629

3630
					if ( geometry.geometryGroups === undefined ) {
M
Mr.doob 已提交
3631

3632
						sortFacesByMaterial( geometry );
M
Mr.doob 已提交
3633

3634 3635 3636
					}

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

3638
					for ( g in geometry.geometryGroups ) {
M
Mr.doob 已提交
3639

3640
						geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
3641

3642
						// initialise VBO on the first access
M
Mr.doob 已提交
3643

3644
						if ( ! geometryGroup.__webglVertexBuffer ) {
3645

3646 3647
							createMeshBuffers( geometryGroup );
							initMeshBuffers( geometryGroup, object );
M
Mr.doob 已提交
3648

3649 3650 3651 3652 3653 3654 3655 3656 3657
							geometry.__dirtyVertices = true;
							geometry.__dirtyMorphTargets = true;
							geometry.__dirtyElements = true;
							geometry.__dirtyUvs = true;
							geometry.__dirtyNormals = true;
							geometry.__dirtyTangents = true;
							geometry.__dirtyColors = true;

						}
M
Mr.doob 已提交
3658

3659
					}
M
Mr.doob 已提交
3660

3661
				}
M
Mr.doob 已提交
3662

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

3665
				geometry = object.geometry;
M
Mr.doob 已提交
3666

3667
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
3668

3669 3670
					createRibbonBuffers( geometry );
					initRibbonBuffers( geometry );
M
Mr.doob 已提交
3671

3672 3673
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
3674

3675
				}
M
Mr.doob 已提交
3676

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

3679
				geometry = object.geometry;
M
Mr.doob 已提交
3680

3681
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
3682

3683 3684
					createLineBuffers( geometry );
					initLineBuffers( geometry, object );
M
Mr.doob 已提交
3685

3686 3687
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
3688

3689
				}
3690

3691
			} else if ( object instanceof THREE.ParticleSystem ) {
3692

3693
				geometry = object.geometry;
3694

3695
				if ( ! geometry.__webglVertexBuffer ) {
3696

3697 3698
					createParticleBuffers( geometry );
					initParticleBuffers( geometry, object );
3699

3700 3701
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
3702

3703
				}
3704

3705
			}
3706

3707
		}
3708

3709
		if ( ! object.__webglActive ) {
3710

3711
			if ( object instanceof THREE.Mesh ) {
3712

3713
				geometry = object.geometry;
3714

3715 3716 3717 3718 3719 3720 3721 3722 3723
				if ( geometry instanceof THREE.BufferGeometry ) {

					addBuffer( scene.__webglObjects, geometry, object );

				} else {

					for ( g in geometry.geometryGroups ) {

						geometryGroup = geometry.geometryGroups[ g ];
3724

3725
						addBuffer( scene.__webglObjects, geometryGroup, object );
3726

3727
					}
3728

3729
				}
3730

3731 3732 3733
			} else if ( object instanceof THREE.Ribbon ||
						object instanceof THREE.Line ||
						object instanceof THREE.ParticleSystem ) {
3734

3735 3736
				geometry = object.geometry;
				addBuffer( scene.__webglObjects, geometry, object );
3737

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

3740
				addBufferImmediate( scene.__webglObjectsImmediate, object );
3741

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

3744
				scene.__webglSprites.push( object );
3745

3746 3747 3748 3749
			} else if ( object instanceof THREE.LensFlare ) {

				scene.__webglFlares.push( object );

3750 3751
			}

3752
			object.__webglActive = true;
3753

3754
		}
3755

3756
	};
3757

3758
	function addBuffer ( objlist, buffer, object ) {
3759

3760 3761 3762 3763 3764 3765 3766 3767
		objlist.push(
			{
				buffer: buffer,
				object: object,
				opaque: null,
				transparent: null
			}
		);
3768

3769
	};
3770

3771
	function addBufferImmediate ( objlist, object ) {
3772

3773 3774 3775 3776 3777
		objlist.push(
			{
				object: object,
				opaque: null,
				transparent: null
3778
			}
3779
		);
3780

3781
	};
3782

3783
	// Objects updates
3784

3785
	function updateObject ( object ) {
3786

3787 3788
		var geometry = object.geometry,
			geometryGroup, customAttributesDirty, material;
3789

3790
		if ( object instanceof THREE.Mesh ) {
3791

3792 3793 3794 3795 3796
			if ( geometry instanceof THREE.BufferGeometry ) {

				if ( geometry.__dirtyVertices || geometry.__dirtyElements ||
					 geometry.__dirtyUvs || geometry.__dirtyNormals ||
					 geometry.__dirtyColors  ) {
3797

3798 3799
					// TODO
					// set buffers from typed arrays
3800

3801
				}
3802

3803 3804 3805 3806 3807
				geometry.__dirtyVertices = false;
				geometry.__dirtyElements = false;
				geometry.__dirtyUvs = false;
				geometry.__dirtyNormals = false;
				geometry.__dirtyColors = false;
3808

3809
			} else {
3810

3811
				// check all geometry groups
3812

3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827
				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 );

					}
3828

3829
				}
M
Mr.doob 已提交
3830

3831 3832 3833 3834 3835 3836 3837
				geometry.__dirtyVertices = false;
				geometry.__dirtyMorphTargets = false;
				geometry.__dirtyElements = false;
				geometry.__dirtyUvs = false;
				geometry.__dirtyNormals = false;
				geometry.__dirtyColors = false;
				geometry.__dirtyTangents = false;
3838

3839
				material.attributes && clearCustomAttributes( material );
3840

3841
			}
3842

3843
		} else if ( object instanceof THREE.Ribbon ) {
3844

3845
			if ( geometry.__dirtyVertices || geometry.__dirtyColors ) {
3846

3847
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
3848

3849
			}
3850

3851 3852
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
3853

3854
		} else if ( object instanceof THREE.Line ) {
3855

3856
			material = getBufferMaterial( object, geometryGroup );
A
alteredq 已提交
3857

3858
			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
A
alteredq 已提交
3859

3860
			if ( geometry.__dirtyVertices ||  geometry.__dirtyColors || customAttributesDirty ) {
A
alteredq 已提交
3861

3862
				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
3863

3864
			}
3865

3866 3867
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
3868

3869
			material.attributes && clearCustomAttributes( material );
3870

3871
		} else if ( object instanceof THREE.ParticleSystem ) {
3872

3873
			material = getBufferMaterial( object, geometryGroup );
3874

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

3877
			if ( geometry.__dirtyVertices || geometry.__dirtyColors || object.sortParticles || customAttributesDirty ) {
3878

3879
				setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
3880

3881
			}
3882

3883 3884
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
3885

3886
			material.attributes && clearCustomAttributes( material );
3887

3888
		}
3889

3890
	};
3891

3892
	// Objects updates - custom attributes check
3893

3894
	function areCustomAttributesDirty ( material ) {
3895

3896
		for ( var a in material.attributes ) {
3897

3898
			if ( material.attributes[ a ].needsUpdate ) return true;
3899

3900
		}
3901

3902
		return false;
3903

3904
	};
3905

3906 3907 3908
	function clearCustomAttributes ( material ) {

		for ( var a in material.attributes ) {
3909

3910
			material.attributes[ a ].needsUpdate = false;
3911

3912
		}
3913

3914
	};
3915

3916
	// Objects removal
3917

3918
	function removeObject ( object, scene ) {
3919

3920 3921 3922 3923
		if ( object instanceof THREE.Mesh  ||
			 object instanceof THREE.ParticleSystem ||
			 object instanceof THREE.Ribbon ||
			 object instanceof THREE.Line ) {
3924

3925
			removeInstances( scene.__webglObjects, object );
3926

3927
		} else if ( object instanceof THREE.Sprite ) {
3928

3929
			removeInstancesDirect( scene.__webglSprites, object );
3930

3931 3932 3933 3934
		} else if ( object instanceof THREE.LensFlare ) {

			removeInstancesDirect( scene.__webglFlares, object );

3935
		} else if ( object instanceof THREE.MarchingCubes || object.immediateRenderCallback ) {
3936

3937
			removeInstances( scene.__webglObjectsImmediate, object );
3938

3939
		}
3940

3941
		object.__webglActive = false;
3942

3943
	};
3944

3945
	function removeInstances ( objlist, object ) {
3946

3947
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
3948

3949
			if ( objlist[ o ].object === object ) {
3950

3951
				objlist.splice( o, 1 );
3952

3953
			}
3954

3955
		}
3956

3957
	};
3958

3959
	function removeInstancesDirect ( objlist, object ) {
3960

3961
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
3962

3963
			if ( objlist[ o ] === object ) {
3964

3965
				objlist.splice( o, 1 );
3966

3967
			}
3968

3969
		}
3970

3971
	};
3972

3973
	// Materials
3974

3975
	this.initMaterial = function ( material, lights, fog, object ) {
3976

3977
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
3978

3979
		if ( material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
3980

3981
			shaderID = 'depth';
3982

3983
		} else if ( material instanceof THREE.MeshNormalMaterial ) {
3984

3985
			shaderID = 'normal';
M
Mr.doob 已提交
3986

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

3989
			shaderID = 'basic';
M
Mr.doob 已提交
3990

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

3993
			shaderID = 'lambert';
M
Mr.doob 已提交
3994

3995
		} else if ( material instanceof THREE.MeshPhongMaterial ) {
3996

3997
			shaderID = 'phong';
3998

3999
		} else if ( material instanceof THREE.LineBasicMaterial ) {
4000

4001
			shaderID = 'basic';
4002

4003
		} else if ( material instanceof THREE.ParticleBasicMaterial ) {
4004

4005
			shaderID = 'particle_basic';
4006 4007 4008

		}

4009
		if ( shaderID ) {
4010

4011
			setMaterialShaders( material, THREE.ShaderLib[ shaderID ] );
4012

4013
		}
4014

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

4018
		maxLightCount = allocateLights( lights );
4019

4020
		maxShadows = allocateShadows( lights );
4021

4022
		maxBones = allocateBones( object );
4023

4024
		parameters = {
4025

4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042
			map: !!material.map, envMap: !!material.envMap, lightMap: !!material.lightMap,
			vertexColors: material.vertexColors,
			fog: fog, useFog: material.fog,
			sizeAttenuation: material.sizeAttenuation,
			skinning: material.skinning,
			morphTargets: material.morphTargets,
			maxMorphTargets: this.maxMorphTargets,
			maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
			maxBones: maxBones,
			shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
			shadowMapSoft: this.shadowMapSoft,
			shadowMapWidth: this.shadowMapWidth,
			shadowMapHeight: this.shadowMapHeight,
			maxShadows: maxShadows,
			alphaTest: material.alphaTest,
			metal: material.metal,
			perPixel: material.perPixel
4043

4044
		};
M
Mr.doob 已提交
4045

4046
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
4047

4048
		var attributes = material.program.attributes;
4049

4050 4051 4052 4053
		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 );
4054

4055 4056 4057
		if ( material.skinning &&
			 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
M
Mr.doob 已提交
4058

4059 4060 4061 4062
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
M
Mr.doob 已提交
4063 4064

		}
4065

4066
		if ( material.attributes ) {
A
alteredq 已提交
4067

4068
			for ( a in material.attributes ) {
M
Mr.doob 已提交
4069

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

4072
			}
M
Mr.doob 已提交
4073

4074
		}
M
Mr.doob 已提交
4075

4076
		if ( material.morphTargets ) {
M
Mr.doob 已提交
4077

4078
			material.numSupportedMorphTargets = 0;
4079

4080
			var id, base = "morphTarget";
4081

4082
			for ( i = 0; i < this.maxMorphTargets; i ++ ) {
4083

4084
				id = base + i;
M
Mr.doob 已提交
4085

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

4088 4089
					_gl.enableVertexAttribArray( attributes[ id ] );
					material.numSupportedMorphTargets ++;
4090

4091
				}
4092

4093
			}
4094

4095
		}
4096

4097
		material.uniformsList = [];
4098

4099
		for ( u in material.uniforms ) {
4100

4101
			material.uniformsList.push( [ material.uniforms[ u ], u ] );
4102

4103
		}
M
Mr.doob 已提交
4104

4105
	};
M
Mr.doob 已提交
4106

4107
	function setMaterialShaders ( material, shaders ) {
M
Mr.doob 已提交
4108

4109 4110 4111
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
M
Mr.doob 已提交
4112

4113
	};
M
Mr.doob 已提交
4114

4115
	function setProgram ( camera, lights, fog, material, object ) {
4116

4117
		if ( ! material.program ) {
4118

4119
			_this.initMaterial( material, lights, fog, object );
4120

4121
		}
4122

4123
		if ( material.morphTargets ) {
4124

4125
			if ( ! object.__webglMorphTargetInfluences ) {
4126

4127
				object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );
4128

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

4131
					object.__webglMorphTargetInfluences[ i ] = 0;
4132

4133
				}
4134

4135
			}
4136

4137
		}
4138

4139
		var refreshMaterial = false;
4140

4141 4142 4143
		var program = material.program,
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
4144

4145
		if ( program !== _currentProgram ) {
4146

4147 4148
			_gl.useProgram( program );
			_currentProgram = program;
4149

4150
			refreshMaterial = true;
4151

4152
		}
4153

4154
		if ( material.id !== _currentMaterialId ) {
4155

4156 4157
			_currentMaterialId = material.id;
			refreshMaterial = true;
4158

4159
		}
4160

4161
		if ( refreshMaterial ) {
4162

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

4165
			// refresh uniforms common to several materials
4166

4167
			if ( fog && material.fog ) {
4168

4169
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
4170

4171
			}
M
Mr.doob 已提交
4172

4173 4174 4175
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material.lights ) {
4176

4177 4178
				setupLights( program, lights );
				refreshUniformsLights( m_uniforms, _lights );
4179

4180
			}
M
Mr.doob 已提交
4181

4182 4183 4184
			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
4185

4186
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
4187 4188 4189

			}

4190
			// refresh single material specific uniforms
M
Mr.doob 已提交
4191

4192
			if ( material instanceof THREE.LineBasicMaterial ) {
4193

4194
				refreshUniformsLine( m_uniforms, material );
M
Mr.doob 已提交
4195

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

4198
				refreshUniformsParticle( m_uniforms, material );
M
Mr.doob 已提交
4199

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

4202
				refreshUniformsPhong( m_uniforms, material );
M
Mr.doob 已提交
4203

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

4206
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
4207

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

4210 4211 4212
				m_uniforms.mNear.value = camera.near;
				m_uniforms.mFar.value = camera.far;
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4213

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

4216
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4217

4218
			}
M
Mr.doob 已提交
4219

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

4222
				refreshUniformsShadow( m_uniforms, material );
M
Mr.doob 已提交
4223

4224
			}
M
Mr.doob 已提交
4225

4226
			// load common uniforms
M
Mr.doob 已提交
4227

4228
			loadUniformsGeneric( program, material.uniformsList );
M
Mr.doob 已提交
4229

4230 4231
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)
4232

4233 4234 4235
			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
				 material.envMap ) {
4236

4237
				if( p_uniforms.cameraPosition !== null ) {
4238

4239
					_gl.uniform3f( p_uniforms.cameraPosition, camera.position.x, camera.position.y, camera.position.z );
4240

4241
				}
4242 4243 4244

			}

4245 4246 4247 4248
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {
4249

4250
				if( p_uniforms.viewMatrix !== null ) {
4251

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

4254
				}
4255

4256
			}
M
Mr.doob 已提交
4257

4258
			if ( material.skinning ) {
4259

A
alteredq 已提交
4260
				loadUniformsSkinning( p_uniforms, object, camera );
4261

4262
			}
4263

4264
		}
M
Mr.doob 已提交
4265

4266
		loadUniformsMatrices( p_uniforms, object );
M
Mr.doob 已提交
4267

4268 4269 4270 4271
		if ( material instanceof THREE.ShaderMaterial ||
			 material.envMap ||
			 material.skinning ||
			 object.receiveShadow ) {
M
Mr.doob 已提交
4272

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

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

4277
			}
4278

4279
		}
4280

4281
		return program;
4282

4283
	};
4284

4285
	// Uniforms (refresh uniforms objects)
A
alteredq 已提交
4286

4287
	function refreshUniformsCommon ( uniforms, material ) {
4288

4289
		uniforms.opacity.value = material.opacity;
4290

4291
		if ( _this.gammaInput ) {
4292

4293
			uniforms.diffuse.value.copyGammaToLinear( material.color );
4294

4295
		} else {
4296

4297
			uniforms.diffuse.value = material.color;
4298

4299
		}
4300

4301
		uniforms.map.texture = material.map;
4302

4303
		if ( material.map ) {
4304

4305
			uniforms.offsetRepeat.value.set( material.map.offset.x, material.map.offset.y, material.map.repeat.x, material.map.repeat.y );
M
Mr.doob 已提交
4306

4307
		}
M
Mr.doob 已提交
4308

4309
		uniforms.lightMap.texture = material.lightMap;
4310

4311 4312
		uniforms.envMap.texture = material.envMap;
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
4313

4314
		if ( _this.gammaInput ) {
4315

4316 4317
			//uniforms.reflectivity.value = material.reflectivity * material.reflectivity;
			uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
4318

4319
		} else {
4320

4321
			uniforms.reflectivity.value = material.reflectivity;
4322

4323
		}
4324

4325 4326 4327
		uniforms.refractionRatio.value = material.refractionRatio;
		uniforms.combine.value = material.combine;
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
M
Mr.doob 已提交
4328

4329
	};
M
Mr.doob 已提交
4330

4331
	function refreshUniformsLine ( uniforms, material ) {
M
Mr.doob 已提交
4332

4333 4334
		uniforms.diffuse.value = material.color;
		uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4335

4336
	};
M
Mr.doob 已提交
4337

4338
	function refreshUniformsParticle ( uniforms, material ) {
4339

4340 4341 4342 4343
		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.
4344

4345
		uniforms.map.texture = material.map;
4346

4347
	};
4348

4349
	function refreshUniformsFog ( uniforms, fog ) {
4350

4351
		uniforms.fogColor.value = fog.color;
4352

4353
		if ( fog instanceof THREE.Fog ) {
4354

4355 4356
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
4357

4358
		} else if ( fog instanceof THREE.FogExp2 ) {
M
Mikael Emtinger 已提交
4359

4360
			uniforms.fogDensity.value = fog.density;
M
Mikael Emtinger 已提交
4361

4362
		}
M
Mikael Emtinger 已提交
4363

4364
	};
M
Mikael Emtinger 已提交
4365

4366
	function refreshUniformsPhong ( uniforms, material ) {
M
Mikael Emtinger 已提交
4367

4368
		uniforms.shininess.value = material.shininess;
4369

4370
		if ( _this.gammaInput ) {
M
Mikael Emtinger 已提交
4371

4372 4373
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
			uniforms.specular.value.copyGammaToLinear( material.specular );
4374

4375
		} else {
4376

4377 4378
			uniforms.ambient.value = material.ambient;
			uniforms.specular.value = material.specular;
4379

4380
		}
4381

4382
	};
4383

4384
	function refreshUniformsLambert ( uniforms, material ) {
4385

4386
		if ( _this.gammaInput ) {
4387

4388
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
M
Mr.doob 已提交
4389

4390
		} else {
4391

4392
			uniforms.ambient.value = material.ambient;
4393

4394
		}
4395

4396
	};
4397

4398
	function refreshUniformsLights ( uniforms, lights ) {
4399

4400
		uniforms.ambientLightColor.value = lights.ambient;
4401

4402 4403
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
4404

4405 4406 4407
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
		uniforms.pointLightDistance.value = lights.point.distances;
4408

4409
	};
4410

4411
	function refreshUniformsShadow ( uniforms, material ) {
M
Mr.doob 已提交
4412

4413
		if ( uniforms.shadowMatrix ) {
4414

A
alteredq 已提交
4415
			for ( var i = 0; i < _this.shadowMapPlugin.shadowMatrix.length; i ++ ) {
4416

A
alteredq 已提交
4417 4418
				uniforms.shadowMatrix.value[ i ] = _this.shadowMapPlugin.shadowMatrix[ i ];
				uniforms.shadowMap.texture[ i ] = _this.shadowMapPlugin.shadowMap[ i ];
4419 4420


4421
			}
4422

4423 4424 4425
			uniforms.shadowDarkness.value = _this.shadowMapDarkness;
			uniforms.shadowBias.value = _this.shadowMapBias;

4426 4427
		}

4428
	};
4429

4430
	// Uniforms (load to GPU)
4431

A
alteredq 已提交
4432
	function loadUniformsSkinning ( uniforms, object, camera ) {
4433

A
alteredq 已提交
4434
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, camera._viewMatrixArray );
4435
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
4436

4437
	};
4438

4439

4440
	function loadUniformsMatrices ( uniforms, object ) {
4441

4442
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
4443

4444
		if ( uniforms.normalMatrix ) {
4445

4446
			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );
4447

4448
		}
4449

4450
	};
4451

4452
	function loadUniformsGeneric ( program, uniforms ) {
4453

4454
		var uniform, value, type, location, texture, i, il, j, jl, offset;
4455

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

4458 4459
			location = program.uniforms[ uniforms[ j ][ 1 ] ];
			if ( !location ) continue;
4460

4461
			uniform = uniforms[ j ][ 0 ];
4462

4463 4464
			type = uniform.type;
			value = uniform.value;
4465

4466
			// single integer
4467

4468
			if( type === "i" ) {
4469

4470
				_gl.uniform1i( location, value );
4471

4472
			// single float
4473

4474
			} else if( type === "f" ) {
4475

4476
				_gl.uniform1f( location, value );
4477

4478
			// single THREE.Vector2
4479

4480
			} else if( type === "v2" ) {
4481

4482
				_gl.uniform2f( location, value.x, value.y );
4483

4484
			// single THREE.Vector3
4485

4486
			} else if( type === "v3" ) {
4487

4488
				_gl.uniform3f( location, value.x, value.y, value.z );
4489

4490
			// single THREE.Vector4
4491

4492
			} else if( type === "v4" ) {
4493

4494
				_gl.uniform4f( location, value.x, value.y, value.z, value.w );
4495

4496
			// single THREE.Color
4497

4498
			} else if( type === "c" ) {
4499

4500
				_gl.uniform3f( location, value.r, value.g, value.b );
4501

4502
			// flat array of floats (JS or typed array)
4503

4504
			} else if( type === "fv1" ) {
4505

4506
				_gl.uniform1fv( location, value );
4507

4508
			// flat array of floats with 3 x N size (JS or typed array)
4509

4510
			} else if( type === "fv" ) {
4511

4512
				_gl.uniform3fv( location, value );
4513

4514
			// array of THREE.Vector3
4515

4516
			} else if( type === "v3v" ) {
4517

4518
				if ( ! uniform._array ) {
4519

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

4522
				}
A
alteredq 已提交
4523

4524
				for ( i = 0, il = value.length; i < il; i ++ ) {
A
alteredq 已提交
4525

4526
					offset = i * 3;
4527

4528 4529 4530
					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;
					uniform._array[ offset + 2 ] = value[ i ].z;
4531

4532
				}
4533

4534
				_gl.uniform3fv( location, uniform._array );
4535

4536
			// single THREE.Matrix4
4537

4538
			} else if( type === "m4" ) {
M
Mr.doob 已提交
4539

4540
				if ( ! uniform._array ) {
A
alteredq 已提交
4541

4542
					uniform._array = new Float32Array( 16 );
4543

4544
				}
4545

4546 4547
				value.flattenToArray( uniform._array );
				_gl.uniformMatrix4fv( location, false, uniform._array );
4548

4549
			// array of THREE.Matrix4
4550

4551
			} else if( type === "m4v" ) {
A
alteredq 已提交
4552

4553 4554 4555
				if ( ! uniform._array ) {

					uniform._array = new Float32Array( 16 * value.length );
A
alteredq 已提交
4556

M
Mr.doob 已提交
4557
				}
M
Mr.doob 已提交
4558

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

4561
					value[ i ].flattenToArrayOffset( uniform._array, i * 16 );
M
Mr.doob 已提交
4562

4563
				}
A
alteredq 已提交
4564

4565
				_gl.uniformMatrix4fv( location, false, uniform._array );
M
Mr.doob 已提交
4566

4567

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

4570
			} else if( type === "t" ) {
A
alteredq 已提交
4571

4572
				_gl.uniform1i( location, value );
4573

4574
				texture = uniform.texture;
A
alteredq 已提交
4575

4576
				if ( !texture ) continue;
A
alteredq 已提交
4577

4578
				if ( texture.image instanceof Array && texture.image.length === 6 ) {
A
alteredq 已提交
4579

4580
					setCubeTexture( texture, value );
A
alteredq 已提交
4581

4582
				} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
M
Mr.doob 已提交
4583

4584 4585 4586 4587
					setCubeTextureDynamic( texture, value );

				} else {

4588
					_this.setTexture( texture, value );
4589

M
Mr.doob 已提交
4590
				}
M
Mr.doob 已提交
4591

4592
			// array of THREE.Texture (2d)
M
Mr.doob 已提交
4593

4594
			} else if( type === "tv" ) {
M
Mr.doob 已提交
4595

4596
				if ( ! uniform._array ) {
M
Mr.doob 已提交
4597

4598
					uniform._array = [];
A
alteredq 已提交
4599

4600 4601 4602 4603 4604
					for( i = 0, il = uniform.texture.length; i < il; i ++ ) {

						uniform._array[ i ] = value + i;

					}
A
alteredq 已提交
4605

M
Mr.doob 已提交
4606
				}
A
alteredq 已提交
4607

4608
				_gl.uniform1iv( location, uniform._array );
A
alteredq 已提交
4609

4610
				for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
4611

4612
					texture = uniform.texture[ i ];
4613

4614
					if ( !texture ) continue;
M
Mr.doob 已提交
4615

4616
					_this.setTexture( texture, uniform._array[ i ] );
M
Mr.doob 已提交
4617

M
Mr.doob 已提交
4618
				}
M
Mr.doob 已提交
4619

M
Mr.doob 已提交
4620
			}
M
Mr.doob 已提交
4621

M
Mr.doob 已提交
4622
		}
M
Mr.doob 已提交
4623

4624
	};
M
Mr.doob 已提交
4625

A
alteredq 已提交
4626
	function setupMatrices ( object, camera ) {
M
Mr.doob 已提交
4627

4628
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
M
Mr.doob 已提交
4629

4630
		var inverseMatrix = THREE.Matrix4.makeInvert3x3( object._modelViewMatrix );
4631

4632
		if ( inverseMatrix ) {
4633

4634
			inverseMatrix.transposeIntoArray( object._normalMatrixArray );
M
Mr.doob 已提交
4635

4636
		}
M
Mr.doob 已提交
4637

A
alteredq 已提交
4638
	};
M
Mr.doob 已提交
4639

4640
	function setupLights ( program, lights ) {
M
Mr.doob 已提交
4641

4642 4643 4644
		var l, ll, light, n,
		r = 0, g = 0, b = 0,
		color, position, intensity, distance,
M
Mr.doob 已提交
4645

4646
		zlights = _lights,
A
alteredq 已提交
4647

4648 4649
		dcolors = zlights.directional.colors,
		dpositions = zlights.directional.positions,
A
alteredq 已提交
4650

4651 4652 4653
		pcolors = zlights.point.colors,
		ppositions = zlights.point.positions,
		pdistances = zlights.point.distances,
4654

4655 4656
		dlength = 0,
		plength = 0,
4657

4658 4659
		doffset = 0,
		poffset = 0;
4660

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

4663 4664
			light = lights[ l ];
			color = light.color;
A
alteredq 已提交
4665

4666 4667
			intensity = light.intensity;
			distance = light.distance;
A
alteredq 已提交
4668

4669
			if ( light instanceof THREE.AmbientLight ) {
4670

4671
				if ( _this.gammaInput ) {
4672

4673 4674 4675
					r += color.r * color.r;
					g += color.g * color.g;
					b += color.b * color.b;
4676

4677
				} else {
4678

4679 4680 4681
					r += color.r;
					g += color.g;
					b += color.b;
4682

4683
				}
4684

4685
			} else if ( light instanceof THREE.DirectionalLight ) {
4686

4687
				doffset = dlength * 3;
4688

4689
				if ( _this.gammaInput ) {
4690

4691 4692 4693
					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;
4694

4695
				} else {
4696

4697 4698 4699
					dcolors[ doffset ]     = color.r * intensity;
					dcolors[ doffset + 1 ] = color.g * intensity;
					dcolors[ doffset + 2 ] = color.b * intensity;
A
alteredq 已提交
4700

4701
				}
A
alteredq 已提交
4702

A
alteredq 已提交
4703 4704 4705 4706 4707 4708 4709
				position = light.matrixWorld.getPosition();

				n = 1 / position.length();

				dpositions[ doffset ]     = position.x * n;
				dpositions[ doffset + 1 ] = position.y * n;
				dpositions[ doffset + 2 ] = position.z * n;
A
alteredq 已提交
4710

4711
				dlength += 1;
A
alteredq 已提交
4712

4713
			} else if ( light instanceof THREE.SpotLight ) { // hack, not a proper spotlight
A
alteredq 已提交
4714

4715
				doffset = dlength * 3;
A
alteredq 已提交
4716

4717
				if ( _this.gammaInput ) {
4718

4719 4720 4721
					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;
4722

4723
				} else {
A
alteredq 已提交
4724

4725 4726 4727
					dcolors[ doffset ]     = color.r * intensity;
					dcolors[ doffset + 1 ] = color.g * intensity;
					dcolors[ doffset + 2 ] = color.b * intensity;
A
alteredq 已提交
4728 4729 4730

				}

A
alteredq 已提交
4731 4732
				position = light.matrixWorld.getPosition();

4733
				n = 1 / position.length();
A
alteredq 已提交
4734

4735 4736 4737
				dpositions[ doffset ]     = position.x * n;
				dpositions[ doffset + 1 ] = position.y * n;
				dpositions[ doffset + 2 ] = position.z * n;
M
Mr.doob 已提交
4738

4739
				dlength += 1;
4740

4741
			} else if( light instanceof THREE.PointLight ) {
M
Mr.doob 已提交
4742

4743
				poffset = plength * 3;
M
Mr.doob 已提交
4744

4745
				if ( _this.gammaInput ) {
4746

4747 4748 4749
					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 已提交
4750

4751
				} else {
A
alteredq 已提交
4752

4753 4754 4755
					pcolors[ poffset ]     = color.r * intensity;
					pcolors[ poffset + 1 ] = color.g * intensity;
					pcolors[ poffset + 2 ] = color.b * intensity;
A
alteredq 已提交
4756

4757
				}
A
alteredq 已提交
4758

A
alteredq 已提交
4759 4760
				position = light.matrixWorld.getPosition();

4761 4762 4763
				ppositions[ poffset ]     = position.x;
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
A
alteredq 已提交
4764

4765
				pdistances[ plength ] = distance;
A
alteredq 已提交
4766

4767
				plength += 1;
4768

4769
			}
4770

4771
		}
A
alteredq 已提交
4772

4773 4774
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
A
alteredq 已提交
4775

4776 4777
		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 已提交
4778

4779 4780
		zlights.point.length = plength;
		zlights.directional.length = dlength;
A
alteredq 已提交
4781

4782 4783 4784
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
4785

4786
	};
M
Mr.doob 已提交
4787

4788
	// GL state setting
M
Mr.doob 已提交
4789

4790
	this.setFaceCulling = function ( cullFace, frontFace ) {
M
Mr.doob 已提交
4791

4792
		if ( cullFace ) {
M
Mr.doob 已提交
4793

4794
			if ( !frontFace || frontFace === "ccw" ) {
4795

4796
				_gl.frontFace( _gl.CCW );
4797

4798
			} else {
4799

4800
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
4801

4802
			}
M
Mr.doob 已提交
4803

4804
			if( cullFace === "back" ) {
4805

4806
				_gl.cullFace( _gl.BACK );
4807

4808
			} else if( cullFace === "front" ) {
4809

4810
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
4811

4812
			} else {
4813

4814
				_gl.cullFace( _gl.FRONT_AND_BACK );
4815

4816
			}
4817

4818
			_gl.enable( _gl.CULL_FACE );
4819

4820
		} else {
4821

4822
			_gl.disable( _gl.CULL_FACE );
4823 4824 4825 4826 4827

		}

	};

A
alteredq 已提交
4828
	this.setObjectFaces = function ( object ) {
4829

4830
		if ( _oldDoubleSided !== object.doubleSided ) {
M
Mr.doob 已提交
4831

4832
			if( object.doubleSided ) {
M
Mr.doob 已提交
4833

4834
				_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
4835

4836
			} else {
4837

4838
				_gl.enable( _gl.CULL_FACE );
4839

4840
			}
4841

4842
			_oldDoubleSided = object.doubleSided;
4843

4844
		}
4845

4846
		if ( _oldFlipSided !== object.flipSided ) {
4847

4848
			if( object.flipSided ) {
4849

4850
				_gl.frontFace( _gl.CW );
4851

4852
			} else {
4853

4854
				_gl.frontFace( _gl.CCW );
4855

4856
			}
4857

4858
			_oldFlipSided = object.flipSided;
4859

4860
		}
4861

4862
	};
4863

A
alteredq 已提交
4864
	this.setDepthTest = function ( depthTest ) {
4865

4866
		if ( _oldDepthTest !== depthTest ) {
4867

4868
			if( depthTest ) {
4869

4870
				_gl.enable( _gl.DEPTH_TEST );
4871

4872
			} else {
4873

4874
				_gl.disable( _gl.DEPTH_TEST );
4875 4876 4877

			}

4878
			_oldDepthTest = depthTest;
4879

4880
		}
4881

4882
	};
4883

A
alteredq 已提交
4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895
	function setLineWidth ( width ) {

		if ( width !== _oldLineWidth ) {

			_gl.lineWidth( width );

			_oldLineWidth = width;

		}

	};

4896
	function setDepthWrite ( depthWrite ) {
4897

4898
		if ( _oldDepthWrite !== depthWrite ) {
4899

4900 4901
			_gl.depthMask( depthWrite );
			_oldDepthWrite = depthWrite;
4902 4903 4904

		}

4905
	};
4906

4907
	function setPolygonOffset ( polygonoffset, factor, units ) {
4908

4909
		if ( _oldPolygonOffset !== polygonoffset ) {
M
Mr.doob 已提交
4910

4911
			if ( polygonoffset ) {
4912

4913
				_gl.enable( _gl.POLYGON_OFFSET_FILL );
4914

4915
			} else {
4916

4917
				_gl.disable( _gl.POLYGON_OFFSET_FILL );
4918

4919
			}
4920

4921
			_oldPolygonOffset = polygonoffset;
4922

4923
		}
4924

4925
		if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
4926

4927
			_gl.polygonOffset( factor, units );
M
Mr.doob 已提交
4928

4929 4930
			_oldPolygonOffsetFactor = factor;
			_oldPolygonOffsetUnits = units;
M
Mr.doob 已提交
4931

4932
		}
M
Mr.doob 已提交
4933

4934
	};
M
Mr.doob 已提交
4935

4936
	this.setBlending = function ( blending ) {
M
Mr.doob 已提交
4937

4938
		if ( blending !== _oldBlending ) {
M
Mr.doob 已提交
4939

4940
			switch ( blending ) {
M
Mr.doob 已提交
4941

4942
				case THREE.AdditiveBlending:
M
Mr.doob 已提交
4943

4944 4945
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
M
Mr.doob 已提交
4946

4947
					break;
M
Mr.doob 已提交
4948

4949
				case THREE.SubtractiveBlending:
M
Mr.doob 已提交
4950

4951
					// TODO: Find blendFuncSeparate() combination
M
Mr.doob 已提交
4952

4953 4954
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
M
Mr.doob 已提交
4955

4956
					break;
M
Mr.doob 已提交
4957

4958
				case THREE.MultiplyBlending:
M
Mr.doob 已提交
4959

4960
					// TODO: Find blendFuncSeparate() combination
M
Mr.doob 已提交
4961

4962 4963
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
M
Mr.doob 已提交
4964

4965
					break;
4966

4967
				default:
N
Nicolas Garcia Belmonte 已提交
4968

4969 4970
					_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 );
4971

4972
					break;
4973

4974
			}
4975

4976
			_oldBlending = blending;
4977

4978
		}
4979 4980

	};
4981

4982 4983 4984
	// Shaders

	function buildProgram ( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
4985

4986
		var p, pl, program, code;
4987
		var chunks = [];
4988 4989 4990

		// Generate code

4991 4992 4993 4994 4995 4996 4997 4998 4999 5000
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

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

		}
5001 5002 5003

		for ( p in parameters ) {

5004 5005
			chunks.push( p );
			chunks.push( parameters[ p ] );
5006 5007 5008

		}

5009 5010
		code = chunks.join();

5011 5012 5013 5014
		// Check if code has been already compiled

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

5015
			if ( _programs[ p ].code === code ) {
5016 5017

				// console.log( "Code already compiled." /*: \n\n" + code*/ );
5018

5019 5020 5021 5022 5023
				return _programs[ p ].program;

			}

		}
5024

5025
		//console.log( "building new program " );
5026 5027 5028

		//

5029
		program = _gl.createProgram();
M
Mr.doob 已提交
5030

5031
		var prefix_vertex = [
M
Mr.doob 已提交
5032

A
alteredq 已提交
5033
			_supportsVertexTextures ? "#define VERTEX_TEXTURES" : "",
5034

5035 5036 5037 5038
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

5039 5040 5041
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

5042 5043
			"#define MAX_SHADOWS " + parameters.maxShadows,

5044 5045
			"#define MAX_BONES " + parameters.maxBones,

5046
			parameters.map ? "#define USE_MAP" : "",
5047 5048 5049
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5050
			parameters.skinning ? "#define USE_SKINNING" : "",
5051
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
A
alteredq 已提交
5052
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
5053

5054
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5055
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
5056

5057 5058
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
5059 5060 5061
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
5062 5063
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
5064
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
5065 5066 5067

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
5068 5069 5070
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
5071
			"attribute vec2 uv2;",
5072

5073
			"#ifdef USE_COLOR",
5074

5075
				"attribute vec3 color;",
5076

5077 5078
			"#endif",

5079
			"#ifdef USE_MORPHTARGETS",
5080

5081 5082 5083 5084 5085 5086 5087 5088
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
				"attribute vec3 morphTarget4;",
				"attribute vec3 morphTarget5;",
				"attribute vec3 morphTarget6;",
				"attribute vec3 morphTarget7;",
5089

5090 5091 5092
			"#endif",

			"#ifdef USE_SKINNING",
5093

5094 5095 5096 5097
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
5098

5099
			"#endif",
5100

M
Mr.doob 已提交
5101
			""
A
alteredq 已提交
5102

M
Mr.doob 已提交
5103
		].join("\n");
5104

M
Mr.doob 已提交
5105 5106
		var prefix_fragment = [

5107
			"precision " + _precision + " float;",
M
Mr.doob 已提交
5108 5109 5110 5111

			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

5112 5113
			"#define MAX_SHADOWS " + parameters.maxShadows,

5114 5115
			parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",

5116 5117 5118 5119
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

M
Mr.doob 已提交
5120 5121
			( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
			( parameters.useFog && parameters.fog instanceof THREE.FogExp2 ) ? "#define FOG_EXP2" : "",
M
Mr.doob 已提交
5122 5123 5124 5125 5126

			parameters.map ? "#define USE_MAP" : "",
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5127

5128 5129 5130
			parameters.metal ? "#define METAL" : "",
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",

5131
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5132 5133 5134
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
			parameters.shadowMapSoft ? "#define SHADOWMAP_WIDTH " + parameters.shadowMapWidth.toFixed( 1 ) : "",
			parameters.shadowMapSoft ? "#define SHADOWMAP_HEIGHT " + parameters.shadowMapHeight.toFixed( 1 ) : "",
M
Mr.doob 已提交
5135 5136 5137 5138 5139 5140 5141

			"uniform mat4 viewMatrix;",
			"uniform vec3 cameraPosition;",
			""

		].join("\n");

5142 5143
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
5144

M
Mr.doob 已提交
5145
		_gl.linkProgram( program );
N
Nicolas Garcia Belmonte 已提交
5146

M
Mr.doob 已提交
5147
		if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
N
Nicolas Garcia Belmonte 已提交
5148

5149
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
5150

N
Nicolas Garcia Belmonte 已提交
5151
		}
5152

5153 5154
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
5155

M
Mr.doob 已提交
5156
		program.uniforms = {};
5157
		program.attributes = {};
M
Mr.doob 已提交
5158

5159 5160 5161 5162
		var identifiers, u, a, i;

		// cache uniform locations

5163
		identifiers = [
5164

5165 5166
			'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
			'cameraInverseMatrix', 'boneGlobalMatrices', 'morphTargetInfluences'
M
Mr.doob 已提交
5167

5168
		];
M
Mr.doob 已提交
5169

5170
		for ( u in uniforms ) {
M
Mr.doob 已提交
5171

5172
			identifiers.push( u );
M
Mr.doob 已提交
5173

5174
		}
M
Mr.doob 已提交
5175

5176
		cacheUniformLocations( program, identifiers );
M
Mr.doob 已提交
5177

5178
		// cache attributes locations
M
Mr.doob 已提交
5179

5180
		identifiers = [
A
alteredq 已提交
5181

5182 5183
			"position", "normal", "uv", "uv2", "tangent", "color",
			"skinVertexA", "skinVertexB", "skinIndex", "skinWeight"
A
alteredq 已提交
5184

5185
		];
M
Mr.doob 已提交
5186

5187
		for ( i = 0; i < parameters.maxMorphTargets; i ++ ) {
M
Mr.doob 已提交
5188

5189
			identifiers.push( "morphTarget" + i );
M
Mr.doob 已提交
5190

5191
		}
5192

5193
		for ( a in attributes ) {
5194

5195
			identifiers.push( a );
5196

5197
		}
5198

5199
		cacheAttributeLocations( program, identifiers );
5200

5201
		program.id = _programs.length;
5202

5203
		_programs.push( { program: program, code: code } );
5204

5205
		_this.info.memory.programs = _programs.length;
5206

5207
		return program;
5208

5209
	};
5210

5211
	// Shader parameters cache
5212

5213
	function cacheUniformLocations ( program, identifiers ) {
5214

5215
		var i, l, id;
5216

5217
		for( i = 0, l = identifiers.length; i < l; i++ ) {
5218

5219 5220
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
5221

5222
		}
M
Mr.doob 已提交
5223

5224
	};
M
Mr.doob 已提交
5225

5226
	function cacheAttributeLocations ( program, identifiers ) {
A
alteredq 已提交
5227

5228
		var i, l, id;
A
alteredq 已提交
5229

5230
		for( i = 0, l = identifiers.length; i < l; i++ ) {
A
alteredq 已提交
5231

5232 5233
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
A
alteredq 已提交
5234

5235
		}
5236

5237
	};
A
alteredq 已提交
5238

5239
	function getShader ( type, string ) {
A
alteredq 已提交
5240

5241
		var shader;
5242

5243
		if ( type === "fragment" ) {
A
alteredq 已提交
5244

5245
			shader = _gl.createShader( _gl.FRAGMENT_SHADER );
A
alteredq 已提交
5246

5247
		} else if ( type === "vertex" ) {
A
alteredq 已提交
5248

5249
			shader = _gl.createShader( _gl.VERTEX_SHADER );
A
alteredq 已提交
5250

5251
		}
A
alteredq 已提交
5252

5253 5254
		_gl.shaderSource( shader, string );
		_gl.compileShader( shader );
5255

5256
		if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {
5257

5258 5259 5260
			console.error( _gl.getShaderInfoLog( shader ) );
			console.error( string );
			return null;
5261

A
alteredq 已提交
5262 5263
		}

5264 5265
		return shader;

A
alteredq 已提交
5266
	};
5267

5268 5269
	// Textures

5270 5271 5272 5273 5274 5275 5276

	function isPowerOfTwo ( value ) {

		return ( value & ( value - 1 ) ) === 0;

	};

5277
	function setTextureParameters ( textureType, texture, image ) {
5278

5279
		if ( isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ) ) {
M
Mr.doob 已提交
5280

5281 5282
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
5283

5284 5285
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
5286

5287
			return true;
M
Mr.doob 已提交
5288

5289
		} else {
M
Mr.doob 已提交
5290

5291 5292
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
5293

5294 5295
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
5296

5297 5298
			return false;

5299
		}
M
Mr.doob 已提交
5300

5301
	};
5302

5303
	this.setTexture = function ( texture, slot ) {
5304

5305
		if ( texture.needsUpdate ) {
A
alteredq 已提交
5306

5307
			if ( ! texture.__webglInit ) {
M
Mr.doob 已提交
5308

5309
				texture.__webglInit = true;
5310
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5311

M
Mr.doob 已提交
5312 5313
				_this.info.memory.textures ++;

5314
			}
M
Mr.doob 已提交
5315

5316
			_gl.activeTexture( _gl.TEXTURE0 + slot );
5317 5318
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );

5319 5320 5321
			var needsMipMaps = setTextureParameters( _gl.TEXTURE_2D, texture, texture.image ),
			glFormat = paramThreeToGL( texture.format ),
			glType = paramThreeToGL( texture.type );
5322

5323
			if ( texture instanceof THREE.DataTexture ) {
5324

5325
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, texture.image.width, texture.image.height, 0, glFormat, glType, texture.image.data );
M
Mr.doob 已提交
5326

A
alteredq 已提交
5327
			} else {
M
Mr.doob 已提交
5328

5329
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, texture.image );
M
Mr.doob 已提交
5330 5331 5332

			}

5333 5334 5335 5336 5337
			if ( needsMipMaps ) {

				_gl.generateMipmap( _gl.TEXTURE_2D );

			}
M
Mr.doob 已提交
5338

A
alteredq 已提交
5339
			texture.needsUpdate = false;
5340

5341 5342
			if ( texture.onUpdated ) texture.onUpdated();

5343
		} else {
5344

5345 5346
			_gl.activeTexture( _gl.TEXTURE0 + slot );
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
5347 5348

		}
M
Mr.doob 已提交
5349

5350
	};
M
Mr.doob 已提交
5351

5352
	function setCubeTexture ( texture, slot ) {
5353

5354
		if ( texture.image.length === 6 ) {
5355 5356 5357

			if ( texture.needsUpdate ) {

A
alteredq 已提交
5358
				if ( ! texture.image.__webglTextureCube ) {
5359 5360

					texture.image.__webglTextureCube = _gl.createTexture();
5361

A
alteredq 已提交
5362
				}
5363

A
alteredq 已提交
5364 5365
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5366

5367 5368 5369
				var needsMipMaps = setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[ 0 ] ),
				glFormat = paramThreeToGL( texture.format ),
				glType = paramThreeToGL( texture.type );
5370

A
alteredq 已提交
5371
				for ( var i = 0; i < 6; i ++ ) {
5372

5373
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, texture.image[ i ] );
5374

A
alteredq 已提交
5375
				}
5376

5377 5378 5379 5380 5381
				if ( needsMipMaps ) {

					_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

				}
5382

A
alteredq 已提交
5383
				texture.needsUpdate = false;
5384

A
alteredq 已提交
5385
			} else {
5386

A
alteredq 已提交
5387 5388
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5389

A
alteredq 已提交
5390
			}
5391

A
alteredq 已提交
5392
		}
5393

A
alteredq 已提交
5394
	};
5395

5396
	function setCubeTextureDynamic ( texture, slot ) {
5397

A
alteredq 已提交
5398 5399
		_gl.activeTexture( _gl.TEXTURE0 + slot );
		_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
5400 5401 5402

	};

5403 5404 5405
	// Render targets

	function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
5406

5407 5408
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
A
alteredq 已提交
5409

5410
	};
M
Mr.doob 已提交
5411

5412
	function setupRenderBuffer ( renderbuffer, renderTarget  ) {
M
Mikael Emtinger 已提交
5413

5414
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
5415

5416
		if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
M
Mr.doob 已提交
5417

5418 5419
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5420

5421 5422
		/* For some reason this is not working. Defaulting to RGBA4.
		} else if( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
A
alteredq 已提交
5423

5424 5425 5426 5427
			_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 已提交
5428

5429 5430
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5431

5432
		} else {
A
alteredq 已提交
5433

5434
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
A
alteredq 已提交
5435

5436
		}
A
alteredq 已提交
5437

5438
	};
A
alteredq 已提交
5439

A
alteredq 已提交
5440
	this.setRenderTarget = function ( renderTarget ) {
A
alteredq 已提交
5441

5442
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
A
alteredq 已提交
5443

5444
		if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
A
alteredq 已提交
5445

5446 5447
			if( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
			if( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
A
alteredq 已提交
5448

5449
			renderTarget.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5450

5451
			// Setup texture, create render and frame buffers
5452

5453 5454 5455
			var glFormat = paramThreeToGL( renderTarget.format ),
				glType = paramThreeToGL( renderTarget.type );

5456
			if ( isCube ) {
M
Mr.doob 已提交
5457

5458 5459
				renderTarget.__webglFramebuffer = [];
				renderTarget.__webglRenderbuffer = [];
M
Mikael Emtinger 已提交
5460

5461 5462
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, renderTarget );
A
alteredq 已提交
5463

5464
				for ( var i = 0; i < 6; i ++ ) {
A
alteredq 已提交
5465

5466 5467
					renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
					renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
A
alteredq 已提交
5468

5469
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
A
alteredq 已提交
5470

5471 5472
					setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
					setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
A
alteredq 已提交
5473

5474
				}
5475

5476
			} else {
5477

5478 5479
				renderTarget.__webglFramebuffer = _gl.createFramebuffer();
				renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
5480

5481 5482
				_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
				setTextureParameters( _gl.TEXTURE_2D, renderTarget, renderTarget );
5483

5484
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
5485

5486 5487
				setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
				setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
5488

M
Mikael Emtinger 已提交
5489
			}
5490

5491
			// Release everything
M
Mr.doob 已提交
5492

A
alteredq 已提交
5493 5494 5495 5496 5497 5498 5499 5500 5501 5502
			if ( isCube ) {

				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

			} else {

				_gl.bindTexture( _gl.TEXTURE_2D, null );

			}

5503 5504
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
5505

5506 5507
		}

5508
		var framebuffer, width, height, vx, vy;
M
Mr.doob 已提交
5509

5510
		if ( renderTarget ) {
M
Mr.doob 已提交
5511

A
alteredq 已提交
5512 5513
			if ( isCube ) {

5514
				framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
A
alteredq 已提交
5515 5516 5517

			} else {

5518
				framebuffer = renderTarget.__webglFramebuffer;
A
alteredq 已提交
5519 5520 5521

			}

5522 5523
			width = renderTarget.width;
			height = renderTarget.height;
M
Mr.doob 已提交
5524

5525 5526 5527
			vx = 0;
			vy = 0;

5528
		} else {
M
Mr.doob 已提交
5529

5530
			framebuffer = null;
5531

5532 5533
			width = _viewportWidth;
			height = _viewportHeight;
5534

5535 5536
			vx = _viewportX;
			vy = _viewportY;
M
Mr.doob 已提交
5537

5538
		}
M
Mr.doob 已提交
5539

5540
		if ( framebuffer !== _currentFramebuffer ) {
M
Mr.doob 已提交
5541

5542
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
5543
			_gl.viewport( vx, vy, width, height );
M
Mr.doob 已提交
5544

5545
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
5546

5547
		}
5548

A
alteredq 已提交
5549 5550 5551
		_currentWidth = width;
		_currentHeight = height;

5552
	};
M
Mr.doob 已提交
5553

5554
	function updateRenderTargetMipmap ( renderTarget ) {
M
Mr.doob 已提交
5555

A
alteredq 已提交
5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568
		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 已提交
5569 5570

	};
5571

5572
	// Fallback filters for non-power-of-2 textures
5573

5574
	function filterFallback ( f ) {
5575

5576 5577 5578 5579 5580 5581 5582 5583
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mr.doob 已提交
5584
			case THREE.LinearMipMapLinearFilter:
M
Mikael Emtinger 已提交
5585
			default:
5586

M
Mikael Emtinger 已提交
5587
				return _gl.LINEAR; break;
5588 5589

		}
5590

5591
	};
5592

5593 5594
	// Map three.js constants to WebGL constants

5595
	function paramThreeToGL ( p ) {
M
Mr.doob 已提交
5596

5597
		switch ( p ) {
M
Mr.doob 已提交
5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610

			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;

5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624
			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;

5625
		}
M
Mr.doob 已提交
5626

5627
		return 0;
M
Mr.doob 已提交
5628

5629 5630
	};

5631
	// Allocations
5632

5633
	function allocateBones ( object ) {
5634

5635 5636 5637 5638 5639 5640 5641
		// 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)
5642

5643
		var maxBones = 50;
5644

5645
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
5646

5647 5648 5649 5650 5651
			maxBones = object.bones.length;

		}

		return maxBones;
5652

5653
	};
5654

5655
	function allocateLights ( lights ) {
5656

5657 5658
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
5659

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

5662
			light = lights[ l ];
5663

5664 5665 5666
			if ( light instanceof THREE.SpotLight ) dirLights ++; // hack, not a proper spotlight
			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
			if ( light instanceof THREE.PointLight ) pointLights ++;
5667

5668
		}
5669

5670
		if ( ( pointLights + dirLights ) <= _maxLights ) {
5671

5672 5673
			maxDirLights = dirLights;
			maxPointLights = pointLights;
5674

5675
		} else {
5676

5677 5678
			maxDirLights = Math.ceil( _maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = _maxLights - maxDirLights;
5679 5680 5681

		}

5682
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
5683 5684

	};
M
Mr.doob 已提交
5685

5686
	function allocateShadows ( lights ) {
5687

M
Mr.doob 已提交
5688
		var l, ll, light, maxShadows = 0;
5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701

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

			light = lights[ l ];

			if ( light instanceof THREE.SpotLight && light.castShadow ) maxShadows ++;

		}

		return maxShadows;

	};

5702
	function maxVertexTextures () {
5703

5704 5705 5706
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
M
Mr.doob 已提交
5707

5708
	// Initialization
M
Mr.doob 已提交
5709

5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760
	function initGL () {

		var gl;

		try {

			if ( ! ( gl = _canvas.getContext( 'experimental-webgl', { antialias: _antialias, stencil: _stencil, preserveDrawingBuffer: _preserveDrawingBuffer } ) ) ) {

				throw 'Error creating WebGL context.';

			}

			console.log(
				navigator.userAgent + " | " +
				gl.getParameter( gl.VERSION ) + " | " +
				gl.getParameter( gl.VENDOR ) + " | " +
				gl.getParameter( gl.RENDERER ) + " | " +
				gl.getParameter( gl.SHADING_LANGUAGE_VERSION )
			);

		} catch ( error ) {

			console.error( error );

		}

		return gl;

	};

	function setDefaultGLState () {

		_gl.clearColor( 0, 0, 0, 1 );
		_gl.clearDepth( 1 );
		_gl.clearStencil( 0 );

		_gl.enable( _gl.DEPTH_TEST );
		_gl.depthFunc( _gl.LEQUAL );

		_gl.frontFace( _gl.CCW );
		_gl.cullFace( _gl.BACK );
		_gl.enable( _gl.CULL_FACE );

		_gl.enable( _gl.BLEND );
		_gl.blendEquation( _gl.FUNC_ADD );
		_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA );

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

	};

5761 5762
	// default plugins (order is important)

A
alteredq 已提交
5763 5764 5765 5766 5767
	this.shadowMapPlugin = new THREE.ShadowMapPlugin();
	this.addPrePlugin( this.shadowMapPlugin );

	this.addPostPlugin( new THREE.SpritePlugin() );
	this.addPostPlugin( new THREE.LensFlarePlugin() );
5768

5769
};