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

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

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

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

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

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

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

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

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

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

	// clearing
M
Mr.doob 已提交
35

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

41 42
	// scene graph

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

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

	// physically based shading

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

54 55 56
	// shadow map

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

63
	// morphs
64

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

68 69 70 71
	// flags

	this.autoScaleCubemaps = true;

72 73
	// custom render plugins

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

77
	// info
78

79
	this.info = {
80

81
		memory: {
82

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

87
		},
88

89
		render: {
90

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

		}

98
	};
M
Mr.doob 已提交
99

100
	// internal properties
101

102
	var _this = this,
103

104
	_gl,
105

106
	_programs = [],
107

108
	// internal state cache
109

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

117
	// GL state cache
118

119 120
	_oldDoubleSided = null,
	_oldFlipSided = null,
121

122
	_oldBlending = null,
123 124 125 126 127

	_oldBlendEquation = null,
	_oldBlendSrc = null,
	_oldBlendDst = null,

128 129
	_oldDepthTest = null,
	_oldDepthWrite = null,
130

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

135
	_oldLineWidth = null,
136

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

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

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

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

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

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

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

157 158
	_direction = new THREE.Vector3(),

159
	_lights = {
M
Mr.doob 已提交
160

161 162
		ambient: [ 0, 0, 0 ],
		directional: { length: 0, colors: new Array(), positions: new Array() },
A
alteredq 已提交
163 164
		point: { length: 0, colors: new Array(), positions: new Array(), distances: new Array() },
		spot: { length: 0, colors: new Array(), positions: new Array(), distances: new Array(), directions: new Array(), angles: new Array(), exponents: new Array() }
M
Mr.doob 已提交
165

166
	};
M
Mr.doob 已提交
167

168
	// initialize
M
Mikael Emtinger 已提交
169

170
	_gl = initGL();
M
Mikael Emtinger 已提交
171

172
	setDefaultGLState();
M
Mikael Emtinger 已提交
173

174
	this.context = _gl;
M
Mikael Emtinger 已提交
175

176 177 178
	// GPU capabilities

	var _maxVertexTextures = _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ),
A
alteredq 已提交
179
	_maxTextureSize = _gl.getParameter( _gl.MAX_TEXTURE_SIZE ),
180
	_maxCubemapSize = _gl.getParameter( _gl.MAX_CUBE_MAP_TEXTURE_SIZE );
M
Mr.doob 已提交
181

182
	// API
M
Mr.doob 已提交
183

184
	this.getContext = function () {
M
Mr.doob 已提交
185

186
		return _gl;
M
Mr.doob 已提交
187

188
	};
M
Mr.doob 已提交
189

190
	this.supportsVertexTextures = function () {
M
Mikael Emtinger 已提交
191

192
		return _maxVertexTextures > 0;
M
Mikael Emtinger 已提交
193

194
	};
M
Mikael Emtinger 已提交
195

N
Nicolas Garcia Belmonte 已提交
196 197 198 199
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
200

201 202 203
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
204

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

207 208
		_viewportX = x;
		_viewportY = y;
209

210 211
		_viewportWidth = width;
		_viewportHeight = height;
212

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

N
Nicolas Garcia Belmonte 已提交
215
	};
216

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

219
		_gl.scissor( x, y, width, height );
220

221
	};
222

223
	this.enableScissorTest = function ( enable ) {
224

M
Mr.doob 已提交
225
		enable ? _gl.enable( _gl.SCISSOR_TEST ) : _gl.disable( _gl.SCISSOR_TEST );
226 227

	};
228

229 230
	// Clearing

231
	this.setClearColorHex = function ( hex, alpha ) {
232

233 234 235 236
		_clearColor.setHex( hex );
		_clearAlpha = alpha;

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

238
	};
A
alteredq 已提交
239

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

242 243 244 245
		_clearColor.copy( color );
		_clearAlpha = alpha;

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

	};
248

M
Mr.doob 已提交
249 250 251 252 253 254 255
	this.getClearColor = function () {

		return _clearColor;

	};

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

M
Mr.doob 已提交
257 258 259 260 261 262 263 264
		return _clearAlpha;

	};

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

		var bits = 0;

265 266 267
		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 已提交
268 269

		_gl.clear( bits );
N
Nicolas Garcia Belmonte 已提交
270 271 272

	};

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

A
alteredq 已提交
275
		this.setRenderTarget( renderTarget );
276
		this.clear( color, depth, stencil );
M
Mr.doob 已提交
277 278 279

	};

280 281
	// Plugins

A
alteredq 已提交
282
	this.addPostPlugin = function ( plugin ) {
283 284

		plugin.init( this );
A
alteredq 已提交
285
		this.renderPluginsPost.push( plugin );
286 287 288

	};

A
alteredq 已提交
289 290 291 292 293 294
	this.addPrePlugin = function ( plugin ) {

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

	};
295

296 297
	// Deallocation

298 299 300 301 302 303 304
	this.deallocateObject = function ( object ) {

		if ( ! object.__webglInit ) return;

		object.__webglInit = false;

		delete object._modelViewMatrix;
305
		delete object._normalMatrix;
306 307 308 309 310 311 312

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

		if ( object instanceof THREE.Mesh ) {

313
			for ( var g in object.geometry.geometryGroups ) {
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341

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

344 345
	};

346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
	this.deallocateRenderTarget = function ( renderTarget ) {

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

		_gl.deleteTexture( renderTarget.__webglTexture );

		if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {

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

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

			}

		} else {

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

		}

	};

370
	// Rendering
371

372
	this.updateShadowMap = function ( scene, camera ) {
373

A
alteredq 已提交
374 375 376 377 378 379 380 381
		_currentProgram = null;
		_oldBlending = -1;
		_oldDepthTest = -1;
		_oldDepthWrite = -1;
		_currentGeometryGroupHash = -1;
		_currentMaterialId = -1;

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

383
	};
M
Mr.doob 已提交
384

385
	// Internal functions
386

387
	// Buffer allocation
388

389
	function createParticleBuffers ( geometry ) {
390

391 392
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
393

394
		_this.info.geometries ++;
395

396
	};
397

398
	function createLineBuffers ( geometry ) {
399

400 401
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
402

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

405
	};
406

407
	function createRibbonBuffers ( geometry ) {
408

409 410
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
411

412
		_this.info.memory.geometries ++;
M
Mr.doob 已提交
413

414
	};
415

416
	function createMeshBuffers ( geometryGroup ) {
417

418 419 420 421 422 423
		geometryGroup.__webglVertexBuffer = _gl.createBuffer();
		geometryGroup.__webglNormalBuffer = _gl.createBuffer();
		geometryGroup.__webglTangentBuffer = _gl.createBuffer();
		geometryGroup.__webglColorBuffer = _gl.createBuffer();
		geometryGroup.__webglUVBuffer = _gl.createBuffer();
		geometryGroup.__webglUV2Buffer = _gl.createBuffer();
424

425 426 427 428
		geometryGroup.__webglSkinVertexABuffer = _gl.createBuffer();
		geometryGroup.__webglSkinVertexBBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinIndicesBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinWeightsBuffer = _gl.createBuffer();
429

430 431
		geometryGroup.__webglFaceBuffer = _gl.createBuffer();
		geometryGroup.__webglLineBuffer = _gl.createBuffer();
432

433
		var m, ml;
434

435
		if ( geometryGroup.numMorphTargets ) {
436

437
			geometryGroup.__webglMorphTargetsBuffers = [];
438

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

441
				geometryGroup.__webglMorphTargetsBuffers.push( _gl.createBuffer() );
442 443 444 445 446 447 448 449 450 451 452

			}

		}

		if ( geometryGroup.numMorphNormals ) {

			geometryGroup.__webglMorphNormalsBuffers = [];

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

A
alteredq 已提交
453
				geometryGroup.__webglMorphNormalsBuffers.push( _gl.createBuffer() );
454

455
			}
456

457
		}
458

459
		_this.info.memory.geometries ++;
460

461
	};
462

463
	// Buffer deallocation
464

465
	function deleteParticleBuffers ( geometry ) {
466

467 468
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
469

470
		_this.info.memory.geometries --;
471

472
	};
473

474
	function deleteLineBuffers ( geometry ) {
475

476 477
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
478

M
Mr.doob 已提交
479 480
		_this.info.memory.geometries --;

481 482
	};

483
	function deleteRibbonBuffers ( geometry ) {
484 485 486 487

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

M
Mr.doob 已提交
488 489
		_this.info.memory.geometries --;

490 491
	};

492
	function deleteMeshBuffers ( geometryGroup ) {
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508

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

509 510
		var m, ml;

511 512
		if ( geometryGroup.numMorphTargets ) {

513
			for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
514 515

				_gl.deleteBuffer( geometryGroup.__webglMorphTargetsBuffers[ m ] );
516 517 518 519 520 521 522 523 524

			}

		}

		if ( geometryGroup.numMorphNormals ) {

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

A
alteredq 已提交
525
				_gl.deleteBuffer( geometryGroup.__webglMorphNormalsBuffers[ m ] );
526 527 528 529 530

			}

		}

531 532 533 534 535 536 537 538 539 540 541

		if ( geometryGroup.__webglCustomAttributesList ) {

			for ( var id in geometryGroup.__webglCustomAttributesList ) {

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

			}

		}

M
Mr.doob 已提交
542 543
		_this.info.memory.geometries --;

544 545
	};

546
	// Buffer initialization
547

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

550 551
		var nvertices = geometry.vertices.length;

552
		var material = object.material;
553

554
		if ( material.attributes ) {
555

556
			if ( geometry.__webglCustomAttributesList === undefined ) {
557

558
				geometry.__webglCustomAttributesList = [];
559

560
			}
561

562
			for ( var a in material.attributes ) {
563

564
				var attribute = material.attributes[ a ];
565

566
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
567

568
					attribute.__webglInitialized = true;
569

A
alteredq 已提交
570
					var size = 1;		// "f" and "i"
571

572 573 574 575
					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;
576

577
					attribute.size = size;
A
alteredq 已提交
578

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

581 582
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
583

584
					attribute.needsUpdate = true;
585

586
				}
587

588
				geometry.__webglCustomAttributesList.push( attribute );
589

590
			}
591

592
		}
593

594
	};
595

596
	function initParticleBuffers ( geometry, object ) {
A
alteredq 已提交
597 598 599 600 601 602

		var nvertices = geometry.vertices.length;

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

603 604 605
		geometry.__sortArray = [];

		geometry.__webglParticleCount = nvertices;
A
alteredq 已提交
606 607 608 609 610

		initCustomAttributes ( geometry, object );

	};

611
	function initLineBuffers ( geometry, object ) {
A
alteredq 已提交
612 613 614 615 616 617

		var nvertices = geometry.vertices.length;

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

618
		geometry.__webglLineCount = nvertices;
A
alteredq 已提交
619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634

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

637 638 639
		var geometry = object.geometry,
			faces3 = geometryGroup.faces3,
			faces4 = geometryGroup.faces4,
M
Mr.doob 已提交
640

641 642 643
			nvertices = faces3.length * 3 + faces4.length * 4,
			ntris     = faces3.length * 1 + faces4.length * 2,
			nlines    = faces3.length * 3 + faces4.length * 4,
644

645
			material = getBufferMaterial( object, geometryGroup ),
646

647 648 649
			uvType = bufferGuessUVType( material ),
			normalType = bufferGuessNormalType( material ),
			vertexColorType = bufferGuessVertexColorType( material );
A
alteredq 已提交
650

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

653
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
654

655
		if ( normalType ) {
M
Mr.doob 已提交
656

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

659
		}
660

661
		if ( geometry.hasTangents ) {
662

663
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
664

665
		}
666

667
		if ( vertexColorType ) {
668

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

671
		}
M
Mr.doob 已提交
672

673
		if ( uvType ) {
674

675
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
676

677 678 679 680 681
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

683 684 685 686 687 688 689 690 691 692 693 694 695 696 697
				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 );

		}

698
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
699
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
700

701 702
		var m, ml;

703 704
		if ( geometryGroup.numMorphTargets ) {

M
Mr.doob 已提交
705
			geometryGroup.__morphTargetsArrays = [];
706

707
			for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
708

709
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );
710 711 712 713 714 715 716 717 718 719 720

			}

		}

		if ( geometryGroup.numMorphNormals ) {

			geometryGroup.__morphNormalsArrays = [];

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

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

723 724 725
			}

		}
726

727
		geometryGroup.__webglFaceCount = ntris * 3;
728
		geometryGroup.__webglLineCount = nlines * 2;
729

M
Mr.doob 已提交
730

731
		// custom attributes
M
Mr.doob 已提交
732

733
		if ( material.attributes ) {
734

735
			if ( geometryGroup.__webglCustomAttributesList === undefined ) {
736

737
				geometryGroup.__webglCustomAttributesList = [];
738

739
			}
740

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

743 744
				// Do a shallow copy of the attribute object so different geometryGroup chunks use different
				// attribute buffers which are correctly indexed in the setMeshBuffers function
745

746
				var originalAttribute = material.attributes[ a ];
747

748
				var attribute = {};
749

750
				for ( var property in originalAttribute ) {
M
Mr.doob 已提交
751

752
					attribute[ property ] = originalAttribute[ property ];
753

754
				}
755

756
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
757

758
					attribute.__webglInitialized = true;
759

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

762 763 764 765
					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;
766

767
					attribute.size = size;
A
alteredq 已提交
768

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

771 772
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
773

774 775
					originalAttribute.needsUpdate = true;
					attribute.__original = originalAttribute;
776 777 778

				}

779 780
				geometryGroup.__webglCustomAttributesList.push( attribute );

781
			}
M
Mr.doob 已提交
782

783
		}
784

785 786
		geometryGroup.__inittedArrays = true;

787
	};
M
Mr.doob 已提交
788

789
	function getBufferMaterial( object, geometryGroup ) {
790

791
		if ( object.material && ! ( object.material instanceof THREE.MeshFaceMaterial ) ) {
792

793
			return object.material;
794

795
		} else if ( geometryGroup.materialIndex >= 0 ) {
796

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

799
		}
800

801
	};
M
Mr.doob 已提交
802

803
	function materialNeedsSmoothNormals ( material ) {
804

805
		return material && material.shading !== undefined && material.shading === THREE.SmoothShading;
806

807
	};
M
Mr.doob 已提交
808

809
	function bufferGuessNormalType ( material ) {
810

811
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
812

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

815
			return false;
816

817
		}
818

819
		if ( materialNeedsSmoothNormals( material ) ) {
820

821
			return THREE.SmoothShading;
M
Mr.doob 已提交
822

823
		} else {
824

825
			return THREE.FlatShading;
826

827
		}
828

829
	};
830

831
	function bufferGuessVertexColorType ( material ) {
832

833
		if ( material.vertexColors ) {
834

835
			return material.vertexColors;
836

837
		}
M
Mr.doob 已提交
838

839
		return false;
M
Mr.doob 已提交
840

841
	};
M
Mr.doob 已提交
842

843
	function bufferGuessUVType ( material ) {
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
		// 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,

874
		dirtyVertices = geometry.verticesNeedUpdate,
M
Mr.doob 已提交
875
		dirtyElements = geometry.elementsNeedUpdate,
M
Mr.doob 已提交
876
		dirtyColors = geometry.colorsNeedUpdate,
877 878 879 880 881 882 883 884

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

		if ( object.sortParticles ) {

A
alteredq 已提交
885 886
			_projScreenMatrixPS.copy( _projScreenMatrix );
			_projScreenMatrixPS.multiplySelf( object.matrixWorld );
887 888 889

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

890
				vertex = vertices[ v ];
891 892

				_vector3.copy( vertex );
A
alteredq 已提交
893
				_projScreenMatrixPS.multiplyVector3( _vector3 );
894 895 896 897 898 899 900 901 902

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

			}

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

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

903
				vertex = vertices[ sortArray[v][1] ];
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

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

1027
					vertex = vertices[ v ];
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

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

1193
		dirtyVertices = geometry.verticesNeedUpdate,
M
Mr.doob 已提交
1194
		dirtyColors = geometry.colorsNeedUpdate,
1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205

		customAttributes = geometry.__webglCustomAttributesList,

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

		if ( dirtyVertices ) {

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

1206
				vertex = vertices[ v ];
1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346

				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,

1347
		dirtyVertices = geometry.verticesNeedUpdate,
M
Mr.doob 已提交
1348
		dirtyColors = geometry.colorsNeedUpdate;
1349 1350 1351 1352 1353

		if ( dirtyVertices ) {

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

1354
				vertex = vertices[ v ];
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

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

		}

	};

1390
	function setMeshBuffers( geometryGroup, object, hint, dispose, material ) {
1391 1392 1393 1394 1395 1396 1397 1398

		if ( ! geometryGroup.__inittedArrays ) {

			// console.log( object );
			return;

		}

1399 1400 1401 1402 1403 1404
		var normalType = bufferGuessNormalType( material ),
		vertexColorType = bufferGuessVertexColorType( material ),
		uvType = bufferGuessUVType( material ),

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

1405 1406 1407 1408
		var f, fl, fi, face,
		vertexNormals, faceNormal, normal,
		vertexColors, faceColor,
		vertexTangents,
A
alteredq 已提交
1409
		uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4, n1, n2, n3, n4,
1410 1411 1412 1413 1414 1415 1416 1417
		c1, c2, c3, c4,
		sw1, sw2, sw3, sw4,
		si1, si2, si3, si4,
		sa1, sa2, sa3, sa4,
		sb1, sb2, sb3, sb4,
		m, ml, i, il,
		vn, uvi, uv2i,
		vk, vkl, vka,
A
alteredq 已提交
1418
		nka, chf, faceVertexNormals,
1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450
		a,

		vertexIndex = 0,

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

		value,

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

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

		morphTargetsArrays = geometryGroup.__morphTargetsArrays,
A
alteredq 已提交
1451
		morphNormalsArrays = geometryGroup.__morphNormalsArrays,
1452 1453 1454 1455 1456 1457 1458 1459 1460

		customAttributes = geometryGroup.__webglCustomAttributesList,
		customAttribute,

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

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

1461
		dirtyVertices = geometry.verticesNeedUpdate,
M
Mr.doob 已提交
1462
		dirtyElements = geometry.elementsNeedUpdate,
M
Mr.doob 已提交
1463
		dirtyUvs = geometry.uvsNeedUpdate,
M
Mr.doob 已提交
1464
		dirtyNormals = geometry.normalsNeedUpdate,
M
Mr.doob 已提交
1465
		dirtyTangents = geometry.tangetsNeedUpdate,
M
Mr.doob 已提交
1466
		dirtyColors = geometry.colorsNeedUpdate,
1467
		dirtyMorphTargets = geometry.morphTargetsNeedUpdate,
1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483

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

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

		obj_colors = geometry.colors,

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

A
alteredq 已提交
1484 1485
		morphTargets = geometry.morphTargets,
		morphNormals = geometry.morphNormals;
1486 1487 1488 1489 1490 1491 1492

		if ( dirtyVertices ) {

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

				face = obj_faces[ chunk_faces3[ f ] ];

1493 1494 1495
				v1 = vertices[ face.a ];
				v2 = vertices[ face.b ];
				v3 = vertices[ face.c ];
1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507

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

1509
				offset += 9;
M
Mr.doob 已提交
1510

1511
			}
1512

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

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

1517 1518 1519 1520
				v1 = vertices[ face.a ];
				v2 = vertices[ face.b ];
				v3 = vertices[ face.c ];
				v4 = vertices[ face.d ];
1521

A
alteredq 已提交
1522 1523 1524
				vertexArray[ offset ]     = v1.x;
				vertexArray[ offset + 1 ] = v1.y;
				vertexArray[ offset + 2 ] = v1.z;
1525

A
alteredq 已提交
1526 1527 1528
				vertexArray[ offset + 3 ] = v2.x;
				vertexArray[ offset + 4 ] = v2.y;
				vertexArray[ offset + 5 ] = v2.z;
1529

A
alteredq 已提交
1530 1531 1532
				vertexArray[ offset + 6 ] = v3.x;
				vertexArray[ offset + 7 ] = v3.y;
				vertexArray[ offset + 8 ] = v3.z;
1533

A
alteredq 已提交
1534 1535 1536
				vertexArray[ offset + 9 ]  = v4.x;
				vertexArray[ offset + 10 ] = v4.y;
				vertexArray[ offset + 11 ] = v4.z;
1537

A
alteredq 已提交
1538
				offset += 12;
1539

A
alteredq 已提交
1540
			}
1541

A
alteredq 已提交
1542 1543
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1544

A
alteredq 已提交
1545
		}
M
Mr.doob 已提交
1546

A
alteredq 已提交
1547
		if ( dirtyMorphTargets ) {
M
Mr.doob 已提交
1548

1549
			for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {
1550

1551
				offset_morphTarget = 0;
1552

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

A
alteredq 已提交
1555 1556 1557 1558
					chf = chunk_faces3[ f ];
					face = obj_faces[ chf ];

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

1560 1561 1562
					v1 = morphTargets[ vk ].vertices[ face.a ];
					v2 = morphTargets[ vk ].vertices[ face.b ];
					v3 = morphTargets[ vk ].vertices[ face.c ];
M
Mr.doob 已提交
1563

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

A
alteredq 已提交
1566 1567 1568
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
M
Mr.doob 已提交
1569

A
alteredq 已提交
1570 1571 1572
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
M
Mr.doob 已提交
1573

A
alteredq 已提交
1574 1575 1576
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
M
Mr.doob 已提交
1577

A
alteredq 已提交
1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615
					// morph normals

					if ( material.morphNormals ) {

						if ( needsSmoothNormals ) {

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

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

						} else {

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

						}

						nka = morphNormalsArrays[ vk ];

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

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

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

					}

					//

1616
					offset_morphTarget += 9;
1617

1618
				}
1619

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

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

					// morph positions
1626

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

1632
					vka = morphTargetsArrays[ vk ];
1633

1634 1635 1636
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
1637

1638 1639 1640
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
1641

1642 1643 1644
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
1645

A
alteredq 已提交
1646 1647 1648 1649
					vka[ offset_morphTarget + 9 ]  = v4.x;
					vka[ offset_morphTarget + 10 ] = v4.y;
					vka[ offset_morphTarget + 11 ] = v4.z;

A
alteredq 已提交
1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693
					// morph normals

					if ( material.morphNormals ) {

						if ( needsSmoothNormals ) {

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

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

						} else {

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

						}

						nka = morphNormalsArrays[ vk ];

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

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

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

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

					}

					//

1694
					offset_morphTarget += 12;
A
alteredq 已提交
1695

1696
				}
A
alteredq 已提交
1697 1698 1699

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

A
alteredq 已提交
1701 1702 1703 1704 1705 1706 1707
				if ( material.morphNormals ) {

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

				}

1708
			}
1709

A
alteredq 已提交
1710 1711 1712 1713 1714 1715 1716
		}

		if ( obj_skinWeights.length ) {

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

				face = obj_faces[ chunk_faces3[ f ]	];
1717

1718
				// weights
A
alteredq 已提交
1719

1720 1721 1722
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
A
alteredq 已提交
1723

1724 1725 1726 1727
				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 已提交
1728

1729 1730 1731 1732
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1733

1734 1735 1736 1737
				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 已提交
1738

1739
				// indices
A
alteredq 已提交
1740

1741 1742 1743
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
A
alteredq 已提交
1744

1745 1746 1747 1748
				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 已提交
1749

1750 1751 1752 1753
				skinIndexArray[ offset_skin + 4 ] = si2.x;
				skinIndexArray[ offset_skin + 5 ] = si2.y;
				skinIndexArray[ offset_skin + 6 ] = si2.z;
				skinIndexArray[ offset_skin + 7 ] = si2.w;
1754

1755 1756 1757 1758
				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 已提交
1759

1760
				// vertices A
A
alteredq 已提交
1761

1762 1763 1764
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
A
alteredq 已提交
1765

1766 1767 1768 1769
				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 已提交
1770

1771 1772 1773 1774
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1775

1776 1777 1778 1779
				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 已提交
1780

1781
				// vertices B
A
alteredq 已提交
1782

1783 1784 1785
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
A
alteredq 已提交
1786

1787 1788 1789 1790
				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 已提交
1791

1792 1793 1794 1795
				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
				skinVertexBArray[ offset_skin + 7 ] = 1;
1796

1797 1798 1799 1800
				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
				skinVertexBArray[ offset_skin + 11 ] = 1;
1801

1802
				offset_skin += 12;
1803

1804
			}
1805

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

A
alteredq 已提交
1808
				face = obj_faces[ chunk_faces4[ f ] ];
1809

A
alteredq 已提交
1810
				// weights
1811

A
alteredq 已提交
1812 1813 1814 1815
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
				sw4 = obj_skinWeights[ face.d ];
1816

A
alteredq 已提交
1817 1818 1819 1820
				skinWeightArray[ offset_skin ]     = sw1.x;
				skinWeightArray[ offset_skin + 1 ] = sw1.y;
				skinWeightArray[ offset_skin + 2 ] = sw1.z;
				skinWeightArray[ offset_skin + 3 ] = sw1.w;
1821

A
alteredq 已提交
1822 1823 1824 1825
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1826

A
alteredq 已提交
1827 1828 1829 1830
				skinWeightArray[ offset_skin + 8 ]  = sw3.x;
				skinWeightArray[ offset_skin + 9 ]  = sw3.y;
				skinWeightArray[ offset_skin + 10 ] = sw3.z;
				skinWeightArray[ offset_skin + 11 ] = sw3.w;
1831

A
alteredq 已提交
1832 1833 1834 1835
				skinWeightArray[ offset_skin + 12 ] = sw4.x;
				skinWeightArray[ offset_skin + 13 ] = sw4.y;
				skinWeightArray[ offset_skin + 14 ] = sw4.z;
				skinWeightArray[ offset_skin + 15 ] = sw4.w;
1836

A
alteredq 已提交
1837
				// indices
1838

A
alteredq 已提交
1839 1840 1841 1842
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
				si4 = obj_skinIndices[ face.d ];
1843

A
alteredq 已提交
1844 1845 1846 1847
				skinIndexArray[ offset_skin ]     = si1.x;
				skinIndexArray[ offset_skin + 1 ] = si1.y;
				skinIndexArray[ offset_skin + 2 ] = si1.z;
				skinIndexArray[ offset_skin + 3 ] = si1.w;
1848

A
alteredq 已提交
1849 1850 1851 1852
				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 已提交
1853

A
alteredq 已提交
1854 1855 1856 1857
				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 已提交
1858

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

A
alteredq 已提交
1864
				// vertices A
M
Mr.doob 已提交
1865

A
alteredq 已提交
1866 1867 1868 1869
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
				sa4 = obj_skinVerticesA[ face.d ];
1870

A
alteredq 已提交
1871 1872 1873 1874
				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 已提交
1875

A
alteredq 已提交
1876 1877 1878 1879
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1880

A
alteredq 已提交
1881 1882 1883 1884
				skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
				skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
				skinVertexAArray[ offset_skin + 10 ] = sa3.z;
				skinVertexAArray[ offset_skin + 11 ] = 1;
1885

A
alteredq 已提交
1886 1887 1888 1889
				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 已提交
1890

A
alteredq 已提交
1891
				// vertices B
M
Mr.doob 已提交
1892

A
alteredq 已提交
1893 1894 1895 1896
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
				sb4 = obj_skinVerticesB[ face.d ];
M
Mr.doob 已提交
1897

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

A
alteredq 已提交
1903 1904 1905 1906
				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
				skinVertexBArray[ offset_skin + 7 ] = 1;
1907

A
alteredq 已提交
1908 1909 1910 1911
				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
				skinVertexBArray[ offset_skin + 11 ] = 1;
1912

A
alteredq 已提交
1913 1914 1915 1916
				skinVertexBArray[ offset_skin + 12 ] = sb4.x;
				skinVertexBArray[ offset_skin + 13 ] = sb4.y;
				skinVertexBArray[ offset_skin + 14 ] = sb4.z;
				skinVertexBArray[ offset_skin + 15 ] = 1;
1917

A
alteredq 已提交
1918
				offset_skin += 16;
M
Mr.doob 已提交
1919

A
alteredq 已提交
1920
			}
M
Mr.doob 已提交
1921

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

A
alteredq 已提交
1924 1925
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );
M
Mr.doob 已提交
1926

A
alteredq 已提交
1927 1928 1929 1930 1931 1932 1933 1934
				_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 );
1935

1936
			}
1937

A
alteredq 已提交
1938
		}
M
Mr.doob 已提交
1939

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

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

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

A
alteredq 已提交
1946 1947
				vertexColors = face.vertexColors;
				faceColor = face.color;
1948

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

A
alteredq 已提交
1951 1952 1953
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
1954

A
alteredq 已提交
1955
				} else {
1956

A
alteredq 已提交
1957 1958 1959
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
1960

A
alteredq 已提交
1961
				}
1962

A
alteredq 已提交
1963 1964 1965
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
1966

A
alteredq 已提交
1967 1968 1969
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
1970

A
alteredq 已提交
1971 1972 1973
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
1974

A
alteredq 已提交
1975
				offset_color += 9;
M
Mr.doob 已提交
1976

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

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

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

A
alteredq 已提交
1983 1984
				vertexColors = face.vertexColors;
				faceColor = face.color;
M
Mr.doob 已提交
1985

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

A
alteredq 已提交
1988 1989 1990 1991
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
					c4 = vertexColors[ 3 ];
1992

A
alteredq 已提交
1993
				} else {
M
Mr.doob 已提交
1994

A
alteredq 已提交
1995 1996 1997 1998
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
					c4 = faceColor;
M
Mr.doob 已提交
1999

A
alteredq 已提交
2000
				}
2001

A
alteredq 已提交
2002 2003 2004
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
2005

A
alteredq 已提交
2006 2007 2008
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
M
Mr.doob 已提交
2009

A
alteredq 已提交
2010 2011 2012
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
M
Mr.doob 已提交
2013

A
alteredq 已提交
2014 2015 2016
				colorArray[ offset_color + 9 ]  = c4.r;
				colorArray[ offset_color + 10 ] = c4.g;
				colorArray[ offset_color + 11 ] = c4.b;
M
Mr.doob 已提交
2017

A
alteredq 已提交
2018
				offset_color += 12;
2019

2020
			}
2021

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

A
alteredq 已提交
2024 2025
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
M
Mr.doob 已提交
2026

2027
			}
2028

A
alteredq 已提交
2029
		}
M
Mr.doob 已提交
2030

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

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

A
alteredq 已提交
2035
				face = obj_faces[ chunk_faces3[ f ]	];
2036

A
alteredq 已提交
2037
				vertexTangents = face.vertexTangents;
M
Mr.doob 已提交
2038

A
alteredq 已提交
2039 2040 2041
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
2042

A
alteredq 已提交
2043 2044 2045 2046
				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 已提交
2047

A
alteredq 已提交
2048 2049 2050 2051
				tangentArray[ offset_tangent + 4 ] = t2.x;
				tangentArray[ offset_tangent + 5 ] = t2.y;
				tangentArray[ offset_tangent + 6 ] = t2.z;
				tangentArray[ offset_tangent + 7 ] = t2.w;
2052

A
alteredq 已提交
2053 2054 2055 2056
				tangentArray[ offset_tangent + 8 ]  = t3.x;
				tangentArray[ offset_tangent + 9 ]  = t3.y;
				tangentArray[ offset_tangent + 10 ] = t3.z;
				tangentArray[ offset_tangent + 11 ] = t3.w;
2057

A
alteredq 已提交
2058
				offset_tangent += 12;
2059

2060
			}
2061

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

A
alteredq 已提交
2064
				face = obj_faces[ chunk_faces4[ f ] ];
2065

A
alteredq 已提交
2066
				vertexTangents = face.vertexTangents;
2067

A
alteredq 已提交
2068 2069 2070 2071
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
				t4 = vertexTangents[ 3 ];
2072

A
alteredq 已提交
2073 2074 2075 2076
				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 已提交
2077

A
alteredq 已提交
2078 2079 2080 2081
				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 已提交
2082

A
alteredq 已提交
2083 2084 2085 2086
				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 已提交
2087

A
alteredq 已提交
2088 2089 2090 2091
				tangentArray[ offset_tangent + 12 ] = t4.x;
				tangentArray[ offset_tangent + 13 ] = t4.y;
				tangentArray[ offset_tangent + 14 ] = t4.z;
				tangentArray[ offset_tangent + 15 ] = t4.w;
2092

A
alteredq 已提交
2093
				offset_tangent += 16;
2094

A
alteredq 已提交
2095
			}
2096

A
alteredq 已提交
2097 2098
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
2099

A
alteredq 已提交
2100
		}
2101

A
alteredq 已提交
2102
		if ( dirtyNormals && normalType ) {
2103

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

A
alteredq 已提交
2106
				face = obj_faces[ chunk_faces3[ f ]	];
2107

A
alteredq 已提交
2108 2109
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
2110

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

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

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

A
alteredq 已提交
2117 2118 2119
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
2120

A
alteredq 已提交
2121
						offset_normal += 3;
2122

A
alteredq 已提交
2123
					}
2124

A
alteredq 已提交
2125
				} else {
M
Mr.doob 已提交
2126

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

A
alteredq 已提交
2129 2130 2131
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
2132

A
alteredq 已提交
2133
						offset_normal += 3;
M
Mr.doob 已提交
2134

A
alteredq 已提交
2135
					}
2136

A
alteredq 已提交
2137
				}
2138

A
alteredq 已提交
2139
			}
2140

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

A
alteredq 已提交
2143
				face = obj_faces[ chunk_faces4[ f ] ];
2144

A
alteredq 已提交
2145 2146
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
2147

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

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

A
alteredq 已提交
2152
						vn = vertexNormals[ i ];
2153

A
alteredq 已提交
2154 2155 2156
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
2157

A
alteredq 已提交
2158
						offset_normal += 3;
2159

A
alteredq 已提交
2160
					}
M
Mr.doob 已提交
2161

A
alteredq 已提交
2162
				} else {
2163

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

A
alteredq 已提交
2166 2167 2168
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
2169

A
alteredq 已提交
2170
						offset_normal += 3;
M
Mr.doob 已提交
2171

A
alteredq 已提交
2172
					}
2173

A
alteredq 已提交
2174
				}
2175

A
alteredq 已提交
2176
			}
M
Mr.doob 已提交
2177

A
alteredq 已提交
2178 2179
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
2180

A
alteredq 已提交
2181
		}
M
Mr.doob 已提交
2182

A
alteredq 已提交
2183
		if ( dirtyUvs && obj_uvs && uvType ) {
2184

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

A
alteredq 已提交
2187
				fi = chunk_faces3[ f ];
2188

A
alteredq 已提交
2189 2190
				face = obj_faces[ fi ];
				uv = obj_uvs[ fi ];
2191

A
alteredq 已提交
2192
				if ( uv === undefined ) continue;
2193

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

A
alteredq 已提交
2196
					uvi = uv[ i ];
2197

A
alteredq 已提交
2198 2199
					uvArray[ offset_uv ]     = uvi.u;
					uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
2200

A
alteredq 已提交
2201
					offset_uv += 2;
M
Mr.doob 已提交
2202

A
alteredq 已提交
2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223
				}

			}

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

2225 2226
				}

2227
			}
2228

A
alteredq 已提交
2229
			if ( offset_uv > 0 ) {
2230

A
alteredq 已提交
2231 2232
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
2233

A
alteredq 已提交
2234
			}
2235

A
alteredq 已提交
2236
		}
2237

A
alteredq 已提交
2238
		if ( dirtyUvs && obj_uvs2 && uvType ) {
2239

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

A
alteredq 已提交
2242
				fi = chunk_faces3[ f ];
2243

A
alteredq 已提交
2244 2245
				face = obj_faces[ fi ];
				uv2 = obj_uvs2[ fi ];
2246

A
alteredq 已提交
2247 2248 2249 2250 2251 2252 2253 2254 2255 2256
				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;
2257

2258 2259
				}

A
alteredq 已提交
2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280
			}

			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;

				}
2281

2282
			}
2283

A
alteredq 已提交
2284
			if ( offset_uv2 > 0 ) {
2285

A
alteredq 已提交
2286 2287
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );
2288

A
alteredq 已提交
2289
			}
2290

A
alteredq 已提交
2291
		}
2292

A
alteredq 已提交
2293
		if ( dirtyElements ) {
2294

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

A
alteredq 已提交
2297
				face = obj_faces[ chunk_faces3[ f ]	];
2298

A
alteredq 已提交
2299 2300 2301
				faceArray[ offset_face ] 	 = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 2;
2302

A
alteredq 已提交
2303
				offset_face += 3;
2304

A
alteredq 已提交
2305 2306
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2307

A
alteredq 已提交
2308 2309
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 2;
2310

A
alteredq 已提交
2311 2312
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
2313

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

A
alteredq 已提交
2316
				vertexIndex += 3;
2317

A
alteredq 已提交
2318
			}
2319

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

A
alteredq 已提交
2322
				face = obj_faces[ chunk_faces4[ f ] ];
2323

A
alteredq 已提交
2324 2325 2326
				faceArray[ offset_face ]     = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 3;
2327

A
alteredq 已提交
2328 2329 2330
				faceArray[ offset_face + 3 ] = vertexIndex + 1;
				faceArray[ offset_face + 4 ] = vertexIndex + 2;
				faceArray[ offset_face + 5 ] = vertexIndex + 3;
2331

A
alteredq 已提交
2332
				offset_face += 6;
2333

A
alteredq 已提交
2334 2335
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2336

A
alteredq 已提交
2337 2338
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 3;
2339

A
alteredq 已提交
2340 2341
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
2342

A
alteredq 已提交
2343 2344
				lineArray[ offset_line + 6 ] = vertexIndex + 2;
				lineArray[ offset_line + 7 ] = vertexIndex + 3;
2345

A
alteredq 已提交
2346
				offset_line += 8;
2347

A
alteredq 已提交
2348
				vertexIndex += 4;
2349

2350
			}
2351

A
alteredq 已提交
2352 2353
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
2354

A
alteredq 已提交
2355 2356
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
2357

A
alteredq 已提交
2358
		}
2359

A
alteredq 已提交
2360
		if ( customAttributes ) {
2361

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

2364
				customAttribute = customAttributes[ i ];
2365

2366
				if ( ! customAttribute.__original.needsUpdate ) continue;
2367

2368 2369
				offset_custom = 0;
				offset_customSrc = 0;
2370

2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403
				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 ++ ) {

2404
							value = customAttribute.value[ chunk_faces3[ f ] ];
2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415

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

2416
							value = customAttribute.value[ chunk_faces4[ f ] ];
2417 2418 2419 2420 2421 2422 2423 2424 2425

							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;

						}
2426

2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445
					}

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

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

2450
							offset_custom += 6;
A
alteredq 已提交
2451

2452
						}
A
alteredq 已提交
2453

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

2456
							face = obj_faces[ chunk_faces4[ f ] ];
A
alteredq 已提交
2457

2458 2459 2460 2461
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
A
alteredq 已提交
2462

2463 2464
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2465

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

2469 2470
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2471

2472 2473
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
A
alteredq 已提交
2474

2475
							offset_custom += 8;
A
alteredq 已提交
2476

2477
						}
A
alteredq 已提交
2478

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

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

2483
							value = customAttribute.value[ chunk_faces3[ f ] ];
A
alteredq 已提交
2484

2485 2486 2487
							v1 = value;
							v2 = value;
							v3 = value;
A
alteredq 已提交
2488

2489 2490
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2491

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

2495 2496
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2497

2498
							offset_custom += 6;
A
alteredq 已提交
2499

2500
						}
A
alteredq 已提交
2501

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

2504
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2505

2506 2507 2508 2509
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2510

2511 2512
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2513

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

2517 2518
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2519

2520 2521
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
2522

2523
							offset_custom += 8;
M
Mr.doob 已提交
2524

2525
						}
M
Mr.doob 已提交
2526

M
Mr.doob 已提交
2527
					}
M
Mr.doob 已提交
2528

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

2531
					var pp;
2532

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

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

2537
					} else {
M
Mr.doob 已提交
2538

2539
						pp = [ "x", "y", "z" ];
2540

2541
					}
2542

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

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

2547
							face = obj_faces[ chunk_faces3[ f ]	];
2548

2549 2550 2551
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
2552

2553 2554 2555
							customAttribute.array[ offset_custom ] 	   = v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
2556

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

2561 2562 2563
							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 已提交
2564

2565
							offset_custom += 9;
M
Mr.doob 已提交
2566

2567
						}
M
Mr.doob 已提交
2568

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

2571
							face = obj_faces[ chunk_faces4[ f ] ];
M
Mr.doob 已提交
2572

2573 2574 2575 2576
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
M
Mr.doob 已提交
2577

2578 2579 2580
							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 已提交
2581

2582 2583 2584
							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 已提交
2585

2586 2587 2588
							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 已提交
2589

2590 2591 2592
							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 已提交
2593

2594
							offset_custom += 12;
M
Mr.doob 已提交
2595

2596
						}
M
Mr.doob 已提交
2597

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

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

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

2604 2605 2606
							v1 = value;
							v2 = value;
							v3 = value;
M
Mr.doob 已提交
2607

2608 2609 2610
							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 已提交
2611

2612 2613 2614
							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 已提交
2615

2616 2617 2618
							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 已提交
2619

2620
							offset_custom += 9;
M
Mr.doob 已提交
2621

2622
						}
2623

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

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

2628 2629 2630 2631
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
2632

2633 2634 2635
							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
2636

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

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

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

2649
							offset_custom += 12;
2650

2651
						}
2652

A
alteredq 已提交
2653
					}
M
Mr.doob 已提交
2654

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

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

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

2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722
							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 ++ ) {

2723
							value = customAttribute.value[ chunk_faces3[ f ] ];
2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740

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

2744
							offset_custom += 12;
A
alteredq 已提交
2745

2746 2747
						}

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

2750
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2751

2752 2753 2754 2755
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2756

2757 2758 2759 2760
							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;
2761

2762 2763 2764 2765
							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;
2766

2767 2768 2769 2770
							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;
2771

2772 2773 2774 2775
							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;
2776

2777
							offset_custom += 16;
A
alteredq 已提交
2778

2779
						}
A
alteredq 已提交
2780 2781 2782 2783 2784

					}

				}

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

A
alteredq 已提交
2788 2789 2790 2791
			}

		}

2792
		if ( dispose ) {
2793

2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806
			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 已提交
2807

2808
		}
A
alteredq 已提交
2809

2810
	};
A
alteredq 已提交
2811

2812
	// Buffer rendering
A
alteredq 已提交
2813

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

2816 2817
		if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
A
alteredq 已提交
2818

2819
		if ( object.hasPos ) {
A
alteredq 已提交
2820

2821 2822 2823 2824
			_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 已提交
2825 2826 2827

		}

2828
		if ( object.hasNormal ) {
A
alteredq 已提交
2829

2830
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
A
alteredq 已提交
2831

2832
			if ( shading === THREE.FlatShading ) {
2833

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

2839
				for( i = 0; i < il; i += 9 ) {
2840

2841
					normalArray = object.normalArray;
2842

2843 2844 2845
					nax  = normalArray[ i ];
					nay  = normalArray[ i + 1 ];
					naz  = normalArray[ i + 2 ];
2846

2847 2848 2849
					nbx  = normalArray[ i + 3 ];
					nby  = normalArray[ i + 4 ];
					nbz  = normalArray[ i + 5 ];
2850

2851 2852 2853
					ncx  = normalArray[ i + 6 ];
					ncy  = normalArray[ i + 7 ];
					ncz  = normalArray[ i + 8 ];
2854

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

2859 2860 2861
					normalArray[ i ] 	 = nx;
					normalArray[ i + 1 ] = ny;
					normalArray[ i + 2 ] = nz;
2862

2863 2864 2865
					normalArray[ i + 3 ] = nx;
					normalArray[ i + 4 ] = ny;
					normalArray[ i + 5 ] = nz;
2866

2867 2868 2869
					normalArray[ i + 6 ] = nx;
					normalArray[ i + 7 ] = ny;
					normalArray[ i + 8 ] = nz;
2870

2871
				}
2872

2873
			}
2874

2875 2876 2877
			_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 );
2878

2879
		}
2880

2881
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );
2882

2883
		object.count = 0;
2884

2885
	};
2886

2887 2888
	this.renderBufferDirect = function ( camera, lights, fog, material, geometryGroup, object ) {

2889
		var program, attributes, linewidth, primitives, a, attribute;
2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911

		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;

2912
			for ( var i = 0, il = offsets.length; i < il; ++ i ) {
2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976

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

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

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

2983
		attributes = program.attributes;
2984

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

2989
		if ( geometryGroupHash !== _currentGeometryGroupHash ) {
A
alteredq 已提交
2990

2991 2992
			_currentGeometryGroupHash = geometryGroupHash;
			updateBuffers = true;
2993

2994
		}
2995

2996
		// vertices
2997

2998
		if ( !material.morphTargets && attributes.position >= 0 ) {
2999

3000
			if ( updateBuffers ) {
3001

3002 3003
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
				_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3004

3005
			}
3006

3007
		} else {
3008

3009
			if ( object.morphTargetBase ) {
3010

3011
				setupMorphTargets( material, geometryGroup, object );
3012

3013
			}
3014

3015
		}
3016

3017

3018
		if ( updateBuffers ) {
3019

3020
			// custom attributes
3021

3022
			// Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
3023

3024
			if ( geometryGroup.__webglCustomAttributesList ) {
3025

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

3028
					attribute = geometryGroup.__webglCustomAttributesList[ i ];
3029

3030
					if( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
3031

3032 3033
						_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
						_gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 );
3034

3035
					}
3036

3037
				}
3038

3039
			}
3040 3041


3042
			// colors
3043

3044
			if ( attributes.color >= 0 ) {
3045

3046 3047
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
3048

3049
			}
3050

3051
			// normals
3052

3053
			if ( attributes.normal >= 0 ) {
3054

3055 3056
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
				_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
3057

3058
			}
3059

3060
			// tangents
3061

3062
			if ( attributes.tangent >= 0 ) {
3063

3064 3065
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
				_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
3066

3067
			}
3068

3069
			// uvs
3070

3071
			if ( attributes.uv >= 0 ) {
3072

3073
				if ( geometryGroup.__webglUVBuffer ) {
3074

3075 3076
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
					_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
3077

3078
					_gl.enableVertexAttribArray( attributes.uv );
3079

3080
				} else {
3081

3082
					_gl.disableVertexAttribArray( attributes.uv );
3083 3084 3085 3086 3087

				}

			}

3088
			if ( attributes.uv2 >= 0 ) {
3089

3090
				if ( geometryGroup.__webglUV2Buffer ) {
3091

3092 3093
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
					_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
3094

3095
					_gl.enableVertexAttribArray( attributes.uv2 );
3096

3097
				} else {
3098

3099
					_gl.disableVertexAttribArray( attributes.uv2 );
3100 3101

				}
3102 3103

			}
3104

3105 3106 3107
			if ( material.skinning &&
				 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
				 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
A
alteredq 已提交
3108

3109 3110
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3111

3112 3113
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
				_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3114

3115 3116
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
				_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3117

3118 3119
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
				_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
3120

A
alteredq 已提交
3121
			}
3122

3123
		}
3124

3125
		// render mesh
3126

3127
		if ( object instanceof THREE.Mesh ) {
3128

3129
			// wireframe
3130

3131
			if ( material.wireframe ) {
3132

3133
				setLineWidth( material.wireframeLinewidth );
3134

3135 3136
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
3137

3138
			// triangles
3139

3140
			} else {
3141

3142 3143
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3144

3145
			}
3146

3147 3148 3149
			_this.info.render.calls ++;
			_this.info.render.vertices += geometryGroup.__webglFaceCount;
			_this.info.render.faces += geometryGroup.__webglFaceCount / 3;
3150

3151
		// render lines
3152

3153
		} else if ( object instanceof THREE.Line ) {
3154

3155
			primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
3156

3157
			setLineWidth( material.linewidth );
3158

3159
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
3160

3161
			_this.info.render.calls ++;
3162

3163
		// render particles
3164

3165
		} else if ( object instanceof THREE.ParticleSystem ) {
3166

3167
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
3168

3169
			_this.info.render.calls ++;
3170
			_this.info.render.points += geometryGroup.__webglParticleCount;
3171

3172
		// render ribbon
3173

3174
		} else if ( object instanceof THREE.Ribbon ) {
3175

3176
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
3177

3178
			_this.info.render.calls ++;
3179

3180
		}
3181

3182
	};
3183

3184
	function setupMorphTargets ( material, geometryGroup, object ) {
3185

3186
		// set base
3187

3188
		var attributes = material.program.attributes;
3189

3190
		if ( object.morphTargetBase !== - 1 ) {
3191

3192 3193
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3194

3195
		} else if ( attributes.position >= 0 ) {
3196

3197 3198
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3199

3200
		}
3201

3202
		if ( object.morphTargetForcedOrder.length ) {
3203

3204
			// set forced order
3205

3206 3207 3208 3209 3210
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;

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

3212 3213 3214
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ order[ m ] ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );

A
alteredq 已提交
3215 3216 3217 3218 3219 3220 3221
				if ( material.morphNormals ) {

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

				}

3222 3223 3224
				object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ] ];

				m ++;
3225 3226
			}

3227 3228 3229 3230 3231 3232 3233 3234 3235 3236
		} else {

			// find most influencing

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

3238
			if ( object.morphTargetBase !== - 1 ) {
3239

3240
				used[ object.morphTargetBase ] = true;
3241

3242
			}
3243

3244
			while ( m < material.numSupportedMorphTargets ) {
3245

3246
				for ( i = 0; i < il; i ++ ) {
3247

3248
					if ( !used[ i ] && influences[ i ] > candidateInfluence ) {
3249

3250 3251
						candidate = i;
						candidateInfluence = influences[ candidate ];
3252

3253
					}
3254

3255
				}
3256

3257 3258
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
3259

A
alteredq 已提交
3260 3261 3262 3263 3264 3265 3266
				if ( material.morphNormals ) {

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

				}

3267
				object.__webglMorphTargetInfluences[ m ] = candidateInfluence;
3268

3269 3270 3271
				used[ candidate ] = 1;
				candidateInfluence = -1;
				m ++;
3272 3273 3274 3275 3276

			}

		}

3277
		// load updated influences uniform
3278

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

3281
			_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
3282

3283
		}
3284

3285
	};
3286 3287


3288
	function painterSort ( a, b ) {
3289

3290
		return b.z - a.z;
3291

3292
	};
3293

3294
	// Rendering
3295

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

3298 3299 3300 3301 3302
		var i, il,

		webglObject, object,
		renderList,

3303
		lights = scene.__lights,
3304
		fog = scene.fog;
M
Mr.doob 已提交
3305

3306
		_currentMaterialId = -1;
3307

A
alteredq 已提交
3308
		// update scene graph
3309

3310
		if ( camera.parent === undefined ) {
3311

3312 3313
			console.warn( 'DEPRECATED: Camera hasn\'t been added to a Scene. Adding it...' );
			scene.add( camera );
3314

3315
		}
3316

3317
		if ( this.autoUpdateScene ) scene.updateMatrixWorld();
3318

A
alteredq 已提交
3319
		// update camera matrices and frustum
A
alteredq 已提交
3320

A
alteredq 已提交
3321 3322
		if ( ! camera._viewMatrixArray ) camera._viewMatrixArray = new Float32Array( 16 );
		if ( ! camera._projectionMatrixArray ) camera._projectionMatrixArray = new Float32Array( 16 );
A
alteredq 已提交
3323

3324
		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
A
alteredq 已提交
3325 3326 3327

		camera.matrixWorldInverse.flattenToArray( camera._viewMatrixArray );
		camera.projectionMatrix.flattenToArray( camera._projectionMatrixArray );
3328

3329
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
A
alteredq 已提交
3330
		_frustum.setFromMatrix( _projScreenMatrix );
3331

A
alteredq 已提交
3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346
		// update WebGL objects

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

		// custom render plugins (pre pass)

		renderPlugins( this.renderPluginsPre, scene, camera );

		//

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

A
alteredq 已提交
3347
		this.setRenderTarget( renderTarget );
3348

3349
		if ( this.autoClear || forceClear ) {
3350

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

3353
		}
M
Mr.doob 已提交
3354

3355
		// set matrices for regular objects (frustum culled)
3356

3357
		renderList = scene.__webglObjects;
3358

3359
		for ( i = 0, il = renderList.length; i < il; i ++ ) {
3360

3361
			webglObject = renderList[ i ];
3362
			object = webglObject.object;
3363

A
alteredq 已提交
3364 3365
			webglObject.render = false;

3366
			if ( object.visible ) {
3367

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

3370
					//object.matrixWorld.flattenToArray( object._objectMatrixArray );
3371

A
alteredq 已提交
3372
					setupMatrices( object, camera );
3373

3374
					unrollBufferMaterial( webglObject );
3375

3376
					webglObject.render = true;
3377

3378
					if ( this.sortObjects ) {
3379

3380
						if ( object.renderDepth ) {
3381

3382
							webglObject.z = object.renderDepth;
M
Mr.doob 已提交
3383

3384
						} else {
M
Mr.doob 已提交
3385

3386
							_vector3.copy( object.matrixWorld.getPosition() );
3387
							_projScreenMatrix.multiplyVector3( _vector3 );
3388

3389
							webglObject.z = _vector3.z;
3390

3391
						}
M
Mr.doob 已提交
3392

3393
					}
M
Mr.doob 已提交
3394

3395
				}
3396 3397

			}
3398 3399 3400

		}

3401
		if ( this.sortObjects ) {
M
Mr.doob 已提交
3402

3403
			renderList.sort( painterSort );
3404

3405
		}
3406

3407
		// set matrices for immediate objects
3408

3409
		renderList = scene.__webglObjectsImmediate;
3410

3411 3412 3413
		for ( i = 0, il = renderList.length; i < il; i ++ ) {

			webglObject = renderList[ i ];
3414
			object = webglObject.object;
3415

3416
			if ( object.visible ) {
3417

M
Mr.doob 已提交
3418 3419
				/*
				if ( object.matrixAutoUpdate ) {
3420

3421
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3422

3423
				}
M
Mr.doob 已提交
3424
				*/
M
Mr.doob 已提交
3425

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

3428
				unrollImmediateBufferMaterial( webglObject );
M
Mr.doob 已提交
3429

3430
			}
M
Mr.doob 已提交
3431

3432
		}
3433

3434
		if ( scene.overrideMaterial ) {
3435

3436 3437 3438 3439 3440 3441
			var material = scene.overrideMaterial;

			this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
			this.setDepthTest( material.depthTest );
			this.setDepthWrite( material.depthWrite );
			setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
3442

3443 3444
			renderObjects( scene.__webglObjects, false, "", camera, lights, fog, true, material );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "", camera, lights, fog, false, material );
M
Mr.doob 已提交
3445

3446
		} else {
3447

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

3450
			this.setBlending( THREE.NormalBlending );
3451

3452 3453
			renderObjects( scene.__webglObjects, true, "opaque", camera, lights, fog, false );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "opaque", camera, lights, fog, false );
3454

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

3457 3458
			renderObjects( scene.__webglObjects, false, "transparent", camera, lights, fog, true );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "transparent", camera, lights, fog, true );
3459

3460
		}
3461

A
alteredq 已提交
3462
		// custom render plugins (post pass)
3463

A
alteredq 已提交
3464
		renderPlugins( this.renderPluginsPost, scene, camera );
3465 3466


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

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

3471
			updateRenderTargetMipmap( renderTarget );
3472

3473
		}
3474

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

		this.setDepthTest( true );
3478
		this.setDepthWrite( true );
3479

3480
		// _gl.finish();
3481

3482
	};
3483

A
alteredq 已提交
3484 3485 3486 3487 3488 3489 3490
	function renderPlugins( plugins, scene, camera ) {

		if ( ! plugins.length ) return;

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

			_currentProgram = null;
3491
			_currentCamera = null;
A
alteredq 已提交
3492 3493 3494 3495 3496 3497
			_oldBlending = -1;
			_oldDepthTest = -1;
			_oldDepthWrite = -1;
			_currentGeometryGroupHash = -1;
			_currentMaterialId = -1;

A
alteredq 已提交
3498
			plugins[ i ].render( scene, camera, _currentWidth, _currentHeight );
A
alteredq 已提交
3499 3500

			_currentProgram = null;
3501
			_currentCamera = null;
A
alteredq 已提交
3502 3503 3504 3505 3506 3507 3508 3509 3510 3511
			_oldBlending = -1;
			_oldDepthTest = -1;
			_oldDepthWrite = -1;
			_currentGeometryGroupHash = -1;
			_currentMaterialId = -1;

		}

	};

3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547
	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;

3548
					if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
3549

A
alteredq 已提交
3550
					_this.setDepthTest( material.depthTest );
3551
					_this.setDepthWrite( material.depthWrite );
3552 3553 3554 3555
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

A
alteredq 已提交
3556
				_this.setObjectFaces( object );
3557 3558 3559 3560 3561 3562 3563 3564 3565 3566

				if ( buffer instanceof THREE.BufferGeometry ) {

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

				} else {

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

				}
3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594

			}

		}

	};

	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;

3595
					if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
3596

A
alteredq 已提交
3597
					_this.setDepthTest( material.depthTest );
3598
					_this.setDepthWrite( material.depthWrite );
3599 3600 3601 3602
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

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

A
alteredq 已提交
3605
			}
3606

A
alteredq 已提交
3607
		}
3608

A
alteredq 已提交
3609
	};
3610

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

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

A
alteredq 已提交
3615
		_currentGeometryGroupHash = -1;
3616

A
alteredq 已提交
3617 3618 3619 3620 3621 3622 3623 3624 3625
		_this.setObjectFaces( object );

		if ( object.immediateRenderCallback ) {

			object.immediateRenderCallback( program, _gl, _frustum );

		} else {

			object.render( function( object ) { _this.renderBufferImmediate( object, program, material.shading ); } );
3626 3627 3628 3629 3630

		}

	};

3631
	function unrollImmediateBufferMaterial ( globject ) {
3632

3633 3634
		var object = globject.object,
			material = object.material;
3635

3636
		if ( material.transparent ) {
3637

3638 3639
			globject.transparent = material;
			globject.opaque = null;
3640

3641
		} else {
3642

3643 3644
			globject.opaque = material;
			globject.transparent = null;
3645

3646
		}
A
alteredq 已提交
3647

3648
	};
A
alteredq 已提交
3649

3650
	function unrollBufferMaterial ( globject ) {
A
alteredq 已提交
3651

3652 3653 3654
		var object = globject.object,
			buffer = globject.buffer,
			material, materialIndex, meshMaterial;
3655

3656
		meshMaterial = object.material;
3657

3658
		if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
M
Mr.doob 已提交
3659

3660
			materialIndex = buffer.materialIndex;
3661

3662
			if ( materialIndex >= 0 ) {
3663

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

3666
				if ( material.transparent ) {
M
Mr.doob 已提交
3667

3668 3669
					globject.transparent = material;
					globject.opaque = null;
3670

3671
				} else {
3672

3673 3674
					globject.opaque = material;
					globject.transparent = null;
3675

3676
				}
3677

3678
			}
3679

3680
		} else {
3681

3682
			material = meshMaterial;
3683

3684
			if ( material ) {
3685

3686
				if ( material.transparent ) {
M
Mr.doob 已提交
3687

3688 3689
					globject.transparent = material;
					globject.opaque = null;
A
alteredq 已提交
3690

3691
				} else {
3692

3693 3694
					globject.opaque = material;
					globject.transparent = null;
3695

3696
				}
3697

3698
			}
3699

3700
		}
3701

3702
	};
3703

3704
	// Geometry splitting
3705

3706
	function sortFacesByMaterial ( geometry ) {
3707

3708 3709 3710
		var f, fl, face, materialIndex, vertices,
			materialHash, groupHash,
			hash_map = {};
3711

3712
		var numMorphTargets = geometry.morphTargets.length;
3713
		var numMorphNormals = geometry.morphNormals.length;
3714

3715
		geometry.geometryGroups = {};
3716

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

3719 3720
			face = geometry.faces[ f ];
			materialIndex = face.materialIndex;
3721

3722
			materialHash = ( materialIndex !== undefined ) ? materialIndex : -1;
3723

3724
			if ( hash_map[ materialHash ] === undefined ) {
3725

3726
				hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 };
3727 3728 3729

			}

3730
			groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
3731

3732
			if ( geometry.geometryGroups[ groupHash ] === undefined ) {
3733

3734
				geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets, 'numMorphNormals': numMorphNormals };
3735

3736
			}
A
alteredq 已提交
3737

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

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

3742 3743
				hash_map[ materialHash ].counter += 1;
				groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
A
alteredq 已提交
3744

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

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

3749
				}
3750

3751
			}
3752

3753
			if ( face instanceof THREE.Face3 ) {
3754

3755
				geometry.geometryGroups[ groupHash ].faces3.push( f );
3756

3757
			} else {
3758

3759
				geometry.geometryGroups[ groupHash ].faces4.push( f );
3760

A
alteredq 已提交
3761
			}
3762

3763
			geometry.geometryGroups[ groupHash ].vertices += vertices;
3764

3765
		}
3766

3767
		geometry.geometryGroupsList = [];
3768

3769
		for ( var g in geometry.geometryGroups ) {
3770

3771
			geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;
3772

3773
			geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );
3774

3775
		}
3776

3777
	};
3778

3779 3780 3781 3782 3783 3784 3785 3786 3787
	// Objects refresh

	this.initWebGLObjects = function ( scene ) {

		if ( !scene.__webglObjects ) {

			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
			scene.__webglSprites = [];
3788
			scene.__webglFlares = [];
3789 3790

		}
3791

3792
		while ( scene.__objectsAdded.length ) {
3793

3794 3795
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
3796

3797
		}
A
alteredq 已提交
3798

3799
		while ( scene.__objectsRemoved.length ) {
3800

3801 3802
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
3803

3804
		}
3805

3806
		// update must be called after objects adding / removal
3807

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

3810
			updateObject( scene.__webglObjects[ o ].object );
M
Mr.doob 已提交
3811 3812 3813 3814 3815

		}

	};

3816
	// Objects adding
M
Mr.doob 已提交
3817

3818
	function addObject ( object, scene ) {
A
alteredq 已提交
3819

3820
		var g, geometry, geometryGroup;
3821

3822
		if ( ! object.__webglInit ) {
M
Mr.doob 已提交
3823

3824
			object.__webglInit = true;
M
Mr.doob 已提交
3825

3826
			object._modelViewMatrix = new THREE.Matrix4();
3827
			object._normalMatrix = new THREE.Matrix3();
M
Mr.doob 已提交
3828

3829 3830 3831
			//object._normalMatrixArray = new Float32Array( 9 );
			//object._modelViewMatrixArray = new Float32Array( 16 );
			//object._objectMatrixArray = new Float32Array( 16 );
M
Mr.doob 已提交
3832

3833
			//object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3834

3835
			if ( object instanceof THREE.Mesh ) {
M
Mr.doob 已提交
3836

3837
				geometry = object.geometry;
M
Mr.doob 已提交
3838

3839
				if ( geometry instanceof THREE.Geometry ) {
M
Mr.doob 已提交
3840

3841
					if ( geometry.geometryGroups === undefined ) {
M
Mr.doob 已提交
3842

3843
						sortFacesByMaterial( geometry );
M
Mr.doob 已提交
3844

3845 3846 3847
					}

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

3849
					for ( g in geometry.geometryGroups ) {
M
Mr.doob 已提交
3850

3851
						geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
3852

3853
						// initialise VBO on the first access
M
Mr.doob 已提交
3854

3855
						if ( ! geometryGroup.__webglVertexBuffer ) {
3856

3857 3858
							createMeshBuffers( geometryGroup );
							initMeshBuffers( geometryGroup, object );
M
Mr.doob 已提交
3859

3860
							geometry.verticesNeedUpdate = true;
3861
							geometry.morphTargetsNeedUpdate = true;
M
Mr.doob 已提交
3862
							geometry.elementsNeedUpdate = true;
M
Mr.doob 已提交
3863
							geometry.uvsNeedUpdate = true;
M
Mr.doob 已提交
3864
							geometry.normalsNeedUpdate = true;
M
Mr.doob 已提交
3865
							geometry.tangetsNeedUpdate = true;
M
Mr.doob 已提交
3866
							geometry.colorsNeedUpdate = true;
3867 3868

						}
M
Mr.doob 已提交
3869

3870
					}
M
Mr.doob 已提交
3871

3872
				}
M
Mr.doob 已提交
3873

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

3876
				geometry = object.geometry;
M
Mr.doob 已提交
3877

3878
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
3879

3880 3881
					createRibbonBuffers( geometry );
					initRibbonBuffers( geometry );
M
Mr.doob 已提交
3882

3883
					geometry.verticesNeedUpdate = true;
M
Mr.doob 已提交
3884
					geometry.colorsNeedUpdate = true;
M
Mr.doob 已提交
3885

3886
				}
M
Mr.doob 已提交
3887

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

3890
				geometry = object.geometry;
M
Mr.doob 已提交
3891

3892
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
3893

3894 3895
					createLineBuffers( geometry );
					initLineBuffers( geometry, object );
M
Mr.doob 已提交
3896

3897
					geometry.verticesNeedUpdate = true;
M
Mr.doob 已提交
3898
					geometry.colorsNeedUpdate = true;
3899

3900
				}
3901

3902
			} else if ( object instanceof THREE.ParticleSystem ) {
3903

3904
				geometry = object.geometry;
3905

3906
				if ( ! geometry.__webglVertexBuffer ) {
3907

3908 3909
					createParticleBuffers( geometry );
					initParticleBuffers( geometry, object );
3910

3911
					geometry.verticesNeedUpdate = true;
M
Mr.doob 已提交
3912
					geometry.colorsNeedUpdate = true;
3913

3914
				}
3915

3916
			}
3917

3918
		}
3919

3920
		if ( ! object.__webglActive ) {
3921

3922
			if ( object instanceof THREE.Mesh ) {
3923

3924
				geometry = object.geometry;
3925

3926 3927 3928 3929 3930 3931 3932 3933 3934
				if ( geometry instanceof THREE.BufferGeometry ) {

					addBuffer( scene.__webglObjects, geometry, object );

				} else {

					for ( g in geometry.geometryGroups ) {

						geometryGroup = geometry.geometryGroups[ g ];
3935

3936
						addBuffer( scene.__webglObjects, geometryGroup, object );
3937

3938
					}
3939

3940
				}
3941

3942 3943 3944
			} else if ( object instanceof THREE.Ribbon ||
						object instanceof THREE.Line ||
						object instanceof THREE.ParticleSystem ) {
3945

3946 3947
				geometry = object.geometry;
				addBuffer( scene.__webglObjects, geometry, object );
3948

3949
			} else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
3950

3951
				addBufferImmediate( scene.__webglObjectsImmediate, object );
3952

3953
			} else if ( object instanceof THREE.Sprite ) {
3954

3955
				scene.__webglSprites.push( object );
3956

3957 3958 3959 3960
			} else if ( object instanceof THREE.LensFlare ) {

				scene.__webglFlares.push( object );

3961 3962
			}

3963
			object.__webglActive = true;
3964

3965
		}
3966

3967
	};
3968

3969
	function addBuffer ( objlist, buffer, object ) {
3970

3971 3972 3973 3974 3975 3976 3977 3978
		objlist.push(
			{
				buffer: buffer,
				object: object,
				opaque: null,
				transparent: null
			}
		);
3979

3980
	};
3981

3982
	function addBufferImmediate ( objlist, object ) {
3983

3984 3985 3986 3987 3988
		objlist.push(
			{
				object: object,
				opaque: null,
				transparent: null
3989
			}
3990
		);
3991

3992
	};
3993

3994
	// Objects updates
3995

3996
	function updateObject ( object ) {
3997

3998 3999
		var geometry = object.geometry,
			geometryGroup, customAttributesDirty, material;
4000

4001
		if ( object instanceof THREE.Mesh ) {
4002

4003 4004
			if ( geometry instanceof THREE.BufferGeometry ) {

4005
				/*
M
Mr.doob 已提交
4006
				if ( geometry.verticesNeedUpdate || geometry.elementsNeedUpdate ||
M
Mr.doob 已提交
4007
					 geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
M
Mr.doob 已提交
4008
					 geometry.colorsNeedUpdate  ) {
4009

4010 4011
					// TODO
					// set buffers from typed arrays
4012

4013
				}
4014
				*/
4015

4016
				geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4017
				geometry.elementsNeedUpdate = false;
M
Mr.doob 已提交
4018
				geometry.uvsNeedUpdate = false;
M
Mr.doob 已提交
4019
				geometry.normalsNeedUpdate = false;
M
Mr.doob 已提交
4020
				geometry.colorsNeedUpdate = false;
4021

4022
			} else {
4023

4024
				// check all geometry groups
4025

4026 4027 4028 4029 4030 4031 4032 4033
				for( var i = 0, il = geometry.geometryGroupsList.length; i < il; i ++ ) {

					geometryGroup = geometry.geometryGroupsList[ i ];

					material = getBufferMaterial( object, geometryGroup );

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

4034
					if ( geometry.verticesNeedUpdate || geometry.morphTargetsNeedUpdate || geometry.elementsNeedUpdate ||
M
Mr.doob 已提交
4035
						 geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
M
Mr.doob 已提交
4036
						 geometry.colorsNeedUpdate || geometry.tangetsNeedUpdate || customAttributesDirty ) {
4037 4038 4039 4040

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

					}
4041

4042
				}
M
Mr.doob 已提交
4043

4044
				geometry.verticesNeedUpdate = false;
4045
				geometry.morphTargetsNeedUpdate = false;
M
Mr.doob 已提交
4046
				geometry.elementsNeedUpdate = false;
M
Mr.doob 已提交
4047
				geometry.uvsNeedUpdate = false;
M
Mr.doob 已提交
4048
				geometry.normalsNeedUpdate = false;
M
Mr.doob 已提交
4049
				geometry.colorsNeedUpdate = false;
M
Mr.doob 已提交
4050
				geometry.tangetsNeedUpdate = false;
4051

4052
				material.attributes && clearCustomAttributes( material );
4053

4054
			}
4055

4056
		} else if ( object instanceof THREE.Ribbon ) {
4057

M
Mr.doob 已提交
4058
			if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate ) {
4059

4060
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
4061

4062
			}
4063

4064
			geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4065
			geometry.colorsNeedUpdate = false;
4066

4067
		} else if ( object instanceof THREE.Line ) {
4068

4069
			material = getBufferMaterial( object, geometryGroup );
A
alteredq 已提交
4070

4071
			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
A
alteredq 已提交
4072

M
Mr.doob 已提交
4073
			if ( geometry.verticesNeedUpdate ||  geometry.colorsNeedUpdate || customAttributesDirty ) {
A
alteredq 已提交
4074

4075
				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
4076

4077
			}
4078

4079
			geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4080
			geometry.colorsNeedUpdate = false;
4081

4082
			material.attributes && clearCustomAttributes( material );
4083

4084
		} else if ( object instanceof THREE.ParticleSystem ) {
4085

4086
			material = getBufferMaterial( object, geometryGroup );
4087

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

M
Mr.doob 已提交
4090
			if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || object.sortParticles || customAttributesDirty ) {
4091

4092
				setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
4093

4094
			}
4095

4096
			geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4097
			geometry.colorsNeedUpdate = false;
4098

4099
			material.attributes && clearCustomAttributes( material );
4100

4101
		}
4102

4103
	};
4104

4105
	// Objects updates - custom attributes check
4106

4107
	function areCustomAttributesDirty ( material ) {
4108

4109
		for ( var a in material.attributes ) {
4110

4111
			if ( material.attributes[ a ].needsUpdate ) return true;
4112

4113
		}
4114

4115
		return false;
4116

4117
	};
4118

4119 4120 4121
	function clearCustomAttributes ( material ) {

		for ( var a in material.attributes ) {
4122

4123
			material.attributes[ a ].needsUpdate = false;
4124

4125
		}
4126

4127
	};
4128

4129
	// Objects removal
4130

4131
	function removeObject ( object, scene ) {
4132

4133 4134 4135 4136
		if ( object instanceof THREE.Mesh  ||
			 object instanceof THREE.ParticleSystem ||
			 object instanceof THREE.Ribbon ||
			 object instanceof THREE.Line ) {
4137

4138
			removeInstances( scene.__webglObjects, object );
4139

4140
		} else if ( object instanceof THREE.Sprite ) {
4141

4142
			removeInstancesDirect( scene.__webglSprites, object );
4143

4144 4145 4146 4147
		} else if ( object instanceof THREE.LensFlare ) {

			removeInstancesDirect( scene.__webglFlares, object );

4148
		} else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
4149

4150
			removeInstances( scene.__webglObjectsImmediate, object );
4151

4152
		}
4153

4154
		object.__webglActive = false;
4155

4156
	};
4157

4158
	function removeInstances ( objlist, object ) {
4159

4160
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4161

4162
			if ( objlist[ o ].object === object ) {
4163

4164
				objlist.splice( o, 1 );
4165

4166
			}
4167

4168
		}
4169

4170
	};
4171

4172
	function removeInstancesDirect ( objlist, object ) {
4173

4174
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4175

4176
			if ( objlist[ o ] === object ) {
4177

4178
				objlist.splice( o, 1 );
4179

4180
			}
4181

4182
		}
4183

4184
	};
4185

4186
	// Materials
4187

4188
	this.initMaterial = function ( material, lights, fog, object ) {
4189

4190
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
4191

4192
		if ( material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
4193

4194
			shaderID = 'depth';
4195

4196
		} else if ( material instanceof THREE.MeshNormalMaterial ) {
4197

4198
			shaderID = 'normal';
M
Mr.doob 已提交
4199

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

4202
			shaderID = 'basic';
M
Mr.doob 已提交
4203

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

4206
			shaderID = 'lambert';
M
Mr.doob 已提交
4207

4208
		} else if ( material instanceof THREE.MeshPhongMaterial ) {
4209

4210
			shaderID = 'phong';
4211

4212
		} else if ( material instanceof THREE.LineBasicMaterial ) {
4213

4214
			shaderID = 'basic';
4215

4216
		} else if ( material instanceof THREE.ParticleBasicMaterial ) {
4217

4218
			shaderID = 'particle_basic';
4219 4220 4221

		}

4222
		if ( shaderID ) {
4223

4224
			setMaterialShaders( material, THREE.ShaderLib[ shaderID ] );
4225

4226
		}
4227

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

4231
		maxLightCount = allocateLights( lights );
4232

4233
		maxShadows = allocateShadows( lights );
4234

4235
		maxBones = allocateBones( object );
4236

4237
		parameters = {
4238

A
alteredq 已提交
4239 4240 4241 4242
			map: !!material.map,
			envMap: !!material.envMap,
			lightMap: !!material.lightMap,

4243
			vertexColors: material.vertexColors,
A
alteredq 已提交
4244 4245 4246 4247

			fog: fog,
			useFog: material.fog,

4248
			sizeAttenuation: material.sizeAttenuation,
A
alteredq 已提交
4249

4250
			skinning: material.skinning,
A
alteredq 已提交
4251 4252
			maxBones: maxBones,

4253
			morphTargets: material.morphTargets,
A
alteredq 已提交
4254
			morphNormals: material.morphNormals,
4255
			maxMorphTargets: this.maxMorphTargets,
A
alteredq 已提交
4256
			maxMorphNormals: this.maxMorphNormals,
A
alteredq 已提交
4257 4258 4259 4260 4261 4262

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

			maxShadows: maxShadows,
4263 4264
			shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
			shadowMapSoft: this.shadowMapSoft,
A
alteredq 已提交
4265 4266
			shadowMapDebug: this.shadowMapDebug,
			shadowMapCascade: this.shadowMapCascade,
A
alteredq 已提交
4267

4268 4269
			alphaTest: material.alphaTest,
			metal: material.metal,
4270
			perPixel: material.perPixel,
4271
			wrapAround: material.wrapAround,
4272
			doubleSided: object && object.doubleSided
4273

4274
		};
M
Mr.doob 已提交
4275

4276
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
4277

4278
		var attributes = material.program.attributes;
4279

4280 4281 4282 4283
		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 );
4284

4285 4286 4287
		if ( material.skinning &&
			 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
M
Mr.doob 已提交
4288

4289 4290 4291 4292
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
M
Mr.doob 已提交
4293 4294

		}
4295

4296
		if ( material.attributes ) {
A
alteredq 已提交
4297

4298
			for ( a in material.attributes ) {
M
Mr.doob 已提交
4299

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

4302
			}
M
Mr.doob 已提交
4303

4304
		}
M
Mr.doob 已提交
4305

4306
		if ( material.morphTargets ) {
M
Mr.doob 已提交
4307

4308
			material.numSupportedMorphTargets = 0;
4309

4310
			var id, base = "morphTarget";
4311

4312
			for ( i = 0; i < this.maxMorphTargets; i ++ ) {
4313

4314
				id = base + i;
M
Mr.doob 已提交
4315

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

4318 4319
					_gl.enableVertexAttribArray( attributes[ id ] );
					material.numSupportedMorphTargets ++;
4320

4321
				}
4322

4323
			}
4324

4325
		}
4326

A
alteredq 已提交
4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347
		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

			var id, base = "morphNormal";

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

				id = base + i;

				if ( attributes[ id ] >= 0 ) {

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

				}

			}

		}

4348
		material.uniformsList = [];
4349

4350
		for ( u in material.uniforms ) {
4351

4352
			material.uniformsList.push( [ material.uniforms[ u ], u ] );
4353

4354
		}
M
Mr.doob 已提交
4355

4356
	};
M
Mr.doob 已提交
4357

4358
	function setMaterialShaders( material, shaders ) {
M
Mr.doob 已提交
4359

4360 4361 4362
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
M
Mr.doob 已提交
4363

4364
	};
M
Mr.doob 已提交
4365

4366
	function setProgram( camera, lights, fog, material, object ) {
4367

A
alteredq 已提交
4368
		if ( ! material.program || material.needsUpdate ) {
4369

4370
			_this.initMaterial( material, lights, fog, object );
A
alteredq 已提交
4371
			material.needsUpdate = false;
4372

4373
		}
4374

4375
		if ( material.morphTargets ) {
4376

4377
			if ( ! object.__webglMorphTargetInfluences ) {
4378

4379
				object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );
4380

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

4383
					object.__webglMorphTargetInfluences[ i ] = 0;
4384

4385
				}
4386

4387
			}
4388

4389
		}
4390

4391
		var refreshMaterial = false;
4392

4393 4394 4395
		var program = material.program,
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
4396

4397
		if ( program !== _currentProgram ) {
4398

4399 4400
			_gl.useProgram( program );
			_currentProgram = program;
4401

4402
			refreshMaterial = true;
4403

4404
		}
4405

4406
		if ( material.id !== _currentMaterialId ) {
4407

4408 4409
			_currentMaterialId = material.id;
			refreshMaterial = true;
4410

4411
		}
4412

4413
		if ( refreshMaterial || camera !== _currentCamera ) {
4414

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

4417 4418 4419 4420 4421 4422
			if ( camera !== _currentCamera ) _currentCamera = camera;

		}

		if ( refreshMaterial ) {

4423
			// refresh uniforms common to several materials
4424

4425
			if ( fog && material.fog ) {
4426

4427
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
4428

4429
			}
M
Mr.doob 已提交
4430

4431 4432 4433
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material.lights ) {
4434

4435 4436
				setupLights( program, lights );
				refreshUniformsLights( m_uniforms, _lights );
4437

4438
			}
M
Mr.doob 已提交
4439

4440 4441 4442
			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
4443

4444
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
4445 4446 4447

			}

4448
			// refresh single material specific uniforms
M
Mr.doob 已提交
4449

4450
			if ( material instanceof THREE.LineBasicMaterial ) {
4451

4452
				refreshUniformsLine( m_uniforms, material );
M
Mr.doob 已提交
4453

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

4456
				refreshUniformsParticle( m_uniforms, material );
M
Mr.doob 已提交
4457

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

4460
				refreshUniformsPhong( m_uniforms, material );
M
Mr.doob 已提交
4461

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

4464
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
4465

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

4468 4469 4470
				m_uniforms.mNear.value = camera.near;
				m_uniforms.mFar.value = camera.far;
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4471

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

4474
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4475

4476
			}
M
Mr.doob 已提交
4477

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

4480
				refreshUniformsShadow( m_uniforms, lights );
M
Mr.doob 已提交
4481

4482
			}
M
Mr.doob 已提交
4483

4484
			// load common uniforms
M
Mr.doob 已提交
4485

4486
			loadUniformsGeneric( program, material.uniformsList );
M
Mr.doob 已提交
4487

4488 4489
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)
4490

4491 4492 4493
			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
				 material.envMap ) {
4494

4495
				if ( p_uniforms.cameraPosition !== null ) {
4496

4497 4498
					var position = camera.matrixWorld.getPosition();
					_gl.uniform3f( p_uniforms.cameraPosition, position.x, position.y, position.z );
4499

4500
				}
4501 4502 4503

			}

4504 4505 4506 4507
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {
4508

4509
				if ( p_uniforms.viewMatrix !== null ) {
4510

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

4513
				}
4514

4515
			}
M
Mr.doob 已提交
4516

4517
			if ( material.skinning ) {
4518

A
alteredq 已提交
4519
				_gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.boneMatrices );
4520

4521
			}
4522

4523
		}
M
Mr.doob 已提交
4524

4525
		loadUniformsMatrices( p_uniforms, object );
M
Mr.doob 已提交
4526

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

4529
			_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object.matrixWorld.elements );
4530

4531
		}
4532

4533
		return program;
4534

4535
	};
4536

4537
	// Uniforms (refresh uniforms objects)
A
alteredq 已提交
4538

4539
	function refreshUniformsCommon ( uniforms, material ) {
4540

4541
		uniforms.opacity.value = material.opacity;
4542

4543
		if ( _this.gammaInput ) {
4544

4545
			uniforms.diffuse.value.copyGammaToLinear( material.color );
4546

4547
		} else {
4548

4549
			uniforms.diffuse.value = material.color;
4550

4551
		}
4552

4553
		uniforms.map.texture = material.map;
4554

4555
		if ( material.map ) {
4556

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

4559
		}
M
Mr.doob 已提交
4560

4561
		uniforms.lightMap.texture = material.lightMap;
4562

4563 4564
		uniforms.envMap.texture = material.envMap;
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
4565

4566
		if ( _this.gammaInput ) {
4567

4568 4569
			//uniforms.reflectivity.value = material.reflectivity * material.reflectivity;
			uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
4570

4571
		} else {
4572

4573
			uniforms.reflectivity.value = material.reflectivity;
4574

4575
		}
4576

4577 4578 4579
		uniforms.refractionRatio.value = material.refractionRatio;
		uniforms.combine.value = material.combine;
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
M
Mr.doob 已提交
4580

4581
	};
M
Mr.doob 已提交
4582

4583
	function refreshUniformsLine ( uniforms, material ) {
M
Mr.doob 已提交
4584

4585 4586
		uniforms.diffuse.value = material.color;
		uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4587

4588
	};
M
Mr.doob 已提交
4589

4590
	function refreshUniformsParticle ( uniforms, material ) {
4591

4592 4593 4594 4595
		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.
4596

4597
		uniforms.map.texture = material.map;
4598

4599
	};
4600

4601
	function refreshUniformsFog ( uniforms, fog ) {
4602

4603
		uniforms.fogColor.value = fog.color;
4604

4605
		if ( fog instanceof THREE.Fog ) {
4606

4607 4608
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
4609

4610
		} else if ( fog instanceof THREE.FogExp2 ) {
M
Mikael Emtinger 已提交
4611

4612
			uniforms.fogDensity.value = fog.density;
M
Mikael Emtinger 已提交
4613

4614
		}
M
Mikael Emtinger 已提交
4615

4616
	};
M
Mikael Emtinger 已提交
4617

4618
	function refreshUniformsPhong ( uniforms, material ) {
M
Mikael Emtinger 已提交
4619

4620
		uniforms.shininess.value = material.shininess;
4621

4622
		if ( _this.gammaInput ) {
M
Mikael Emtinger 已提交
4623

4624
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
4625
			uniforms.emissive.value.copyGammaToLinear( material.emissive );
4626
			uniforms.specular.value.copyGammaToLinear( material.specular );
4627

4628
		} else {
4629

4630
			uniforms.ambient.value = material.ambient;
4631
			uniforms.emissive.value = material.emissive;
4632
			uniforms.specular.value = material.specular;
4633

4634
		}
4635

4636 4637 4638 4639 4640 4641
		if ( material.wrapAround ) {

			uniforms.wrapRGB.value.copy( material.wrapRGB );

		}

4642
	};
4643

4644
	function refreshUniformsLambert ( uniforms, material ) {
4645

4646
		if ( _this.gammaInput ) {
4647

4648
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
4649
			uniforms.emissive.value.copyGammaToLinear( material.emissive );
M
Mr.doob 已提交
4650

4651
		} else {
4652

4653
			uniforms.ambient.value = material.ambient;
4654
			uniforms.emissive.value = material.emissive;
4655

4656
		}
4657

4658 4659 4660 4661 4662 4663
		if ( material.wrapAround ) {

			uniforms.wrapRGB.value.copy( material.wrapRGB );

		}

4664
	};
4665

4666
	function refreshUniformsLights ( uniforms, lights ) {
4667

4668
		uniforms.ambientLightColor.value = lights.ambient;
4669

4670 4671
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
4672

4673 4674 4675
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
		uniforms.pointLightDistance.value = lights.point.distances;
4676

A
alteredq 已提交
4677 4678 4679 4680 4681 4682 4683
		uniforms.spotLightColor.value = lights.spot.colors;
		uniforms.spotLightPosition.value = lights.spot.positions;
		uniforms.spotLightDistance.value = lights.spot.distances;
		uniforms.spotLightDirection.value = lights.spot.directions;
		uniforms.spotLightAngle.value = lights.spot.angles;
		uniforms.spotLightExponent.value = lights.spot.exponents;

4684
	};
4685

4686
	function refreshUniformsShadow ( uniforms, lights ) {
M
Mr.doob 已提交
4687

4688
		if ( uniforms.shadowMatrix ) {
4689

4690
			var j = 0;
4691

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

4694
				var light = lights[ i ];
4695

A
alteredq 已提交
4696 4697
				if ( ! light.castShadow ) continue;

4698
				if ( light instanceof THREE.SpotLight || ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) ) {
4699 4700 4701

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

4703 4704 4705 4706 4707 4708 4709 4710 4711 4712
					uniforms.shadowMatrix.value[ j ] = light.shadowMatrix;

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

					j ++;

				}

			}
4713

4714 4715
		}

4716
	};
4717

4718
	// Uniforms (load to GPU)
4719

4720
	function loadUniformsMatrices ( uniforms, object ) {
4721

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

4724
		if ( uniforms.normalMatrix ) {
4725

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

4728
		}
4729

4730
	};
4731

4732
	function loadUniformsGeneric ( program, uniforms ) {
4733

4734
		var uniform, value, type, location, texture, i, il, j, jl, offset;
4735

M
Mr.doob 已提交
4736
		for ( j = 0, jl = uniforms.length; j < jl; j ++ ) {
4737

4738 4739
			location = program.uniforms[ uniforms[ j ][ 1 ] ];
			if ( !location ) continue;
4740

4741
			uniform = uniforms[ j ][ 0 ];
4742

4743 4744
			type = uniform.type;
			value = uniform.value;
4745

M
Mr.doob 已提交
4746
			switch ( type ) {
4747

M
Mr.doob 已提交
4748
				case "i": // single integer
4749

M
Mr.doob 已提交
4750
					_gl.uniform1i( location, value );
4751

M
Mr.doob 已提交
4752
					break;
4753

M
Mr.doob 已提交
4754
				case "f": // single float
4755

M
Mr.doob 已提交
4756
					_gl.uniform1f( location, value );
4757

M
Mr.doob 已提交
4758
					break;
4759

M
Mr.doob 已提交
4760
				case "v2": // single THREE.Vector2
4761

M
Mr.doob 已提交
4762
					_gl.uniform2f( location, value.x, value.y );
4763

M
Mr.doob 已提交
4764
					break;
4765

M
Mr.doob 已提交
4766
				case "v3": // single THREE.Vector3
4767

M
Mr.doob 已提交
4768
					_gl.uniform3f( location, value.x, value.y, value.z );
4769

M
Mr.doob 已提交
4770
					break;
4771

M
Mr.doob 已提交
4772
				case "v4": // single THREE.Vector4
4773

M
Mr.doob 已提交
4774
					_gl.uniform4f( location, value.x, value.y, value.z, value.w );
4775

M
Mr.doob 已提交
4776
					break;
4777

M
Mr.doob 已提交
4778
				case "c": // single THREE.Color
4779

M
Mr.doob 已提交
4780
					_gl.uniform3f( location, value.r, value.g, value.b );
4781

M
Mr.doob 已提交
4782
					break;
4783

M
Mr.doob 已提交
4784
				case "fv1": // flat array of floats (JS or typed array)
4785

M
Mr.doob 已提交
4786
					_gl.uniform1fv( location, value );
4787

M
Mr.doob 已提交
4788
					break;
4789

M
Mr.doob 已提交
4790
				case "fv": // flat array of floats with 3 x N size (JS or typed array)
4791

M
Mr.doob 已提交
4792
					_gl.uniform3fv( location, value );
4793

M
Mr.doob 已提交
4794
					break;
4795

M
Mr.doob 已提交
4796
				case "v2v": // array of THREE.Vector2
4797

M
Mr.doob 已提交
4798
					if ( ! uniform._array ) {
M
Mr.doob 已提交
4799

M
Mr.doob 已提交
4800
						uniform._array = new Float32Array( 2 * value.length );
A
alteredq 已提交
4801

M
Mr.doob 已提交
4802
					}
A
alteredq 已提交
4803

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

M
Mr.doob 已提交
4806
						offset = i * 2;
4807

M
Mr.doob 已提交
4808 4809
						uniform._array[ offset ] 	 = value[ i ].x;
						uniform._array[ offset + 1 ] = value[ i ].y;
4810

M
Mr.doob 已提交
4811
					}
4812

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

M
Mr.doob 已提交
4815
					break;
4816

M
Mr.doob 已提交
4817
				case "v3v": // array of THREE.Vector3
4818

M
Mr.doob 已提交
4819
					if ( ! uniform._array ) {
4820

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

M
Mr.doob 已提交
4823
					}
4824

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

M
Mr.doob 已提交
4827
						offset = i * 3;
4828

M
Mr.doob 已提交
4829 4830 4831
						uniform._array[ offset ] 	 = value[ i ].x;
						uniform._array[ offset + 1 ] = value[ i ].y;
						uniform._array[ offset + 2 ] = value[ i ].z;
4832

M
Mr.doob 已提交
4833
					}
M
Mr.doob 已提交
4834

M
Mr.doob 已提交
4835
					_gl.uniform3fv( location, uniform._array );
A
alteredq 已提交
4836

M
Mr.doob 已提交
4837
					break;
4838

M
Mr.doob 已提交
4839
				case "v4v": // array of THREE.Vector4
4840

M
Mr.doob 已提交
4841
					if ( ! uniform._array ) {
4842

M
Mr.doob 已提交
4843
						uniform._array = new Float32Array( 4 * value.length );
A
alteredq 已提交
4844

M
Mr.doob 已提交
4845
					}
4846

M
Mr.doob 已提交
4847
					for ( i = 0, il = value.length; i < il; i ++ ) {
A
alteredq 已提交
4848

M
Mr.doob 已提交
4849
						offset = i * 4;
M
Mr.doob 已提交
4850

M
Mr.doob 已提交
4851 4852 4853 4854
						uniform._array[ offset ] 	 = value[ i ].x;
						uniform._array[ offset + 1 ] = value[ i ].y;
						uniform._array[ offset + 2 ] = value[ i ].z;
						uniform._array[ offset + 3 ] = value[ i ].w;
M
Mr.doob 已提交
4855

M
Mr.doob 已提交
4856
					}
M
Mr.doob 已提交
4857

M
Mr.doob 已提交
4858
					_gl.uniform4fv( location, uniform._array );
A
alteredq 已提交
4859

M
Mr.doob 已提交
4860
					break;
M
Mr.doob 已提交
4861

M
Mr.doob 已提交
4862
				case "m4": // single THREE.Matrix4
M
Mr.doob 已提交
4863

M
Mr.doob 已提交
4864
					if ( ! uniform._array ) {
A
alteredq 已提交
4865

M
Mr.doob 已提交
4866
						uniform._array = new Float32Array( 16 );
4867

M
Mr.doob 已提交
4868
					}
A
alteredq 已提交
4869

M
Mr.doob 已提交
4870 4871
					value.flattenToArray( uniform._array );
					_gl.uniformMatrix4fv( location, false, uniform._array );
A
alteredq 已提交
4872

M
Mr.doob 已提交
4873
					break;
A
alteredq 已提交
4874

M
Mr.doob 已提交
4875
				case "m4v": // array of THREE.Matrix4
A
alteredq 已提交
4876

M
Mr.doob 已提交
4877
					if ( ! uniform._array ) {
M
Mr.doob 已提交
4878

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

M
Mr.doob 已提交
4881
					}
4882

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

M
Mr.doob 已提交
4885
						value[ i ].flattenToArrayOffset( uniform._array, i * 16 );
M
Mr.doob 已提交
4886

M
Mr.doob 已提交
4887
					}
M
Mr.doob 已提交
4888

M
Mr.doob 已提交
4889
					_gl.uniformMatrix4fv( location, false, uniform._array );
M
Mr.doob 已提交
4890

M
Mr.doob 已提交
4891
					break;
A
alteredq 已提交
4892

M
Mr.doob 已提交
4893 4894 4895 4896 4897
				case "t": // single THREE.Texture (2d or cube)

					_gl.uniform1i( location, value );

					texture = uniform.texture;
4898

M
Mr.doob 已提交
4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911
					if ( !texture ) continue;

					if ( texture.image instanceof Array && texture.image.length === 6 ) {

						setCubeTexture( texture, value );

					} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {

						setCubeTextureDynamic( texture, value );

					} else {

						_this.setTexture( texture, value );
4912 4913

					}
A
alteredq 已提交
4914

M
Mr.doob 已提交
4915
					break;
A
alteredq 已提交
4916

M
Mr.doob 已提交
4917
				case "tv": // array of THREE.Texture (2d)
A
alteredq 已提交
4918

M
Mr.doob 已提交
4919
					if ( ! uniform._array ) {
4920

M
Mr.doob 已提交
4921
						uniform._array = [];
4922

M
Mr.doob 已提交
4923
						for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
M
Mr.doob 已提交
4924

M
Mr.doob 已提交
4925
							uniform._array[ i ] = value + i;
M
Mr.doob 已提交
4926

M
Mr.doob 已提交
4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943
						}

					}

					_gl.uniform1iv( location, uniform._array );

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

						texture = uniform.texture[ i ];

						if ( !texture ) continue;

						_this.setTexture( texture, uniform._array[ i ] );

					}

					break;
M
Mr.doob 已提交
4944

M
Mr.doob 已提交
4945
			}
M
Mr.doob 已提交
4946

M
Mr.doob 已提交
4947
		}
M
Mr.doob 已提交
4948

4949
	};
M
Mr.doob 已提交
4950

A
alteredq 已提交
4951
	function setupMatrices ( object, camera ) {
M
Mr.doob 已提交
4952

4953
		object._modelViewMatrix.multiply( camera.matrixWorldInverse, object.matrixWorld);
M
Mr.doob 已提交
4954

4955
		object._normalMatrix.getInverse( object._modelViewMatrix );
4956
		object._normalMatrix.transpose();
M
Mr.doob 已提交
4957

A
alteredq 已提交
4958
	};
M
Mr.doob 已提交
4959

4960
	function setupLights ( program, lights ) {
M
Mr.doob 已提交
4961

4962 4963 4964
		var l, ll, light, n,
		r = 0, g = 0, b = 0,
		color, position, intensity, distance,
M
Mr.doob 已提交
4965

4966
		zlights = _lights,
A
alteredq 已提交
4967

4968 4969
		dcolors = zlights.directional.colors,
		dpositions = zlights.directional.positions,
A
alteredq 已提交
4970

4971 4972 4973
		pcolors = zlights.point.colors,
		ppositions = zlights.point.positions,
		pdistances = zlights.point.distances,
4974

A
alteredq 已提交
4975 4976 4977 4978 4979 4980 4981
		scolors = zlights.spot.colors,
		spositions = zlights.spot.positions,
		sdistances = zlights.spot.distances,
		sdirections = zlights.spot.directions,
		sangles = zlights.spot.angles,
		sexponents = zlights.spot.exponents,

4982 4983
		dlength = 0,
		plength = 0,
A
alteredq 已提交
4984
		slength = 0,
4985

4986
		doffset = 0,
A
alteredq 已提交
4987 4988
		poffset = 0,
		soffset = 0;
4989

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

4992
			light = lights[ l ];
A
alteredq 已提交
4993

A
alteredq 已提交
4994 4995 4996
			if ( light.onlyShadow ) continue;

			color = light.color;
4997 4998
			intensity = light.intensity;
			distance = light.distance;
A
alteredq 已提交
4999

5000
			if ( light instanceof THREE.AmbientLight ) {
5001

5002
				if ( _this.gammaInput ) {
5003

5004 5005 5006
					r += color.r * color.r;
					g += color.g * color.g;
					b += color.b * color.b;
5007

5008
				} else {
5009

5010 5011 5012
					r += color.r;
					g += color.g;
					b += color.b;
5013

5014
				}
5015

5016
			} else if ( light instanceof THREE.DirectionalLight ) {
5017

5018
				doffset = dlength * 3;
5019

5020
				if ( _this.gammaInput ) {
5021

5022 5023 5024
					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;
5025

5026
				} else {
5027

5028 5029 5030
					dcolors[ doffset ]     = color.r * intensity;
					dcolors[ doffset + 1 ] = color.g * intensity;
					dcolors[ doffset + 2 ] = color.b * intensity;
A
alteredq 已提交
5031

5032
				}
A
alteredq 已提交
5033

5034 5035 5036
				_direction.copy( light.matrixWorld.getPosition() );
				_direction.subSelf( light.target.matrixWorld.getPosition() );
				_direction.normalize();
A
alteredq 已提交
5037

5038 5039 5040
				dpositions[ doffset ]     = _direction.x;
				dpositions[ doffset + 1 ] = _direction.y;
				dpositions[ doffset + 2 ] = _direction.z;
A
alteredq 已提交
5041

5042
				dlength += 1;
A
alteredq 已提交
5043

A
alteredq 已提交
5044
			} else if( light instanceof THREE.PointLight ) {
M
Mr.doob 已提交
5045

5046
				poffset = plength * 3;
M
Mr.doob 已提交
5047

5048
				if ( _this.gammaInput ) {
5049

5050 5051 5052
					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 已提交
5053

5054
				} else {
A
alteredq 已提交
5055

5056 5057 5058
					pcolors[ poffset ]     = color.r * intensity;
					pcolors[ poffset + 1 ] = color.g * intensity;
					pcolors[ poffset + 2 ] = color.b * intensity;
A
alteredq 已提交
5059

5060
				}
A
alteredq 已提交
5061

A
alteredq 已提交
5062 5063
				position = light.matrixWorld.getPosition();

5064 5065 5066
				ppositions[ poffset ]     = position.x;
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
A
alteredq 已提交
5067

5068
				pdistances[ plength ] = distance;
A
alteredq 已提交
5069

5070
				plength += 1;
5071

A
alteredq 已提交
5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110
			} else if( light instanceof THREE.SpotLight ) {

				soffset = slength * 3;

				if ( _this.gammaInput ) {

					scolors[ soffset ]     = color.r * color.r * intensity * intensity;
					scolors[ soffset + 1 ] = color.g * color.g * intensity * intensity;
					scolors[ soffset + 2 ] = color.b * color.b * intensity * intensity;

				} else {

					scolors[ soffset ]     = color.r * intensity;
					scolors[ soffset + 1 ] = color.g * intensity;
					scolors[ soffset + 2 ] = color.b * intensity;

				}

				position = light.matrixWorld.getPosition();

				spositions[ soffset ]     = position.x;
				spositions[ soffset + 1 ] = position.y;
				spositions[ soffset + 2 ] = position.z;

				sdistances[ slength ] = distance;

				_direction.copy( position );
				_direction.subSelf( light.target.matrixWorld.getPosition() );
				_direction.normalize();

				sdirections[ soffset ]     = _direction.x;
				sdirections[ soffset + 1 ] = _direction.y;
				sdirections[ soffset + 2 ] = _direction.z;

				sangles[ slength ] = Math.cos( light.angle );
				sexponents[ slength ] = light.exponent;

				slength += 1;

5111
			}
5112

5113
		}
A
alteredq 已提交
5114

5115 5116
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
A
alteredq 已提交
5117

5118 5119
		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 已提交
5120
		for ( l = slength * 3, ll = scolors.length; l < ll; l ++ ) scolors[ l ] = 0.0;
A
alteredq 已提交
5121

5122
		zlights.directional.length = dlength;
A
alteredq 已提交
5123 5124
		zlights.point.length = plength;
		zlights.spot.length = slength;
A
alteredq 已提交
5125

5126 5127 5128
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
5129

5130
	};
M
Mr.doob 已提交
5131

5132
	// GL state setting
M
Mr.doob 已提交
5133

5134
	this.setFaceCulling = function ( cullFace, frontFace ) {
M
Mr.doob 已提交
5135

5136
		if ( cullFace ) {
M
Mr.doob 已提交
5137

5138
			if ( !frontFace || frontFace === "ccw" ) {
5139

5140
				_gl.frontFace( _gl.CCW );
5141

5142
			} else {
5143

5144
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
5145

5146
			}
M
Mr.doob 已提交
5147

5148
			if( cullFace === "back" ) {
5149

5150
				_gl.cullFace( _gl.BACK );
5151

5152
			} else if( cullFace === "front" ) {
5153

5154
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
5155

5156
			} else {
5157

5158
				_gl.cullFace( _gl.FRONT_AND_BACK );
5159

5160
			}
5161

5162
			_gl.enable( _gl.CULL_FACE );
5163

5164
		} else {
5165

5166
			_gl.disable( _gl.CULL_FACE );
5167 5168 5169 5170 5171

		}

	};

A
alteredq 已提交
5172
	this.setObjectFaces = function ( object ) {
5173

5174
		if ( _oldDoubleSided !== object.doubleSided ) {
M
Mr.doob 已提交
5175

M
Mr.doob 已提交
5176
			if ( object.doubleSided ) {
M
Mr.doob 已提交
5177

5178
				_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
5179

5180
			} else {
5181

5182
				_gl.enable( _gl.CULL_FACE );
5183

5184
			}
5185

5186
			_oldDoubleSided = object.doubleSided;
5187

5188
		}
5189

5190
		if ( _oldFlipSided !== object.flipSided ) {
5191

M
Mr.doob 已提交
5192
			if ( object.flipSided ) {
5193

5194
				_gl.frontFace( _gl.CW );
5195

5196
			} else {
5197

5198
				_gl.frontFace( _gl.CCW );
5199

5200
			}
5201

5202
			_oldFlipSided = object.flipSided;
5203

5204
		}
5205

5206
	};
5207

A
alteredq 已提交
5208
	this.setDepthTest = function ( depthTest ) {
5209

5210
		if ( _oldDepthTest !== depthTest ) {
5211

5212
			if ( depthTest ) {
5213

5214
				_gl.enable( _gl.DEPTH_TEST );
5215

5216
			} else {
5217

5218
				_gl.disable( _gl.DEPTH_TEST );
5219 5220 5221

			}

5222
			_oldDepthTest = depthTest;
5223

5224
		}
5225

5226
	};
5227

5228
	this.setDepthWrite = function ( depthWrite ) {
A
alteredq 已提交
5229

5230
		if ( _oldDepthWrite !== depthWrite ) {
A
alteredq 已提交
5231

5232 5233
			_gl.depthMask( depthWrite );
			_oldDepthWrite = depthWrite;
A
alteredq 已提交
5234 5235 5236 5237 5238

		}

	};

5239
	function setLineWidth ( width ) {
5240

5241
		if ( width !== _oldLineWidth ) {
5242

5243 5244 5245
			_gl.lineWidth( width );

			_oldLineWidth = width;
5246 5247 5248

		}

5249
	};
5250

5251
	function setPolygonOffset ( polygonoffset, factor, units ) {
5252

5253
		if ( _oldPolygonOffset !== polygonoffset ) {
M
Mr.doob 已提交
5254

5255
			if ( polygonoffset ) {
5256

5257
				_gl.enable( _gl.POLYGON_OFFSET_FILL );
5258

5259
			} else {
5260

5261
				_gl.disable( _gl.POLYGON_OFFSET_FILL );
5262

5263
			}
5264

5265
			_oldPolygonOffset = polygonoffset;
5266

5267
		}
5268

5269
		if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
5270

5271
			_gl.polygonOffset( factor, units );
M
Mr.doob 已提交
5272

5273 5274
			_oldPolygonOffsetFactor = factor;
			_oldPolygonOffsetUnits = units;
M
Mr.doob 已提交
5275

5276
		}
M
Mr.doob 已提交
5277

5278
	};
M
Mr.doob 已提交
5279

5280
	this.setBlending = function ( blending, blendEquation, blendSrc, blendDst ) {
M
Mr.doob 已提交
5281

5282
		if ( blending !== _oldBlending ) {
M
Mr.doob 已提交
5283

5284
			switch ( blending ) {
M
Mr.doob 已提交
5285

5286
				case THREE.NoBlending:
5287 5288 5289 5290

					_gl.disable( _gl.BLEND );

					break;
5291

5292
				case THREE.AdditiveBlending:
M
Mr.doob 已提交
5293

5294
					_gl.enable( _gl.BLEND );
5295 5296
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
M
Mr.doob 已提交
5297

5298
					break;
M
Mr.doob 已提交
5299

5300
				case THREE.SubtractiveBlending:
M
Mr.doob 已提交
5301

5302
					// TODO: Find blendFuncSeparate() combination
5303
					_gl.enable( _gl.BLEND );
5304 5305
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
M
Mr.doob 已提交
5306

5307
					break;
M
Mr.doob 已提交
5308

5309
				case THREE.MultiplyBlending:
M
Mr.doob 已提交
5310

5311
					// TODO: Find blendFuncSeparate() combination
5312
					_gl.enable( _gl.BLEND );
5313 5314
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
M
Mr.doob 已提交
5315

5316
					break;
5317

5318 5319 5320 5321 5322 5323
				case THREE.CustomBlending:

					_gl.enable( _gl.BLEND );

					break;

5324
				default:
N
Nicolas Garcia Belmonte 已提交
5325

5326
					_gl.enable( _gl.BLEND );
5327 5328
					_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 );
5329

5330
					break;
5331

5332
			}
5333

5334
			_oldBlending = blending;
5335

5336
		}
5337

5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364
		if ( blending === THREE.CustomBlending ) {

			if ( blendEquation !== _oldBlendEquation ) {

				_gl.blendEquation( paramThreeToGL( blendEquation ) );

				_oldBlendEquation = blendEquation;

			}

			if ( blendSrc !== _oldBlendSrc || blendDst !== _oldBlendDst ) {

				_gl.blendFunc( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ) );

				_oldBlendSrc = blendSrc;
				_oldBlendDst = blendDst;

			}

		} else {

			_oldBlendEquation = null;
			_oldBlendSrc = null;
			_oldBlendDst = null;

		}

5365
	};
5366

5367 5368 5369
	// Shaders

	function buildProgram ( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
5370

5371
		var p, pl, program, code;
5372
		var chunks = [];
5373 5374 5375

		// Generate code

5376 5377 5378 5379 5380 5381 5382 5383 5384 5385
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

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

		}
5386 5387 5388

		for ( p in parameters ) {

5389 5390
			chunks.push( p );
			chunks.push( parameters[ p ] );
5391 5392 5393

		}

5394 5395
		code = chunks.join();

5396 5397 5398 5399
		// Check if code has been already compiled

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

5400
			if ( _programs[ p ].code === code ) {
5401 5402

				// console.log( "Code already compiled." /*: \n\n" + code*/ );
5403

5404 5405 5406 5407 5408
				return _programs[ p ].program;

			}

		}
5409

5410
		//console.log( "building new program " );
5411 5412 5413

		//

5414
		program = _gl.createProgram();
M
Mr.doob 已提交
5415

5416
		var prefix_vertex = [
M
Mr.doob 已提交
5417

5418 5419
			"precision " + _precision + " float;",

5420
			( _maxVertexTextures > 0 ) ? "#define VERTEX_TEXTURES" : "",
5421

5422 5423 5424 5425
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

5426 5427
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
5428
			"#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
5429

5430 5431
			"#define MAX_SHADOWS " + parameters.maxShadows,

5432 5433
			"#define MAX_BONES " + parameters.maxBones,

5434
			parameters.map ? "#define USE_MAP" : "",
5435 5436 5437
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5438
			parameters.skinning ? "#define USE_SKINNING" : "",
5439
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
A
alteredq 已提交
5440
			parameters.morphNormals ? "#define USE_MORPHNORMALS" : "",
A
alteredq 已提交
5441
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
5442
			parameters.wrapAround ? "#define WRAP_AROUND" : "",
5443
			parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
5444

5445
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5446
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
A
alteredq 已提交
5447 5448
			parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
			parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
5449

5450 5451
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
5452 5453 5454
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
5455 5456
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
5457
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
5458

M
Mr.doob 已提交
5459 5460 5461
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
5462
			"attribute vec2 uv2;",
5463

5464
			"#ifdef USE_COLOR",
5465

5466
				"attribute vec3 color;",
5467

5468 5469
			"#endif",

5470
			"#ifdef USE_MORPHTARGETS",
5471

5472 5473 5474 5475
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
A
alteredq 已提交
5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491

				"#ifdef USE_MORPHNORMALS",

					"attribute vec3 morphNormal0;",
					"attribute vec3 morphNormal1;",
					"attribute vec3 morphNormal2;",
					"attribute vec3 morphNormal3;",

				"#else",

					"attribute vec3 morphTarget4;",
					"attribute vec3 morphTarget5;",
					"attribute vec3 morphTarget6;",
					"attribute vec3 morphTarget7;",

				"#endif",
5492

5493 5494 5495
			"#endif",

			"#ifdef USE_SKINNING",
5496

5497 5498 5499 5500
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
5501

5502
			"#endif",
5503

M
Mr.doob 已提交
5504
			""
A
alteredq 已提交
5505

M
Mr.doob 已提交
5506
		].join("\n");
5507

M
Mr.doob 已提交
5508 5509
		var prefix_fragment = [

5510
			"precision " + _precision + " float;",
M
Mr.doob 已提交
5511 5512 5513

			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
5514
			"#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
M
Mr.doob 已提交
5515

5516 5517
			"#define MAX_SHADOWS " + parameters.maxShadows,

5518 5519
			parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",

5520 5521 5522 5523
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

M
Mr.doob 已提交
5524 5525
			( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
			( parameters.useFog && parameters.fog instanceof THREE.FogExp2 ) ? "#define FOG_EXP2" : "",
M
Mr.doob 已提交
5526 5527 5528 5529 5530

			parameters.map ? "#define USE_MAP" : "",
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5531

5532 5533
			parameters.metal ? "#define METAL" : "",
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
5534
			parameters.wrapAround ? "#define WRAP_AROUND" : "",
5535
			parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
5536

5537
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5538
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
A
alteredq 已提交
5539 5540
			parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
			parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
M
Mr.doob 已提交
5541 5542 5543 5544 5545 5546 5547

			"uniform mat4 viewMatrix;",
			"uniform vec3 cameraPosition;",
			""

		].join("\n");

5548 5549
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
5550

M
Mr.doob 已提交
5551
		_gl.linkProgram( program );
N
Nicolas Garcia Belmonte 已提交
5552

M
Mr.doob 已提交
5553
		if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
N
Nicolas Garcia Belmonte 已提交
5554

5555
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
5556

N
Nicolas Garcia Belmonte 已提交
5557
		}
5558

5559 5560
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
5561

M
Mr.doob 已提交
5562
		program.uniforms = {};
5563
		program.attributes = {};
M
Mr.doob 已提交
5564

5565 5566 5567 5568
		var identifiers, u, a, i;

		// cache uniform locations

5569
		identifiers = [
5570

5571
			'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
A
alteredq 已提交
5572
			'boneGlobalMatrices', 'morphTargetInfluences'
M
Mr.doob 已提交
5573

5574
		];
M
Mr.doob 已提交
5575

5576
		for ( u in uniforms ) {
M
Mr.doob 已提交
5577

5578
			identifiers.push( u );
M
Mr.doob 已提交
5579

5580
		}
M
Mr.doob 已提交
5581

5582
		cacheUniformLocations( program, identifiers );
M
Mr.doob 已提交
5583

5584
		// cache attributes locations
M
Mr.doob 已提交
5585

5586
		identifiers = [
A
alteredq 已提交
5587

5588 5589
			"position", "normal", "uv", "uv2", "tangent", "color",
			"skinVertexA", "skinVertexB", "skinIndex", "skinWeight"
A
alteredq 已提交
5590

5591
		];
M
Mr.doob 已提交
5592

5593
		for ( i = 0; i < parameters.maxMorphTargets; i ++ ) {
M
Mr.doob 已提交
5594

5595
			identifiers.push( "morphTarget" + i );
M
Mr.doob 已提交
5596

5597
		}
5598

A
alteredq 已提交
5599 5600 5601 5602 5603 5604
		for ( i = 0; i < parameters.maxMorphNormals; i ++ ) {

			identifiers.push( "morphNormal" + i );

		}

5605
		for ( a in attributes ) {
5606

5607
			identifiers.push( a );
5608

5609
		}
5610

5611
		cacheAttributeLocations( program, identifiers );
5612

5613
		program.id = _programs.length;
5614

5615
		_programs.push( { program: program, code: code } );
5616

5617
		_this.info.memory.programs = _programs.length;
5618

5619
		return program;
5620

5621
	};
5622

5623
	// Shader parameters cache
5624

5625
	function cacheUniformLocations ( program, identifiers ) {
5626

5627
		var i, l, id;
5628

5629
		for( i = 0, l = identifiers.length; i < l; i ++ ) {
5630

5631 5632
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
5633

5634
		}
M
Mr.doob 已提交
5635

5636
	};
M
Mr.doob 已提交
5637

5638
	function cacheAttributeLocations ( program, identifiers ) {
A
alteredq 已提交
5639

5640
		var i, l, id;
A
alteredq 已提交
5641

5642
		for( i = 0, l = identifiers.length; i < l; i ++ ) {
A
alteredq 已提交
5643

5644 5645
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
A
alteredq 已提交
5646

5647
		}
5648

5649
	};
A
alteredq 已提交
5650

5651
	function getShader ( type, string ) {
A
alteredq 已提交
5652

5653
		var shader;
5654

5655
		if ( type === "fragment" ) {
A
alteredq 已提交
5656

5657
			shader = _gl.createShader( _gl.FRAGMENT_SHADER );
A
alteredq 已提交
5658

5659
		} else if ( type === "vertex" ) {
A
alteredq 已提交
5660

5661
			shader = _gl.createShader( _gl.VERTEX_SHADER );
A
alteredq 已提交
5662

5663
		}
A
alteredq 已提交
5664

5665 5666
		_gl.shaderSource( shader, string );
		_gl.compileShader( shader );
5667

5668
		if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {
5669

5670 5671 5672
			console.error( _gl.getShaderInfoLog( shader ) );
			console.error( string );
			return null;
5673

A
alteredq 已提交
5674 5675
		}

5676 5677
		return shader;

A
alteredq 已提交
5678
	};
5679

5680 5681
	// Textures

5682 5683 5684 5685 5686 5687 5688

	function isPowerOfTwo ( value ) {

		return ( value & ( value - 1 ) ) === 0;

	};

5689
	function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {
5690

5691
		if ( isImagePowerOfTwo ) {
M
Mr.doob 已提交
5692

5693 5694
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
5695

5696 5697
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
5698

5699
		} else {
M
Mr.doob 已提交
5700

5701 5702
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
5703

5704 5705
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
5706

5707
		}
M
Mr.doob 已提交
5708

5709
	};
5710

5711
	this.setTexture = function ( texture, slot ) {
5712

5713
		if ( texture.needsUpdate ) {
A
alteredq 已提交
5714

5715
			if ( ! texture.__webglInit ) {
M
Mr.doob 已提交
5716

5717
				texture.__webglInit = true;
5718
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5719

M
Mr.doob 已提交
5720 5721
				_this.info.memory.textures ++;

5722
			}
M
Mr.doob 已提交
5723

5724
			_gl.activeTexture( _gl.TEXTURE0 + slot );
5725 5726
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );

5727 5728
			_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );

5729 5730
			var image = texture.image,
			isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
5731 5732
			glFormat = paramThreeToGL( texture.format ),
			glType = paramThreeToGL( texture.type );
5733

5734 5735
			setTextureParameters( _gl.TEXTURE_2D, texture, isImagePowerOfTwo );

5736
			if ( texture instanceof THREE.DataTexture ) {
5737

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

A
alteredq 已提交
5740
			} else {
M
Mr.doob 已提交
5741

5742
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, texture.image );
M
Mr.doob 已提交
5743 5744 5745

			}

5746
			if ( texture.generateMipmaps && isImagePowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
M
Mr.doob 已提交
5747

A
alteredq 已提交
5748
			texture.needsUpdate = false;
5749

5750
			if ( texture.onUpdate ) texture.onUpdate();
5751

5752
		} else {
5753

5754 5755
			_gl.activeTexture( _gl.TEXTURE0 + slot );
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
5756 5757

		}
M
Mr.doob 已提交
5758

5759
	};
M
Mr.doob 已提交
5760

5761 5762 5763 5764 5765 5766 5767 5768 5769 5770
	function clampToMaxSize ( image, maxSize ) {

		if ( image.width <= maxSize && image.height <= maxSize ) {

			return image;

		}

		// Warning: Scaling through the canvas will only work with images that use
		// premultiplied alpha.
5771

5772 5773 5774 5775 5776 5777 5778
		var maxDimension = Math.max( image.width, image.height );
		var newWidth = Math.floor( image.width * maxSize / maxDimension );
		var newHeight = Math.floor( image.height * maxSize / maxDimension );

		var canvas = document.createElement( 'canvas' );
		canvas.width = newWidth;
		canvas.height = newHeight;
5779

5780
		var ctx = canvas.getContext( "2d" );
5781 5782
		ctx.drawImage( image, 0, 0, image.width, image.height, 0, 0, newWidth, newHeight );

5783 5784 5785 5786
		return canvas;

	}

5787
	function setCubeTexture ( texture, slot ) {
5788

5789
		if ( texture.image.length === 6 ) {
5790 5791 5792

			if ( texture.needsUpdate ) {

A
alteredq 已提交
5793
				if ( ! texture.image.__webglTextureCube ) {
5794 5795

					texture.image.__webglTextureCube = _gl.createTexture();
5796

A
alteredq 已提交
5797
				}
5798

A
alteredq 已提交
5799 5800
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5801

5802
				var cubeImage = [];
5803

A
alteredq 已提交
5804
				for ( var i = 0; i < 6; i ++ ) {
5805

5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817
					if ( _this.autoScaleCubemaps ) {

						cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize );

					} else {

						cubeImage[ i ] = texture.image[ i ];

					}

				}

5818 5819
				var image = cubeImage[ 0 ],
				isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
5820 5821
				glFormat = paramThreeToGL( texture.format ),
				glType = paramThreeToGL( texture.type );
5822

5823 5824
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo );

A
alteredq 已提交
5825
				for ( var i = 0; i < 6; i ++ ) {
5826

5827
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
5828

A
alteredq 已提交
5829
				}
5830

5831
				if ( texture.generateMipmaps && isImagePowerOfTwo )	_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
5832

A
alteredq 已提交
5833
				texture.needsUpdate = false;
5834

5835
				if ( texture.onUpdate ) texture.onUpdate();
5836

A
alteredq 已提交
5837
			} else {
5838

A
alteredq 已提交
5839 5840
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5841

A
alteredq 已提交
5842
			}
5843

A
alteredq 已提交
5844
		}
5845

A
alteredq 已提交
5846
	};
5847

5848
	function setCubeTextureDynamic ( texture, slot ) {
5849

A
alteredq 已提交
5850 5851
		_gl.activeTexture( _gl.TEXTURE0 + slot );
		_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
5852 5853 5854

	};

5855 5856 5857
	// Render targets

	function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
5858

5859 5860
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
A
alteredq 已提交
5861

5862
	};
M
Mr.doob 已提交
5863

5864
	function setupRenderBuffer ( renderbuffer, renderTarget  ) {
M
Mikael Emtinger 已提交
5865

5866
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
5867

5868
		if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
M
Mr.doob 已提交
5869

5870 5871
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5872

5873 5874
		/* For some reason this is not working. Defaulting to RGBA4.
		} else if( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
A
alteredq 已提交
5875

5876 5877 5878 5879
			_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 已提交
5880

5881 5882
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5883

5884
		} else {
A
alteredq 已提交
5885

5886
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
A
alteredq 已提交
5887

5888
		}
A
alteredq 已提交
5889

5890
	};
A
alteredq 已提交
5891

A
alteredq 已提交
5892
	this.setRenderTarget = function ( renderTarget ) {
A
alteredq 已提交
5893

5894
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
A
alteredq 已提交
5895

5896
		if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
A
alteredq 已提交
5897

5898 5899
			if( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
			if( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
A
alteredq 已提交
5900

5901
			renderTarget.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5902

5903
			// Setup texture, create render and frame buffers
5904

5905 5906
			var isTargetPowerOfTwo = isPowerOfTwo( renderTarget.width ) && isPowerOfTwo( renderTarget.height ),
				glFormat = paramThreeToGL( renderTarget.format ),
5907 5908
				glType = paramThreeToGL( renderTarget.type );

5909
			if ( isCube ) {
M
Mr.doob 已提交
5910

5911 5912
				renderTarget.__webglFramebuffer = [];
				renderTarget.__webglRenderbuffer = [];
M
Mikael Emtinger 已提交
5913

5914
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
5915
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, isTargetPowerOfTwo );
A
alteredq 已提交
5916

5917
				for ( var i = 0; i < 6; i ++ ) {
A
alteredq 已提交
5918

5919 5920
					renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
					renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
A
alteredq 已提交
5921

5922
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
A
alteredq 已提交
5923

5924 5925
					setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
					setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
A
alteredq 已提交
5926

5927
				}
5928

5929 5930
				if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

5931
			} else {
5932

5933 5934
				renderTarget.__webglFramebuffer = _gl.createFramebuffer();
				renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
5935

5936
				_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
5937
				setTextureParameters( _gl.TEXTURE_2D, renderTarget, isTargetPowerOfTwo );
5938

5939
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
5940

5941 5942
				setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
				setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
5943

5944 5945
				if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );

M
Mikael Emtinger 已提交
5946
			}
5947

5948
			// Release everything
M
Mr.doob 已提交
5949

A
alteredq 已提交
5950 5951 5952 5953 5954 5955 5956 5957 5958 5959
			if ( isCube ) {

				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

			} else {

				_gl.bindTexture( _gl.TEXTURE_2D, null );

			}

5960 5961
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
5962

5963 5964
		}

5965
		var framebuffer, width, height, vx, vy;
M
Mr.doob 已提交
5966

5967
		if ( renderTarget ) {
M
Mr.doob 已提交
5968

A
alteredq 已提交
5969 5970
			if ( isCube ) {

5971
				framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
A
alteredq 已提交
5972 5973 5974

			} else {

5975
				framebuffer = renderTarget.__webglFramebuffer;
A
alteredq 已提交
5976 5977 5978

			}

5979 5980
			width = renderTarget.width;
			height = renderTarget.height;
M
Mr.doob 已提交
5981

5982 5983 5984
			vx = 0;
			vy = 0;

5985
		} else {
M
Mr.doob 已提交
5986

5987
			framebuffer = null;
5988

5989 5990
			width = _viewportWidth;
			height = _viewportHeight;
5991

5992 5993
			vx = _viewportX;
			vy = _viewportY;
M
Mr.doob 已提交
5994

5995
		}
M
Mr.doob 已提交
5996

5997
		if ( framebuffer !== _currentFramebuffer ) {
M
Mr.doob 已提交
5998

5999
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
6000
			_gl.viewport( vx, vy, width, height );
M
Mr.doob 已提交
6001

6002
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
6003

6004
		}
6005

A
alteredq 已提交
6006 6007 6008
		_currentWidth = width;
		_currentHeight = height;

6009
	};
M
Mr.doob 已提交
6010

6011
	function updateRenderTargetMipmap ( renderTarget ) {
M
Mr.doob 已提交
6012

A
alteredq 已提交
6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025
		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 已提交
6026 6027

	};
6028

6029
	// Fallback filters for non-power-of-2 textures
6030

6031
	function filterFallback ( f ) {
6032

6033 6034 6035 6036 6037 6038 6039 6040
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mr.doob 已提交
6041
			case THREE.LinearMipMapLinearFilter:
M
Mikael Emtinger 已提交
6042
			default:
6043

M
Mikael Emtinger 已提交
6044
				return _gl.LINEAR; break;
6045 6046

		}
6047

6048
	};
6049

6050 6051
	// Map three.js constants to WebGL constants

6052
	function paramThreeToGL ( p ) {
M
Mr.doob 已提交
6053

6054
		switch ( p ) {
M
Mr.doob 已提交
6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067

			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;

6068 6069 6070 6071 6072
			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;
6073
			case THREE.UnsignedIntType: return _gl.UNSIGNED_INT; break;
6074 6075 6076 6077 6078 6079 6080 6081
			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;

6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098
			case THREE.AddEquation: return _gl.FUNC_ADD; break;
			case THREE.SubtractEquation: return _gl.FUNC_SUBTRACT; break;
			case THREE.ReverseSubtractEquation: return _gl.FUNC_REVERSE_SUBTRACT; break;

			case THREE.ZeroFactor: return _gl.ZERO; break;
			case THREE.OneFactor: return _gl.ONE; break;
			case THREE.SrcColorFactor: return _gl.SRC_COLOR; break;
			case THREE.OneMinusSrcColorFactor: return _gl.ONE_MINUS_SRC_COLOR; break;
			case THREE.SrcAlphaFactor: return _gl.SRC_ALPHA; break;
			case THREE.OneMinusSrcAlphaFactor: return _gl.ONE_MINUS_SRC_ALPHA; break;
			case THREE.DstAlphaFactor: return _gl.DST_ALPHA; break;
			case THREE.OneMinusDstAlphaFactor: return _gl.ONE_MINUS_DST_ALPHA; break;

			case THREE.DstColorFactor: return _gl.DST_COLOR; break;
			case THREE.OneMinusDstColorFactor: return _gl.ONE_MINUS_DST_COLOR; break;
			case THREE.SrcAlphaSaturateFactor: return _gl.SRC_ALPHA_SATURATE; break;

6099
		}
M
Mr.doob 已提交
6100

6101
		return 0;
M
Mr.doob 已提交
6102

6103 6104
	};

6105
	// Allocations
6106

6107
	function allocateBones ( object ) {
6108

6109 6110 6111 6112 6113 6114 6115
		// 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)
6116

6117
		var maxBones = 50;
6118

6119
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
6120

6121 6122 6123 6124 6125
			maxBones = object.bones.length;

		}

		return maxBones;
6126

6127
	};
6128

6129
	function allocateLights ( lights ) {
6130

A
alteredq 已提交
6131
		var l, ll, light, dirLights, pointLights, spotLights, maxDirLights, maxPointLights, maxSpotLights;
6132

A
alteredq 已提交
6133 6134 6135
		dirLights = pointLights = spotLights = maxDirLights = maxPointLights = maxSpotLights = 0;

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

6137
			light = lights[ l ];
6138

A
alteredq 已提交
6139 6140
			if ( light.onlyShadow ) continue;

6141 6142
			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
			if ( light instanceof THREE.PointLight ) pointLights ++;
A
alteredq 已提交
6143
			if ( light instanceof THREE.SpotLight ) spotLights ++;
6144

6145
		}
6146

A
alteredq 已提交
6147
		if ( ( pointLights + spotLights + dirLights ) <= _maxLights ) {
6148

6149 6150
			maxDirLights = dirLights;
			maxPointLights = pointLights;
A
alteredq 已提交
6151
			maxSpotLights = spotLights;
6152

6153
		} else {
6154

6155 6156
			maxDirLights = Math.ceil( _maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = _maxLights - maxDirLights;
A
alteredq 已提交
6157
			maxSpotLights = maxPointLights; // this is not really correct
6158 6159 6160

		}

A
alteredq 已提交
6161
		return { 'directional' : maxDirLights, 'point' : maxPointLights, 'spot': maxSpotLights };
6162 6163

	};
M
Mr.doob 已提交
6164

6165
	function allocateShadows ( lights ) {
6166

M
Mr.doob 已提交
6167
		var l, ll, light, maxShadows = 0;
6168 6169 6170 6171 6172

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

			light = lights[ l ];

A
alteredq 已提交
6173 6174
			if ( ! light.castShadow ) continue;

6175 6176
			if ( light instanceof THREE.SpotLight ) maxShadows ++;
			if ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) maxShadows ++;
6177 6178 6179 6180 6181 6182 6183

		}

		return maxShadows;

	};

6184
	// Initialization
M
Mr.doob 已提交
6185

6186 6187 6188 6189 6190 6191
	function initGL () {

		var gl;

		try {

6192
			if ( ! ( gl = _canvas.getContext( 'experimental-webgl', { alpha: _alpha, premultipliedAlpha: _premultipliedAlpha, antialias: _antialias, stencil: _stencil, preserveDrawingBuffer: _preserveDrawingBuffer } ) ) ) {
6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228

				throw 'Error creating WebGL context.';

			}

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

	};

6229 6230
	// default plugins (order is important)

A
alteredq 已提交
6231 6232 6233 6234 6235
	this.shadowMapPlugin = new THREE.ShadowMapPlugin();
	this.addPrePlugin( this.shadowMapPlugin );

	this.addPostPlugin( new THREE.SpritePlugin() );
	this.addPostPlugin( new THREE.LensFlarePlugin() );
6236

6237
};