WebGLRenderer.js 149.5 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 = [],
A
alteredq 已提交
107
	_programs_counter = 0,
108

109
	// internal state cache
110

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

118
	// GL state cache
119

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

123
	_oldBlending = -1,
124

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

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

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

136
	_oldLineWidth = null,
137

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

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

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

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

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

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

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

158 159
	_direction = new THREE.Vector3(),

160 161
	_lightsNeedUpdate = true,

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

164 165
		ambient: [ 0, 0, 0 ],
		directional: { length: 0, colors: new Array(), positions: new Array() },
A
alteredq 已提交
166 167
		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 已提交
168

169
	};
M
Mr.doob 已提交
170

171
	// initialize
M
Mikael Emtinger 已提交
172

173
	_gl = initGL();
M
Mikael Emtinger 已提交
174

175
	setDefaultGLState();
M
Mikael Emtinger 已提交
176

177
	this.context = _gl;
M
Mikael Emtinger 已提交
178

179 180 181
	// GPU capabilities

	var _maxVertexTextures = _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ),
A
alteredq 已提交
182
	_maxTextureSize = _gl.getParameter( _gl.MAX_TEXTURE_SIZE ),
183
	_maxCubemapSize = _gl.getParameter( _gl.MAX_CUBE_MAP_TEXTURE_SIZE );
M
Mr.doob 已提交
184

185
	// API
M
Mr.doob 已提交
186

187
	this.getContext = function () {
M
Mr.doob 已提交
188

189
		return _gl;
M
Mr.doob 已提交
190

191
	};
M
Mr.doob 已提交
192

193
	this.supportsVertexTextures = function () {
M
Mikael Emtinger 已提交
194

195
		return _maxVertexTextures > 0;
M
Mikael Emtinger 已提交
196

197
	};
M
Mikael Emtinger 已提交
198

N
Nicolas Garcia Belmonte 已提交
199 200 201 202
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
203

204 205 206
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
207

208
	this.setViewport = function ( x, y, width, height ) {
209

210 211
		_viewportX = x;
		_viewportY = y;
212

213 214
		_viewportWidth = width;
		_viewportHeight = height;
215

216
		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
217

N
Nicolas Garcia Belmonte 已提交
218
	};
219

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

222
		_gl.scissor( x, y, width, height );
223

224
	};
225

226
	this.enableScissorTest = function ( enable ) {
227

M
Mr.doob 已提交
228
		enable ? _gl.enable( _gl.SCISSOR_TEST ) : _gl.disable( _gl.SCISSOR_TEST );
229 230

	};
231

232 233
	// Clearing

234
	this.setClearColorHex = function ( hex, alpha ) {
235

236 237 238 239
		_clearColor.setHex( hex );
		_clearAlpha = alpha;

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

241
	};
A
alteredq 已提交
242

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

245 246 247 248
		_clearColor.copy( color );
		_clearAlpha = alpha;

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

	};
251

M
Mr.doob 已提交
252 253 254 255 256 257 258
	this.getClearColor = function () {

		return _clearColor;

	};

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

M
Mr.doob 已提交
260 261 262 263 264 265 266 267
		return _clearAlpha;

	};

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

		var bits = 0;

268 269 270
		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 已提交
271 272

		_gl.clear( bits );
N
Nicolas Garcia Belmonte 已提交
273 274 275

	};

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

A
alteredq 已提交
278
		this.setRenderTarget( renderTarget );
279
		this.clear( color, depth, stencil );
M
Mr.doob 已提交
280 281 282

	};

283 284
	// Plugins

A
alteredq 已提交
285
	this.addPostPlugin = function ( plugin ) {
286 287

		plugin.init( this );
A
alteredq 已提交
288
		this.renderPluginsPost.push( plugin );
289 290 291

	};

A
alteredq 已提交
292 293 294 295 296 297
	this.addPrePlugin = function ( plugin ) {

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

	};
298

299 300
	// Deallocation

301 302 303 304 305 306 307
	this.deallocateObject = function ( object ) {

		if ( ! object.__webglInit ) return;

		object.__webglInit = false;

		delete object._modelViewMatrix;
308
		delete object._normalMatrix;
309 310 311 312 313 314 315

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

		if ( object instanceof THREE.Mesh ) {

316
			for ( var g in object.geometry.geometryGroups ) {
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 342 343 344

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

347 348
	};

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

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

		_gl.deleteTexture( renderTarget.__webglTexture );

		if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {

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

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

			}

		} else {

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

		}

	};

A
alteredq 已提交
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435
	this.deallocateMaterial = function ( material ) {

		var program = material.program;

		if ( ! program ) return;

		material.program = undefined;

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

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

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

			programInfo = _programs[ i ];

			if ( programInfo.program === program ) {

				programInfo.usedTimes --;

				if ( programInfo.usedTimes === 0 ) {

					deleteProgram = true;

				}

				break;

			}

		}

		if ( deleteProgram ) {

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

			var newPrograms = [];

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

				programInfo = _programs[ i ];

				if ( programInfo.program !== program ) {

					newPrograms.push( programInfo );

				}

			}

			_programs = newPrograms;

			_gl.deleteProgram( program );

			_this.info.memory.programs --;

		}

	};

436
	// Rendering
437

438
	this.updateShadowMap = function ( scene, camera ) {
439

A
alteredq 已提交
440 441 442 443 444 445
		_currentProgram = null;
		_oldBlending = -1;
		_oldDepthTest = -1;
		_oldDepthWrite = -1;
		_currentGeometryGroupHash = -1;
		_currentMaterialId = -1;
446 447 448
		_lightsNeedUpdate = true;
		_oldDoubleSided = -1;
		_oldFlipSided = -1;
A
alteredq 已提交
449 450

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

452
	};
M
Mr.doob 已提交
453

454
	// Internal functions
455

456
	// Buffer allocation
457

458
	function createParticleBuffers ( geometry ) {
459

460 461
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
462

463
		_this.info.geometries ++;
464

465
	};
466

467
	function createLineBuffers ( geometry ) {
468

469 470
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
471

472
		_this.info.memory.geometries ++;
473

474
	};
475

476
	function createRibbonBuffers ( geometry ) {
477

478 479
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
480

481
		_this.info.memory.geometries ++;
M
Mr.doob 已提交
482

483
	};
484

485
	function createMeshBuffers ( geometryGroup ) {
486

487 488 489 490 491 492
		geometryGroup.__webglVertexBuffer = _gl.createBuffer();
		geometryGroup.__webglNormalBuffer = _gl.createBuffer();
		geometryGroup.__webglTangentBuffer = _gl.createBuffer();
		geometryGroup.__webglColorBuffer = _gl.createBuffer();
		geometryGroup.__webglUVBuffer = _gl.createBuffer();
		geometryGroup.__webglUV2Buffer = _gl.createBuffer();
493

494 495 496 497
		geometryGroup.__webglSkinVertexABuffer = _gl.createBuffer();
		geometryGroup.__webglSkinVertexBBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinIndicesBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinWeightsBuffer = _gl.createBuffer();
498

499 500
		geometryGroup.__webglFaceBuffer = _gl.createBuffer();
		geometryGroup.__webglLineBuffer = _gl.createBuffer();
501

502
		var m, ml;
503

504
		if ( geometryGroup.numMorphTargets ) {
505

506
			geometryGroup.__webglMorphTargetsBuffers = [];
507

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

510
				geometryGroup.__webglMorphTargetsBuffers.push( _gl.createBuffer() );
511 512 513 514 515 516 517 518 519 520 521

			}

		}

		if ( geometryGroup.numMorphNormals ) {

			geometryGroup.__webglMorphNormalsBuffers = [];

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

A
alteredq 已提交
522
				geometryGroup.__webglMorphNormalsBuffers.push( _gl.createBuffer() );
523

524
			}
525

526
		}
527

528
		_this.info.memory.geometries ++;
529

530
	};
531

532
	// Buffer deallocation
533

534
	function deleteParticleBuffers ( geometry ) {
535

536 537
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
538

539
		_this.info.memory.geometries --;
540

541
	};
542

543
	function deleteLineBuffers ( geometry ) {
544

545 546
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
547

M
Mr.doob 已提交
548 549
		_this.info.memory.geometries --;

550 551
	};

552
	function deleteRibbonBuffers ( geometry ) {
553 554 555 556

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

M
Mr.doob 已提交
557 558
		_this.info.memory.geometries --;

559 560
	};

561
	function deleteMeshBuffers ( geometryGroup ) {
562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577

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

578 579
		var m, ml;

580 581
		if ( geometryGroup.numMorphTargets ) {

582
			for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
583 584

				_gl.deleteBuffer( geometryGroup.__webglMorphTargetsBuffers[ m ] );
585 586 587 588 589 590 591 592 593

			}

		}

		if ( geometryGroup.numMorphNormals ) {

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

A
alteredq 已提交
594
				_gl.deleteBuffer( geometryGroup.__webglMorphNormalsBuffers[ m ] );
595 596 597 598 599

			}

		}

600 601 602 603 604 605 606 607 608 609 610

		if ( geometryGroup.__webglCustomAttributesList ) {

			for ( var id in geometryGroup.__webglCustomAttributesList ) {

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

			}

		}

M
Mr.doob 已提交
611 612
		_this.info.memory.geometries --;

613 614
	};

615
	// Buffer initialization
616

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

619 620
		var nvertices = geometry.vertices.length;

621
		var material = object.material;
622

623
		if ( material.attributes ) {
624

625
			if ( geometry.__webglCustomAttributesList === undefined ) {
626

627
				geometry.__webglCustomAttributesList = [];
628

629
			}
630

631
			for ( var a in material.attributes ) {
632

633
				var attribute = material.attributes[ a ];
634

635
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
636

637
					attribute.__webglInitialized = true;
638

A
alteredq 已提交
639
					var size = 1;		// "f" and "i"
640

641 642 643 644
					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;
645

646
					attribute.size = size;
A
alteredq 已提交
647

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

650 651
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
652

653
					attribute.needsUpdate = true;
654

655
				}
656

657
				geometry.__webglCustomAttributesList.push( attribute );
658

659
			}
660

661
		}
662

663
	};
664

665
	function initParticleBuffers ( geometry, object ) {
A
alteredq 已提交
666 667 668 669 670 671

		var nvertices = geometry.vertices.length;

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

672 673 674
		geometry.__sortArray = [];

		geometry.__webglParticleCount = nvertices;
A
alteredq 已提交
675 676 677 678 679

		initCustomAttributes ( geometry, object );

	};

680
	function initLineBuffers ( geometry, object ) {
A
alteredq 已提交
681 682 683 684 685 686

		var nvertices = geometry.vertices.length;

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

687
		geometry.__webglLineCount = nvertices;
A
alteredq 已提交
688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703

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

706 707 708
		var geometry = object.geometry,
			faces3 = geometryGroup.faces3,
			faces4 = geometryGroup.faces4,
M
Mr.doob 已提交
709

710 711 712
			nvertices = faces3.length * 3 + faces4.length * 4,
			ntris     = faces3.length * 1 + faces4.length * 2,
			nlines    = faces3.length * 3 + faces4.length * 4,
713

714
			material = getBufferMaterial( object, geometryGroup ),
715

716 717 718
			uvType = bufferGuessUVType( material ),
			normalType = bufferGuessNormalType( material ),
			vertexColorType = bufferGuessVertexColorType( material );
A
alteredq 已提交
719

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

722
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
723

724
		if ( normalType ) {
M
Mr.doob 已提交
725

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

728
		}
729

730
		if ( geometry.hasTangents ) {
731

732
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
733

734
		}
735

736
		if ( vertexColorType ) {
737

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

740
		}
M
Mr.doob 已提交
741

742
		if ( uvType ) {
743

744
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
745

746 747 748 749 750
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

752 753 754 755 756 757 758 759 760 761 762 763 764 765 766
				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 );

		}

767
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
768
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
769

770 771
		var m, ml;

772 773
		if ( geometryGroup.numMorphTargets ) {

M
Mr.doob 已提交
774
			geometryGroup.__morphTargetsArrays = [];
775

776
			for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
777

778
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );
779 780 781 782 783 784 785 786 787 788 789

			}

		}

		if ( geometryGroup.numMorphNormals ) {

			geometryGroup.__morphNormalsArrays = [];

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

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

792 793 794
			}

		}
795

796
		geometryGroup.__webglFaceCount = ntris * 3;
797
		geometryGroup.__webglLineCount = nlines * 2;
798

M
Mr.doob 已提交
799

800
		// custom attributes
M
Mr.doob 已提交
801

802
		if ( material.attributes ) {
803

804
			if ( geometryGroup.__webglCustomAttributesList === undefined ) {
805

806
				geometryGroup.__webglCustomAttributesList = [];
807

808
			}
809

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

812 813
				// Do a shallow copy of the attribute object so different geometryGroup chunks use different
				// attribute buffers which are correctly indexed in the setMeshBuffers function
814

815
				var originalAttribute = material.attributes[ a ];
816

817
				var attribute = {};
818

819
				for ( var property in originalAttribute ) {
M
Mr.doob 已提交
820

821
					attribute[ property ] = originalAttribute[ property ];
822

823
				}
824

825
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
826

827
					attribute.__webglInitialized = true;
828

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

831 832 833 834
					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;
835

836
					attribute.size = size;
A
alteredq 已提交
837

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

840 841
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
842

843 844
					originalAttribute.needsUpdate = true;
					attribute.__original = originalAttribute;
845 846 847

				}

848 849
				geometryGroup.__webglCustomAttributesList.push( attribute );

850
			}
M
Mr.doob 已提交
851

852
		}
853

854 855
		geometryGroup.__inittedArrays = true;

856
	};
M
Mr.doob 已提交
857

858
	function getBufferMaterial( object, geometryGroup ) {
859

860
		if ( object.material && ! ( object.material instanceof THREE.MeshFaceMaterial ) ) {
861

862
			return object.material;
863

864
		} else if ( geometryGroup.materialIndex >= 0 ) {
865

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

868
		}
869

870
	};
M
Mr.doob 已提交
871

872
	function materialNeedsSmoothNormals ( material ) {
873

874
		return material && material.shading !== undefined && material.shading === THREE.SmoothShading;
875

876
	};
M
Mr.doob 已提交
877

878
	function bufferGuessNormalType ( material ) {
879

880
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
881

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

884
			return false;
885

886
		}
887

888
		if ( materialNeedsSmoothNormals( material ) ) {
889

890
			return THREE.SmoothShading;
M
Mr.doob 已提交
891

892
		} else {
893

894
			return THREE.FlatShading;
895

896
		}
897

898
	};
899

900
	function bufferGuessVertexColorType ( material ) {
901

902
		if ( material.vertexColors ) {
903

904
			return material.vertexColors;
905

906
		}
M
Mr.doob 已提交
907

908
		return false;
M
Mr.doob 已提交
909

910
	};
M
Mr.doob 已提交
911

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

943
		dirtyVertices = geometry.verticesNeedUpdate,
M
Mr.doob 已提交
944
		dirtyElements = geometry.elementsNeedUpdate,
M
Mr.doob 已提交
945
		dirtyColors = geometry.colorsNeedUpdate,
946 947 948 949 950 951 952 953

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

		if ( object.sortParticles ) {

A
alteredq 已提交
954 955
			_projScreenMatrixPS.copy( _projScreenMatrix );
			_projScreenMatrixPS.multiplySelf( object.matrixWorld );
956 957 958

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

959
				vertex = vertices[ v ];
960 961

				_vector3.copy( vertex );
A
alteredq 已提交
962
				_projScreenMatrixPS.multiplyVector3( _vector3 );
963 964 965 966 967 968 969 970 971

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

			}

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

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

972
				vertex = vertices[ sortArray[v][1] ];
973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095

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

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

					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 &&
1131
						 ( customAttribute.boundTo === undefined ||
1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261
						   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,

1262
		dirtyVertices = geometry.verticesNeedUpdate,
M
Mr.doob 已提交
1263
		dirtyColors = geometry.colorsNeedUpdate,
1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274

		customAttributes = geometry.__webglCustomAttributesList,

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

		if ( dirtyVertices ) {

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

1275
				vertex = vertices[ v ];
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 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415

				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,

1416
		dirtyVertices = geometry.verticesNeedUpdate,
M
Mr.doob 已提交
1417
		dirtyColors = geometry.colorsNeedUpdate;
1418 1419 1420 1421 1422

		if ( dirtyVertices ) {

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

1423
				vertex = vertices[ v ];
1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458

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

		}

	};

1459
	function setMeshBuffers( geometryGroup, object, hint, dispose, material ) {
1460 1461 1462 1463 1464 1465 1466 1467

		if ( ! geometryGroup.__inittedArrays ) {

			// console.log( object );
			return;

		}

1468 1469 1470 1471 1472 1473
		var normalType = bufferGuessNormalType( material ),
		vertexColorType = bufferGuessVertexColorType( material ),
		uvType = bufferGuessUVType( material ),

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

1474 1475 1476 1477
		var f, fl, fi, face,
		vertexNormals, faceNormal, normal,
		vertexColors, faceColor,
		vertexTangents,
A
alteredq 已提交
1478
		uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4, n1, n2, n3, n4,
1479 1480 1481 1482 1483 1484 1485 1486
		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 已提交
1487
		nka, chf, faceVertexNormals,
1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519
		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 已提交
1520
		morphNormalsArrays = geometryGroup.__morphNormalsArrays,
1521 1522 1523 1524 1525 1526 1527 1528 1529

		customAttributes = geometryGroup.__webglCustomAttributesList,
		customAttribute,

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

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

1530
		dirtyVertices = geometry.verticesNeedUpdate,
M
Mr.doob 已提交
1531
		dirtyElements = geometry.elementsNeedUpdate,
M
Mr.doob 已提交
1532
		dirtyUvs = geometry.uvsNeedUpdate,
M
Mr.doob 已提交
1533
		dirtyNormals = geometry.normalsNeedUpdate,
M
Mr.doob 已提交
1534
		dirtyTangents = geometry.tangetsNeedUpdate,
M
Mr.doob 已提交
1535
		dirtyColors = geometry.colorsNeedUpdate,
1536
		dirtyMorphTargets = geometry.morphTargetsNeedUpdate,
1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552

		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 已提交
1553 1554
		morphTargets = geometry.morphTargets,
		morphNormals = geometry.morphNormals;
1555 1556 1557 1558 1559 1560 1561

		if ( dirtyVertices ) {

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

				face = obj_faces[ chunk_faces3[ f ] ];

1562 1563 1564
				v1 = vertices[ face.a ];
				v2 = vertices[ face.b ];
				v3 = vertices[ face.c ];
1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576

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

1578
				offset += 9;
M
Mr.doob 已提交
1579

1580
			}
1581

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

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

1586 1587 1588 1589
				v1 = vertices[ face.a ];
				v2 = vertices[ face.b ];
				v3 = vertices[ face.c ];
				v4 = vertices[ face.d ];
1590

A
alteredq 已提交
1591 1592 1593
				vertexArray[ offset ]     = v1.x;
				vertexArray[ offset + 1 ] = v1.y;
				vertexArray[ offset + 2 ] = v1.z;
1594

A
alteredq 已提交
1595 1596 1597
				vertexArray[ offset + 3 ] = v2.x;
				vertexArray[ offset + 4 ] = v2.y;
				vertexArray[ offset + 5 ] = v2.z;
1598

A
alteredq 已提交
1599 1600 1601
				vertexArray[ offset + 6 ] = v3.x;
				vertexArray[ offset + 7 ] = v3.y;
				vertexArray[ offset + 8 ] = v3.z;
1602

A
alteredq 已提交
1603 1604 1605
				vertexArray[ offset + 9 ]  = v4.x;
				vertexArray[ offset + 10 ] = v4.y;
				vertexArray[ offset + 11 ] = v4.z;
1606

A
alteredq 已提交
1607
				offset += 12;
1608

A
alteredq 已提交
1609
			}
1610

A
alteredq 已提交
1611 1612
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1613

A
alteredq 已提交
1614
		}
M
Mr.doob 已提交
1615

A
alteredq 已提交
1616
		if ( dirtyMorphTargets ) {
M
Mr.doob 已提交
1617

1618
			for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {
1619

1620
				offset_morphTarget = 0;
1621

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

A
alteredq 已提交
1624 1625 1626 1627
					chf = chunk_faces3[ f ];
					face = obj_faces[ chf ];

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

1629 1630 1631
					v1 = morphTargets[ vk ].vertices[ face.a ];
					v2 = morphTargets[ vk ].vertices[ face.b ];
					v3 = morphTargets[ vk ].vertices[ face.c ];
M
Mr.doob 已提交
1632

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

A
alteredq 已提交
1635 1636 1637
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
M
Mr.doob 已提交
1638

A
alteredq 已提交
1639 1640 1641
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
M
Mr.doob 已提交
1642

A
alteredq 已提交
1643 1644 1645
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
M
Mr.doob 已提交
1646

A
alteredq 已提交
1647 1648 1649 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
					// 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;

					}

					//

1685
					offset_morphTarget += 9;
1686

1687
				}
1688

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

A
alteredq 已提交
1691 1692 1693 1694
					chf = chunk_faces4[ f ];
					face = obj_faces[ chf ];

					// morph positions
1695

1696 1697 1698 1699
					v1 = morphTargets[ vk ].vertices[ face.a ];
					v2 = morphTargets[ vk ].vertices[ face.b ];
					v3 = morphTargets[ vk ].vertices[ face.c ];
					v4 = morphTargets[ vk ].vertices[ face.d ];
1700

1701
					vka = morphTargetsArrays[ vk ];
1702

1703 1704 1705
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
1706

1707 1708 1709
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
1710

1711 1712 1713
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
1714

A
alteredq 已提交
1715 1716 1717 1718
					vka[ offset_morphTarget + 9 ]  = v4.x;
					vka[ offset_morphTarget + 10 ] = v4.y;
					vka[ offset_morphTarget + 11 ] = v4.z;

A
alteredq 已提交
1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762
					// 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;

					}

					//

1763
					offset_morphTarget += 12;
A
alteredq 已提交
1764

1765
				}
A
alteredq 已提交
1766 1767 1768

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

A
alteredq 已提交
1770 1771 1772 1773 1774 1775 1776
				if ( material.morphNormals ) {

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

				}

1777
			}
1778

A
alteredq 已提交
1779 1780 1781 1782 1783 1784 1785
		}

		if ( obj_skinWeights.length ) {

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

				face = obj_faces[ chunk_faces3[ f ]	];
1786

1787
				// weights
A
alteredq 已提交
1788

1789 1790 1791
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
A
alteredq 已提交
1792

1793 1794 1795 1796
				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 已提交
1797

1798 1799 1800 1801
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1802

1803 1804 1805 1806
				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 已提交
1807

1808
				// indices
A
alteredq 已提交
1809

1810 1811 1812
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
A
alteredq 已提交
1813

1814 1815 1816 1817
				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 已提交
1818

1819 1820 1821 1822
				skinIndexArray[ offset_skin + 4 ] = si2.x;
				skinIndexArray[ offset_skin + 5 ] = si2.y;
				skinIndexArray[ offset_skin + 6 ] = si2.z;
				skinIndexArray[ offset_skin + 7 ] = si2.w;
1823

1824 1825 1826 1827
				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 已提交
1828

1829
				// vertices A
A
alteredq 已提交
1830

1831 1832 1833
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
A
alteredq 已提交
1834

1835 1836 1837 1838
				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 已提交
1839

1840 1841 1842 1843
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1844

1845 1846 1847 1848
				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 已提交
1849

1850
				// vertices B
A
alteredq 已提交
1851

1852 1853 1854
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
A
alteredq 已提交
1855

1856 1857 1858 1859
				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 已提交
1860

1861 1862 1863 1864
				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
				skinVertexBArray[ offset_skin + 7 ] = 1;
1865

1866 1867 1868 1869
				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
				skinVertexBArray[ offset_skin + 11 ] = 1;
1870

1871
				offset_skin += 12;
1872

1873
			}
1874

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

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

A
alteredq 已提交
1879
				// weights
1880

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

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

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

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

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

A
alteredq 已提交
1906
				// indices
1907

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

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

A
alteredq 已提交
1918 1919 1920 1921
				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 已提交
1922

A
alteredq 已提交
1923 1924 1925 1926
				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 已提交
1927

A
alteredq 已提交
1928 1929 1930 1931
				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 已提交
1932

A
alteredq 已提交
1933
				// vertices A
M
Mr.doob 已提交
1934

A
alteredq 已提交
1935 1936 1937 1938
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
				sa4 = obj_skinVerticesA[ face.d ];
1939

A
alteredq 已提交
1940 1941 1942 1943
				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 已提交
1944

A
alteredq 已提交
1945 1946 1947 1948
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1949

A
alteredq 已提交
1950 1951 1952 1953
				skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
				skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
				skinVertexAArray[ offset_skin + 10 ] = sa3.z;
				skinVertexAArray[ offset_skin + 11 ] = 1;
1954

A
alteredq 已提交
1955 1956 1957 1958
				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 已提交
1959

A
alteredq 已提交
1960
				// vertices B
M
Mr.doob 已提交
1961

A
alteredq 已提交
1962 1963 1964 1965
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
				sb4 = obj_skinVerticesB[ face.d ];
M
Mr.doob 已提交
1966

A
alteredq 已提交
1967 1968 1969 1970
				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 已提交
1971

A
alteredq 已提交
1972 1973 1974 1975
				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
				skinVertexBArray[ offset_skin + 7 ] = 1;
1976

A
alteredq 已提交
1977 1978 1979 1980
				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
				skinVertexBArray[ offset_skin + 11 ] = 1;
1981

A
alteredq 已提交
1982 1983 1984 1985
				skinVertexBArray[ offset_skin + 12 ] = sb4.x;
				skinVertexBArray[ offset_skin + 13 ] = sb4.y;
				skinVertexBArray[ offset_skin + 14 ] = sb4.z;
				skinVertexBArray[ offset_skin + 15 ] = 1;
1986

A
alteredq 已提交
1987
				offset_skin += 16;
M
Mr.doob 已提交
1988

A
alteredq 已提交
1989
			}
M
Mr.doob 已提交
1990

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

A
alteredq 已提交
1993 1994
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );
M
Mr.doob 已提交
1995

A
alteredq 已提交
1996 1997 1998 1999 2000 2001 2002 2003
				_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 );
2004

2005
			}
2006

A
alteredq 已提交
2007
		}
M
Mr.doob 已提交
2008

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

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

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

A
alteredq 已提交
2015 2016
				vertexColors = face.vertexColors;
				faceColor = face.color;
2017

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

A
alteredq 已提交
2020 2021 2022
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
2023

A
alteredq 已提交
2024
				} else {
2025

A
alteredq 已提交
2026 2027 2028
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
2029

A
alteredq 已提交
2030
				}
2031

A
alteredq 已提交
2032 2033 2034
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
2035

A
alteredq 已提交
2036 2037 2038
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
2039

A
alteredq 已提交
2040 2041 2042
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
2043

A
alteredq 已提交
2044
				offset_color += 9;
M
Mr.doob 已提交
2045

A
alteredq 已提交
2046
			}
M
Mr.doob 已提交
2047

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

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

A
alteredq 已提交
2052 2053
				vertexColors = face.vertexColors;
				faceColor = face.color;
M
Mr.doob 已提交
2054

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

A
alteredq 已提交
2057 2058 2059 2060
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
					c4 = vertexColors[ 3 ];
2061

A
alteredq 已提交
2062
				} else {
M
Mr.doob 已提交
2063

A
alteredq 已提交
2064 2065 2066 2067
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
					c4 = faceColor;
M
Mr.doob 已提交
2068

A
alteredq 已提交
2069
				}
2070

A
alteredq 已提交
2071 2072 2073
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
2074

A
alteredq 已提交
2075 2076 2077
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
M
Mr.doob 已提交
2078

A
alteredq 已提交
2079 2080 2081
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
M
Mr.doob 已提交
2082

A
alteredq 已提交
2083 2084 2085
				colorArray[ offset_color + 9 ]  = c4.r;
				colorArray[ offset_color + 10 ] = c4.g;
				colorArray[ offset_color + 11 ] = c4.b;
M
Mr.doob 已提交
2086

A
alteredq 已提交
2087
				offset_color += 12;
2088

2089
			}
2090

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

A
alteredq 已提交
2093 2094
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
M
Mr.doob 已提交
2095

2096
			}
2097

A
alteredq 已提交
2098
		}
M
Mr.doob 已提交
2099

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

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

A
alteredq 已提交
2104
				face = obj_faces[ chunk_faces3[ f ]	];
2105

A
alteredq 已提交
2106
				vertexTangents = face.vertexTangents;
M
Mr.doob 已提交
2107

A
alteredq 已提交
2108 2109 2110
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
2111

A
alteredq 已提交
2112 2113 2114 2115
				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 已提交
2116

A
alteredq 已提交
2117 2118 2119 2120
				tangentArray[ offset_tangent + 4 ] = t2.x;
				tangentArray[ offset_tangent + 5 ] = t2.y;
				tangentArray[ offset_tangent + 6 ] = t2.z;
				tangentArray[ offset_tangent + 7 ] = t2.w;
2121

A
alteredq 已提交
2122 2123 2124 2125
				tangentArray[ offset_tangent + 8 ]  = t3.x;
				tangentArray[ offset_tangent + 9 ]  = t3.y;
				tangentArray[ offset_tangent + 10 ] = t3.z;
				tangentArray[ offset_tangent + 11 ] = t3.w;
2126

A
alteredq 已提交
2127
				offset_tangent += 12;
2128

2129
			}
2130

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

A
alteredq 已提交
2133
				face = obj_faces[ chunk_faces4[ f ] ];
2134

A
alteredq 已提交
2135
				vertexTangents = face.vertexTangents;
2136

A
alteredq 已提交
2137 2138 2139 2140
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
				t4 = vertexTangents[ 3 ];
2141

A
alteredq 已提交
2142 2143 2144 2145
				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 已提交
2146

A
alteredq 已提交
2147 2148 2149 2150
				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 已提交
2151

A
alteredq 已提交
2152 2153 2154 2155
				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 已提交
2156

A
alteredq 已提交
2157 2158 2159 2160
				tangentArray[ offset_tangent + 12 ] = t4.x;
				tangentArray[ offset_tangent + 13 ] = t4.y;
				tangentArray[ offset_tangent + 14 ] = t4.z;
				tangentArray[ offset_tangent + 15 ] = t4.w;
2161

A
alteredq 已提交
2162
				offset_tangent += 16;
2163

A
alteredq 已提交
2164
			}
2165

A
alteredq 已提交
2166 2167
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
2168

A
alteredq 已提交
2169
		}
2170

A
alteredq 已提交
2171
		if ( dirtyNormals && normalType ) {
2172

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

A
alteredq 已提交
2175
				face = obj_faces[ chunk_faces3[ f ]	];
2176

A
alteredq 已提交
2177 2178
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
2179

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

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

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

A
alteredq 已提交
2186 2187 2188
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
2189

A
alteredq 已提交
2190
						offset_normal += 3;
2191

A
alteredq 已提交
2192
					}
2193

A
alteredq 已提交
2194
				} else {
M
Mr.doob 已提交
2195

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

A
alteredq 已提交
2198 2199 2200
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
2201

A
alteredq 已提交
2202
						offset_normal += 3;
M
Mr.doob 已提交
2203

A
alteredq 已提交
2204
					}
2205

A
alteredq 已提交
2206
				}
2207

A
alteredq 已提交
2208
			}
2209

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

A
alteredq 已提交
2212
				face = obj_faces[ chunk_faces4[ f ] ];
2213

A
alteredq 已提交
2214 2215
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
2216

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

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

A
alteredq 已提交
2221
						vn = vertexNormals[ i ];
2222

A
alteredq 已提交
2223 2224 2225
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
2226

A
alteredq 已提交
2227
						offset_normal += 3;
2228

A
alteredq 已提交
2229
					}
M
Mr.doob 已提交
2230

A
alteredq 已提交
2231
				} else {
2232

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

A
alteredq 已提交
2235 2236 2237
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
2238

A
alteredq 已提交
2239
						offset_normal += 3;
M
Mr.doob 已提交
2240

A
alteredq 已提交
2241
					}
2242

A
alteredq 已提交
2243
				}
2244

A
alteredq 已提交
2245
			}
M
Mr.doob 已提交
2246

A
alteredq 已提交
2247 2248
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
2249

A
alteredq 已提交
2250
		}
M
Mr.doob 已提交
2251

A
alteredq 已提交
2252
		if ( dirtyUvs && obj_uvs && uvType ) {
2253

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

A
alteredq 已提交
2256
				fi = chunk_faces3[ f ];
2257

A
alteredq 已提交
2258 2259
				face = obj_faces[ fi ];
				uv = obj_uvs[ fi ];
2260

A
alteredq 已提交
2261
				if ( uv === undefined ) continue;
2262

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

A
alteredq 已提交
2265
					uvi = uv[ i ];
2266

A
alteredq 已提交
2267 2268
					uvArray[ offset_uv ]     = uvi.u;
					uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
2269

A
alteredq 已提交
2270
					offset_uv += 2;
M
Mr.doob 已提交
2271

A
alteredq 已提交
2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292
				}

			}

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

2294 2295
				}

2296
			}
2297

A
alteredq 已提交
2298
			if ( offset_uv > 0 ) {
2299

A
alteredq 已提交
2300 2301
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
2302

A
alteredq 已提交
2303
			}
2304

A
alteredq 已提交
2305
		}
2306

A
alteredq 已提交
2307
		if ( dirtyUvs && obj_uvs2 && uvType ) {
2308

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

A
alteredq 已提交
2311
				fi = chunk_faces3[ f ];
2312

A
alteredq 已提交
2313 2314
				face = obj_faces[ fi ];
				uv2 = obj_uvs2[ fi ];
2315

A
alteredq 已提交
2316 2317 2318 2319 2320 2321 2322 2323 2324 2325
				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;
2326

2327 2328
				}

A
alteredq 已提交
2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349
			}

			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;

				}
2350

2351
			}
2352

A
alteredq 已提交
2353
			if ( offset_uv2 > 0 ) {
2354

A
alteredq 已提交
2355 2356
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );
2357

A
alteredq 已提交
2358
			}
2359

A
alteredq 已提交
2360
		}
2361

A
alteredq 已提交
2362
		if ( dirtyElements ) {
2363

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

A
alteredq 已提交
2366
				face = obj_faces[ chunk_faces3[ f ]	];
2367

A
alteredq 已提交
2368 2369 2370
				faceArray[ offset_face ] 	 = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 2;
2371

A
alteredq 已提交
2372
				offset_face += 3;
2373

A
alteredq 已提交
2374 2375
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2376

A
alteredq 已提交
2377 2378
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 2;
2379

A
alteredq 已提交
2380 2381
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
2382

A
alteredq 已提交
2383
				offset_line += 6;
2384

A
alteredq 已提交
2385
				vertexIndex += 3;
2386

A
alteredq 已提交
2387
			}
2388

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

A
alteredq 已提交
2391
				face = obj_faces[ chunk_faces4[ f ] ];
2392

A
alteredq 已提交
2393 2394 2395
				faceArray[ offset_face ]     = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 3;
2396

A
alteredq 已提交
2397 2398 2399
				faceArray[ offset_face + 3 ] = vertexIndex + 1;
				faceArray[ offset_face + 4 ] = vertexIndex + 2;
				faceArray[ offset_face + 5 ] = vertexIndex + 3;
2400

A
alteredq 已提交
2401
				offset_face += 6;
2402

A
alteredq 已提交
2403 2404
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2405

A
alteredq 已提交
2406 2407
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 3;
2408

A
alteredq 已提交
2409 2410
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
2411

A
alteredq 已提交
2412 2413
				lineArray[ offset_line + 6 ] = vertexIndex + 2;
				lineArray[ offset_line + 7 ] = vertexIndex + 3;
2414

A
alteredq 已提交
2415
				offset_line += 8;
2416

A
alteredq 已提交
2417
				vertexIndex += 4;
2418

2419
			}
2420

A
alteredq 已提交
2421 2422
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
2423

A
alteredq 已提交
2424 2425
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
2426

A
alteredq 已提交
2427
		}
2428

A
alteredq 已提交
2429
		if ( customAttributes ) {
2430

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

2433
				customAttribute = customAttributes[ i ];
2434

2435
				if ( ! customAttribute.__original.needsUpdate ) continue;
2436

2437 2438
				offset_custom = 0;
				offset_customSrc = 0;
2439

2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472
				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 ++ ) {

2473
							value = customAttribute.value[ chunk_faces3[ f ] ];
2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484

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

2485
							value = customAttribute.value[ chunk_faces4[ f ] ];
2486 2487 2488 2489 2490 2491 2492 2493 2494

							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;

						}
2495

2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514
					}

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

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

2519
							offset_custom += 6;
A
alteredq 已提交
2520

2521
						}
A
alteredq 已提交
2522

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

2525
							face = obj_faces[ chunk_faces4[ f ] ];
A
alteredq 已提交
2526

2527 2528 2529 2530
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
A
alteredq 已提交
2531

2532 2533
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2534

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

2538 2539
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2540

2541 2542
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
A
alteredq 已提交
2543

2544
							offset_custom += 8;
A
alteredq 已提交
2545

2546
						}
A
alteredq 已提交
2547

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

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

2552
							value = customAttribute.value[ chunk_faces3[ f ] ];
A
alteredq 已提交
2553

2554 2555 2556
							v1 = value;
							v2 = value;
							v3 = value;
A
alteredq 已提交
2557

2558 2559
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2560

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

2564 2565
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2566

2567
							offset_custom += 6;
A
alteredq 已提交
2568

2569
						}
A
alteredq 已提交
2570

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

2573
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2574

2575 2576 2577 2578
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2579

2580 2581
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2582

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

2586 2587
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2588

2589 2590
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
2591

2592
							offset_custom += 8;
M
Mr.doob 已提交
2593

2594
						}
M
Mr.doob 已提交
2595

M
Mr.doob 已提交
2596
					}
M
Mr.doob 已提交
2597

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

2600
					var pp;
2601

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

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

2606
					} else {
M
Mr.doob 已提交
2607

2608
						pp = [ "x", "y", "z" ];
2609

2610
					}
2611

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

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

2616
							face = obj_faces[ chunk_faces3[ f ]	];
2617

2618 2619 2620
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
2621

2622 2623 2624
							customAttribute.array[ offset_custom ] 	   = v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
2625

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

2630 2631 2632
							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 已提交
2633

2634
							offset_custom += 9;
M
Mr.doob 已提交
2635

2636
						}
M
Mr.doob 已提交
2637

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

2640
							face = obj_faces[ chunk_faces4[ f ] ];
M
Mr.doob 已提交
2641

2642 2643 2644 2645
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
M
Mr.doob 已提交
2646

2647 2648 2649
							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 已提交
2650

2651 2652 2653
							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 已提交
2654

2655 2656 2657
							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 已提交
2658

2659 2660 2661
							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 已提交
2662

2663
							offset_custom += 12;
M
Mr.doob 已提交
2664

2665
						}
M
Mr.doob 已提交
2666

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

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

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

2673 2674 2675
							v1 = value;
							v2 = value;
							v3 = value;
M
Mr.doob 已提交
2676

2677 2678 2679
							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 已提交
2680

2681 2682 2683
							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 已提交
2684

2685 2686 2687
							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 已提交
2688

2689
							offset_custom += 9;
M
Mr.doob 已提交
2690

2691
						}
2692

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

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

2697 2698 2699 2700
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
2701

2702 2703 2704
							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
2705

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

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

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

2718
							offset_custom += 12;
2719

2720
						}
2721

A
alteredq 已提交
2722
					}
M
Mr.doob 已提交
2723

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

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

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

2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791
							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 ++ ) {

2792
							value = customAttribute.value[ chunk_faces3[ f ] ];
2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809

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

2813
							offset_custom += 12;
A
alteredq 已提交
2814

2815 2816
						}

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

2819
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2820

2821 2822 2823 2824
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2825

2826 2827 2828 2829
							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;
2830

2831 2832 2833 2834
							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;
2835

2836 2837 2838 2839
							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;
2840

2841 2842 2843 2844
							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;
2845

2846
							offset_custom += 16;
A
alteredq 已提交
2847

2848
						}
A
alteredq 已提交
2849 2850 2851 2852 2853

					}

				}

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

A
alteredq 已提交
2857 2858 2859 2860
			}

		}

2861
		if ( dispose ) {
2862

2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875
			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 已提交
2876

2877
		}
A
alteredq 已提交
2878

2879
	};
A
alteredq 已提交
2880

2881
	// Buffer rendering
A
alteredq 已提交
2882

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

2885 2886
		if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
A
alteredq 已提交
2887

2888
		if ( object.hasPos ) {
A
alteredq 已提交
2889

2890 2891 2892 2893
			_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 已提交
2894 2895 2896

		}

2897
		if ( object.hasNormal ) {
A
alteredq 已提交
2898

2899
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
A
alteredq 已提交
2900

2901
			if ( shading === THREE.FlatShading ) {
2902

2903 2904 2905 2906
				var nx, ny, nz,
					nax, nbx, ncx, nay, nby, ncy, naz, nbz, ncz,
					normalArray,
					i, il = object.count * 3;
2907

2908
				for( i = 0; i < il; i += 9 ) {
2909

2910
					normalArray = object.normalArray;
2911

2912 2913 2914
					nax  = normalArray[ i ];
					nay  = normalArray[ i + 1 ];
					naz  = normalArray[ i + 2 ];
2915

2916 2917 2918
					nbx  = normalArray[ i + 3 ];
					nby  = normalArray[ i + 4 ];
					nbz  = normalArray[ i + 5 ];
2919

2920 2921 2922
					ncx  = normalArray[ i + 6 ];
					ncy  = normalArray[ i + 7 ];
					ncz  = normalArray[ i + 8 ];
2923

2924 2925 2926
					nx = ( nax + nbx + ncx ) / 3;
					ny = ( nay + nby + ncy ) / 3;
					nz = ( naz + nbz + ncz ) / 3;
2927

2928 2929 2930
					normalArray[ i ] 	 = nx;
					normalArray[ i + 1 ] = ny;
					normalArray[ i + 2 ] = nz;
2931

2932 2933 2934
					normalArray[ i + 3 ] = nx;
					normalArray[ i + 4 ] = ny;
					normalArray[ i + 5 ] = nz;
2935

2936 2937 2938
					normalArray[ i + 6 ] = nx;
					normalArray[ i + 7 ] = ny;
					normalArray[ i + 8 ] = nz;
2939

2940
				}
2941

2942
			}
2943

2944 2945 2946
			_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 );
2947

2948
		}
2949

2950
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );
2951

2952
		object.count = 0;
2953

2954
	};
2955

2956 2957
	this.renderBufferDirect = function ( camera, lights, fog, material, geometryGroup, object ) {

2958 2959
		if ( material.visible === false ) return;

2960
		var program, attributes, linewidth, primitives, a, attribute;
2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982

		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;

2983
			for ( var i = 0, il = offsets.length; i < il; ++ i ) {
2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047

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

3050 3051
		if ( material.visible === false ) return;

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

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

3056
		attributes = program.attributes;
3057

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

3062
		if ( geometryGroupHash !== _currentGeometryGroupHash ) {
A
alteredq 已提交
3063

3064 3065
			_currentGeometryGroupHash = geometryGroupHash;
			updateBuffers = true;
3066

3067
		}
3068

3069
		// vertices
3070

3071
		if ( !material.morphTargets && attributes.position >= 0 ) {
3072

3073
			if ( updateBuffers ) {
3074

3075 3076
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
				_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3077

3078
			}
3079

3080
		} else {
3081

3082
			if ( object.morphTargetBase ) {
3083

3084
				setupMorphTargets( material, geometryGroup, object );
3085

3086
			}
3087

3088
		}
3089

3090

3091
		if ( updateBuffers ) {
3092

3093
			// custom attributes
3094

3095
			// Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
3096

3097
			if ( geometryGroup.__webglCustomAttributesList ) {
3098

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

3101
					attribute = geometryGroup.__webglCustomAttributesList[ i ];
3102

3103
					if( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
3104

3105 3106
						_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
						_gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 );
3107

3108
					}
3109

3110
				}
3111

3112
			}
3113 3114


3115
			// colors
3116

3117
			if ( attributes.color >= 0 ) {
3118

3119 3120
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
3121

3122
			}
3123

3124
			// normals
3125

3126
			if ( attributes.normal >= 0 ) {
3127

3128 3129
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
				_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
3130

3131
			}
3132

3133
			// tangents
3134

3135
			if ( attributes.tangent >= 0 ) {
3136

3137 3138
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
				_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
3139

3140
			}
3141

3142
			// uvs
3143

3144
			if ( attributes.uv >= 0 ) {
3145

3146
				if ( geometryGroup.__webglUVBuffer ) {
3147

3148 3149
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
					_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
3150

3151
					_gl.enableVertexAttribArray( attributes.uv );
3152

3153
				} else {
3154

3155
					_gl.disableVertexAttribArray( attributes.uv );
3156 3157 3158 3159 3160

				}

			}

3161
			if ( attributes.uv2 >= 0 ) {
3162

3163
				if ( geometryGroup.__webglUV2Buffer ) {
3164

3165 3166
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
					_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
3167

3168
					_gl.enableVertexAttribArray( attributes.uv2 );
3169

3170
				} else {
3171

3172
					_gl.disableVertexAttribArray( attributes.uv2 );
3173 3174

				}
3175 3176

			}
3177

3178 3179 3180
			if ( material.skinning &&
				 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
				 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
A
alteredq 已提交
3181

3182 3183
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3184

3185 3186
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
				_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3187

3188 3189
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
				_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3190

3191 3192
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
				_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
3193

A
alteredq 已提交
3194
			}
3195

3196
		}
3197

3198
		// render mesh
3199

3200
		if ( object instanceof THREE.Mesh ) {
3201

3202
			// wireframe
3203

3204
			if ( material.wireframe ) {
3205

3206
				setLineWidth( material.wireframeLinewidth );
3207

3208 3209
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
3210

3211
			// triangles
3212

3213
			} else {
3214

3215 3216
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3217

3218
			}
3219

3220 3221 3222
			_this.info.render.calls ++;
			_this.info.render.vertices += geometryGroup.__webglFaceCount;
			_this.info.render.faces += geometryGroup.__webglFaceCount / 3;
3223

3224
		// render lines
3225

3226
		} else if ( object instanceof THREE.Line ) {
3227

3228
			primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
3229

3230
			setLineWidth( material.linewidth );
3231

3232
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
3233

3234
			_this.info.render.calls ++;
3235

3236
		// render particles
3237

3238
		} else if ( object instanceof THREE.ParticleSystem ) {
3239

3240
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
3241

3242
			_this.info.render.calls ++;
3243
			_this.info.render.points += geometryGroup.__webglParticleCount;
3244

3245
		// render ribbon
3246

3247
		} else if ( object instanceof THREE.Ribbon ) {
3248

3249
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
3250

3251
			_this.info.render.calls ++;
3252

3253
		}
3254

3255
	};
3256

3257
	function setupMorphTargets ( material, geometryGroup, object ) {
3258

3259
		// set base
3260

3261
		var attributes = material.program.attributes;
3262

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

3265 3266
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3267

3268
		} else if ( attributes.position >= 0 ) {
3269

3270 3271
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3272

3273
		}
3274

3275
		if ( object.morphTargetForcedOrder.length ) {
3276

3277
			// set forced order
3278

3279 3280 3281 3282 3283
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;

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

3285 3286 3287
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ order[ m ] ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );

A
alteredq 已提交
3288 3289 3290 3291 3292 3293 3294
				if ( material.morphNormals ) {

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

				}

3295 3296 3297
				object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ] ];

				m ++;
3298 3299
			}

3300 3301
		} else {

A
alteredq 已提交
3302
			// find the most influencing
3303

A
alteredq 已提交
3304
			var influence, activeInfluenceIndices = [];
3305 3306
			var influences = object.morphTargetInfluences;
			var i, il = influences.length;
3307

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

A
alteredq 已提交
3310 3311 3312 3313
				influence = influences[ i ];

				if ( influence > 0 ) {

3314
					activeInfluenceIndices.push( [ i, influence ] );
3315

I
ide user ide_gero3 已提交
3316
				}
A
alteredq 已提交
3317

I
ide user ide_gero3 已提交
3318
			}
A
alteredq 已提交
3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330

			if ( activeInfluenceIndices.length > material.numSupportedMorphTargets ) {

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

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

				activeInfluenceIndices.sort( numericalSort );

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

3331
				activeInfluenceIndices.push( [ 0, 0 ] );
A
alteredq 已提交
3332 3333 3334 3335

			};

			var influenceIndex, m = 0;
3336

3337
			while ( m < material.numSupportedMorphTargets ) {
3338

3339
				if ( activeInfluenceIndices[ m ] ) {
3340 3341 3342

					influenceIndex = activeInfluenceIndices[ m ][ 0 ];

A
alteredq 已提交
3343 3344 3345
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ influenceIndex ] );

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

A
alteredq 已提交
3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358
					if ( material.morphNormals ) {

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

					}

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

				} else {

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

A
alteredq 已提交
3360
					if ( material.morphNormals ) {
3361

A
alteredq 已提交
3362
						_gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 );
3363

3364
					}
3365

A
alteredq 已提交
3366 3367
					object.__webglMorphTargetInfluences[ m ] = 0;

3368
				}
A
alteredq 已提交
3369

3370
				m ++;
3371 3372 3373 3374 3375

			}

		}

3376
		// load updated influences uniform
3377

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

3380
			_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
3381

3382
		}
3383

3384
	};
3385

A
alteredq 已提交
3386
	// Sorting
3387

3388
	function painterSort ( a, b ) {
3389

3390
		return b.z - a.z;
3391

3392
	};
3393

3394
	function numericalSort ( a, b ) {
A
alteredq 已提交
3395

3396
		return b[ 1 ] - a[ 1 ];
A
alteredq 已提交
3397 3398 3399 3400

	};


3401
	// Rendering
3402

3403
	this.render = function ( scene, camera, renderTarget, forceClear ) {
3404

3405 3406 3407 3408 3409
		var i, il,

		webglObject, object,
		renderList,

3410
		lights = scene.__lights,
3411
		fog = scene.fog;
M
Mr.doob 已提交
3412

3413 3414
		// reset caching for this frame

3415
		_currentMaterialId = -1;
3416
		_lightsNeedUpdate = true;
3417

A
alteredq 已提交
3418
		// update scene graph
3419

3420
		if ( camera.parent === undefined ) {
3421

3422 3423
			console.warn( 'DEPRECATED: Camera hasn\'t been added to a Scene. Adding it...' );
			scene.add( camera );
3424

3425
		}
3426

3427
		if ( this.autoUpdateScene ) scene.updateMatrixWorld();
3428

A
alteredq 已提交
3429
		// update camera matrices and frustum
A
alteredq 已提交
3430

A
alteredq 已提交
3431 3432
		if ( ! camera._viewMatrixArray ) camera._viewMatrixArray = new Float32Array( 16 );
		if ( ! camera._projectionMatrixArray ) camera._projectionMatrixArray = new Float32Array( 16 );
A
alteredq 已提交
3433

3434
		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
A
alteredq 已提交
3435 3436 3437

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

3439
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
A
alteredq 已提交
3440
		_frustum.setFromMatrix( _projScreenMatrix );
3441

A
alteredq 已提交
3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456
		// 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 已提交
3457
		this.setRenderTarget( renderTarget );
3458

3459
		if ( this.autoClear || forceClear ) {
3460

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

3463
		}
M
Mr.doob 已提交
3464

3465
		// set matrices for regular objects (frustum culled)
3466

3467
		renderList = scene.__webglObjects;
3468

3469
		for ( i = 0, il = renderList.length; i < il; i ++ ) {
3470

3471
			webglObject = renderList[ i ];
3472
			object = webglObject.object;
3473

A
alteredq 已提交
3474 3475
			webglObject.render = false;

3476
			if ( object.visible ) {
3477

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

3480
					//object.matrixWorld.flattenToArray( object._objectMatrixArray );
3481

A
alteredq 已提交
3482
					setupMatrices( object, camera );
3483

3484
					unrollBufferMaterial( webglObject );
3485

3486
					webglObject.render = true;
3487

3488
					if ( this.sortObjects ) {
3489

3490
						if ( object.renderDepth ) {
3491

3492
							webglObject.z = object.renderDepth;
M
Mr.doob 已提交
3493

3494
						} else {
M
Mr.doob 已提交
3495

3496
							_vector3.copy( object.matrixWorld.getPosition() );
3497
							_projScreenMatrix.multiplyVector3( _vector3 );
3498

3499
							webglObject.z = _vector3.z;
3500

3501
						}
M
Mr.doob 已提交
3502

3503
					}
M
Mr.doob 已提交
3504

3505
				}
3506 3507

			}
3508 3509 3510

		}

3511
		if ( this.sortObjects ) {
M
Mr.doob 已提交
3512

3513
			renderList.sort( painterSort );
3514

3515
		}
3516

3517
		// set matrices for immediate objects
3518

3519
		renderList = scene.__webglObjectsImmediate;
3520

3521 3522 3523
		for ( i = 0, il = renderList.length; i < il; i ++ ) {

			webglObject = renderList[ i ];
3524
			object = webglObject.object;
3525

3526
			if ( object.visible ) {
3527

M
Mr.doob 已提交
3528 3529
				/*
				if ( object.matrixAutoUpdate ) {
3530

3531
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3532

3533
				}
M
Mr.doob 已提交
3534
				*/
M
Mr.doob 已提交
3535

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

3538
				unrollImmediateBufferMaterial( webglObject );
M
Mr.doob 已提交
3539

3540
			}
M
Mr.doob 已提交
3541

3542
		}
3543

3544
		if ( scene.overrideMaterial ) {
3545

3546 3547 3548 3549 3550 3551
			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 );
3552

3553 3554
			renderObjects( scene.__webglObjects, false, "", camera, lights, fog, true, material );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "", camera, lights, fog, false, material );
M
Mr.doob 已提交
3555

3556
		} else {
3557

3558
			// opaque pass (front-to-back order)
3559

3560
			this.setBlending( THREE.NormalBlending );
3561

3562 3563
			renderObjects( scene.__webglObjects, true, "opaque", camera, lights, fog, false );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "opaque", camera, lights, fog, false );
3564

3565
			// transparent pass (back-to-front order)
3566

3567 3568
			renderObjects( scene.__webglObjects, false, "transparent", camera, lights, fog, true );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "transparent", camera, lights, fog, true );
3569

3570
		}
3571

A
alteredq 已提交
3572
		// custom render plugins (post pass)
3573

A
alteredq 已提交
3574
		renderPlugins( this.renderPluginsPost, scene, camera );
3575 3576


3577
		// Generate mipmap if we're using any kind of mipmap filtering
3578

3579
		if ( renderTarget && renderTarget.generateMipmaps && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {
3580

3581
			updateRenderTargetMipmap( renderTarget );
3582

3583
		}
3584

3585 3586 3587
		// Ensure depth buffer writing is enabled so it can be cleared on next render

		this.setDepthTest( true );
3588
		this.setDepthWrite( true );
3589

3590
		// _gl.finish();
3591

3592
	};
3593

A
alteredq 已提交
3594 3595 3596 3597 3598 3599
	function renderPlugins( plugins, scene, camera ) {

		if ( ! plugins.length ) return;

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

3600 3601
			// reset state for plugin (to start from clean slate)

A
alteredq 已提交
3602
			_currentProgram = null;
3603
			_currentCamera = null;
3604

A
alteredq 已提交
3605 3606 3607
			_oldBlending = -1;
			_oldDepthTest = -1;
			_oldDepthWrite = -1;
3608 3609
			_oldDoubleSided = -1;
			_oldFlipSided = -1;
A
alteredq 已提交
3610 3611
			_currentGeometryGroupHash = -1;
			_currentMaterialId = -1;
3612

3613
			_lightsNeedUpdate = true;
A
alteredq 已提交
3614

A
alteredq 已提交
3615
			plugins[ i ].render( scene, camera, _currentWidth, _currentHeight );
A
alteredq 已提交
3616

3617 3618
			// reset state after plugin (anything could have changed)

A
alteredq 已提交
3619
			_currentProgram = null;
3620
			_currentCamera = null;
3621

A
alteredq 已提交
3622 3623 3624
			_oldBlending = -1;
			_oldDepthTest = -1;
			_oldDepthWrite = -1;
3625 3626
			_oldDoubleSided = -1;
			_oldFlipSided = -1;
A
alteredq 已提交
3627 3628
			_currentGeometryGroupHash = -1;
			_currentMaterialId = -1;
3629

3630
			_lightsNeedUpdate = true;
A
alteredq 已提交
3631 3632 3633 3634 3635

		}

	};

3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671
	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;

3672
					if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
3673

A
alteredq 已提交
3674
					_this.setDepthTest( material.depthTest );
3675
					_this.setDepthWrite( material.depthWrite );
3676 3677 3678 3679
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

A
alteredq 已提交
3680
				_this.setObjectFaces( object );
3681 3682 3683 3684 3685 3686 3687 3688 3689 3690

				if ( buffer instanceof THREE.BufferGeometry ) {

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

				} else {

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

				}
3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718

			}

		}

	};

	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;

3719
					if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
3720

A
alteredq 已提交
3721
					_this.setDepthTest( material.depthTest );
3722
					_this.setDepthWrite( material.depthWrite );
3723 3724 3725 3726
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

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

A
alteredq 已提交
3729
			}
3730

A
alteredq 已提交
3731
		}
3732

A
alteredq 已提交
3733
	};
3734

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

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

A
alteredq 已提交
3739
		_currentGeometryGroupHash = -1;
3740

A
alteredq 已提交
3741 3742 3743 3744 3745 3746 3747 3748 3749
		_this.setObjectFaces( object );

		if ( object.immediateRenderCallback ) {

			object.immediateRenderCallback( program, _gl, _frustum );

		} else {

			object.render( function( object ) { _this.renderBufferImmediate( object, program, material.shading ); } );
3750 3751 3752 3753 3754

		}

	};

3755
	function unrollImmediateBufferMaterial ( globject ) {
3756

3757 3758
		var object = globject.object,
			material = object.material;
3759

3760
		if ( material.transparent ) {
3761

3762 3763
			globject.transparent = material;
			globject.opaque = null;
3764

3765
		} else {
3766

3767 3768
			globject.opaque = material;
			globject.transparent = null;
3769

3770
		}
A
alteredq 已提交
3771

3772
	};
A
alteredq 已提交
3773

3774
	function unrollBufferMaterial ( globject ) {
A
alteredq 已提交
3775

3776 3777 3778
		var object = globject.object,
			buffer = globject.buffer,
			material, materialIndex, meshMaterial;
3779

3780
		meshMaterial = object.material;
3781

3782
		if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
M
Mr.doob 已提交
3783

3784
			materialIndex = buffer.materialIndex;
3785

3786
			if ( materialIndex >= 0 ) {
3787

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

3790
				if ( material.transparent ) {
M
Mr.doob 已提交
3791

3792 3793
					globject.transparent = material;
					globject.opaque = null;
3794

3795
				} else {
3796

3797 3798
					globject.opaque = material;
					globject.transparent = null;
3799

3800
				}
3801

3802
			}
3803

3804
		} else {
3805

3806
			material = meshMaterial;
3807

3808
			if ( material ) {
3809

3810
				if ( material.transparent ) {
M
Mr.doob 已提交
3811

3812 3813
					globject.transparent = material;
					globject.opaque = null;
A
alteredq 已提交
3814

3815
				} else {
3816

3817 3818
					globject.opaque = material;
					globject.transparent = null;
3819

3820
				}
3821

3822
			}
3823

3824
		}
3825

3826
	};
3827

3828
	// Geometry splitting
3829

3830
	function sortFacesByMaterial ( geometry ) {
3831

3832 3833 3834
		var f, fl, face, materialIndex, vertices,
			materialHash, groupHash,
			hash_map = {};
3835

3836
		var numMorphTargets = geometry.morphTargets.length;
3837
		var numMorphNormals = geometry.morphNormals.length;
3838

3839
		geometry.geometryGroups = {};
3840

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

3843 3844
			face = geometry.faces[ f ];
			materialIndex = face.materialIndex;
3845

3846
			materialHash = ( materialIndex !== undefined ) ? materialIndex : -1;
3847

3848
			if ( hash_map[ materialHash ] === undefined ) {
3849

3850
				hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 };
3851 3852 3853

			}

3854
			groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
3855

3856
			if ( geometry.geometryGroups[ groupHash ] === undefined ) {
3857

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

3860
			}
A
alteredq 已提交
3861

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

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

3866 3867
				hash_map[ materialHash ].counter += 1;
				groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
A
alteredq 已提交
3868

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

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

3873
				}
3874

3875
			}
3876

3877
			if ( face instanceof THREE.Face3 ) {
3878

3879
				geometry.geometryGroups[ groupHash ].faces3.push( f );
3880

3881
			} else {
3882

3883
				geometry.geometryGroups[ groupHash ].faces4.push( f );
3884

A
alteredq 已提交
3885
			}
3886

3887
			geometry.geometryGroups[ groupHash ].vertices += vertices;
3888

3889
		}
3890

3891
		geometry.geometryGroupsList = [];
3892

3893
		for ( var g in geometry.geometryGroups ) {
3894

3895
			geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;
3896

3897
			geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );
3898

3899
		}
3900

3901
	};
3902

3903 3904 3905 3906 3907 3908 3909 3910 3911
	// Objects refresh

	this.initWebGLObjects = function ( scene ) {

		if ( !scene.__webglObjects ) {

			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
			scene.__webglSprites = [];
3912
			scene.__webglFlares = [];
3913 3914

		}
3915

3916
		while ( scene.__objectsAdded.length ) {
3917

3918 3919
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
3920

3921
		}
A
alteredq 已提交
3922

3923
		while ( scene.__objectsRemoved.length ) {
3924

3925 3926
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
3927

3928
		}
3929

3930
		// update must be called after objects adding / removal
3931

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

3934
			updateObject( scene.__webglObjects[ o ].object );
M
Mr.doob 已提交
3935 3936 3937 3938 3939

		}

	};

3940
	// Objects adding
M
Mr.doob 已提交
3941

3942
	function addObject ( object, scene ) {
A
alteredq 已提交
3943

3944
		var g, geometry, geometryGroup;
3945

3946
		if ( ! object.__webglInit ) {
M
Mr.doob 已提交
3947

3948
			object.__webglInit = true;
M
Mr.doob 已提交
3949

3950
			object._modelViewMatrix = new THREE.Matrix4();
3951
			object._normalMatrix = new THREE.Matrix3();
M
Mr.doob 已提交
3952

3953 3954 3955
			//object._normalMatrixArray = new Float32Array( 9 );
			//object._modelViewMatrixArray = new Float32Array( 16 );
			//object._objectMatrixArray = new Float32Array( 16 );
M
Mr.doob 已提交
3956

3957
			//object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3958

3959
			if ( object instanceof THREE.Mesh ) {
M
Mr.doob 已提交
3960

3961
				geometry = object.geometry;
M
Mr.doob 已提交
3962

3963
				if ( geometry instanceof THREE.Geometry ) {
M
Mr.doob 已提交
3964

3965
					if ( geometry.geometryGroups === undefined ) {
M
Mr.doob 已提交
3966

3967
						sortFacesByMaterial( geometry );
M
Mr.doob 已提交
3968

3969 3970 3971
					}

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

3973
					for ( g in geometry.geometryGroups ) {
M
Mr.doob 已提交
3974

3975
						geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
3976

3977
						// initialise VBO on the first access
M
Mr.doob 已提交
3978

3979
						if ( ! geometryGroup.__webglVertexBuffer ) {
3980

3981 3982
							createMeshBuffers( geometryGroup );
							initMeshBuffers( geometryGroup, object );
M
Mr.doob 已提交
3983

3984
							geometry.verticesNeedUpdate = true;
3985
							geometry.morphTargetsNeedUpdate = true;
M
Mr.doob 已提交
3986
							geometry.elementsNeedUpdate = true;
M
Mr.doob 已提交
3987
							geometry.uvsNeedUpdate = true;
M
Mr.doob 已提交
3988
							geometry.normalsNeedUpdate = true;
M
Mr.doob 已提交
3989
							geometry.tangetsNeedUpdate = true;
M
Mr.doob 已提交
3990
							geometry.colorsNeedUpdate = true;
3991 3992

						}
M
Mr.doob 已提交
3993

3994
					}
M
Mr.doob 已提交
3995

3996
				}
M
Mr.doob 已提交
3997

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

4000
				geometry = object.geometry;
M
Mr.doob 已提交
4001

4002
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
4003

4004 4005
					createRibbonBuffers( geometry );
					initRibbonBuffers( geometry );
M
Mr.doob 已提交
4006

4007
					geometry.verticesNeedUpdate = true;
M
Mr.doob 已提交
4008
					geometry.colorsNeedUpdate = true;
M
Mr.doob 已提交
4009

4010
				}
M
Mr.doob 已提交
4011

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

4014
				geometry = object.geometry;
M
Mr.doob 已提交
4015

4016
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
4017

4018 4019
					createLineBuffers( geometry );
					initLineBuffers( geometry, object );
M
Mr.doob 已提交
4020

4021
					geometry.verticesNeedUpdate = true;
M
Mr.doob 已提交
4022
					geometry.colorsNeedUpdate = true;
4023

4024
				}
4025

4026
			} else if ( object instanceof THREE.ParticleSystem ) {
4027

4028
				geometry = object.geometry;
4029

4030
				if ( ! geometry.__webglVertexBuffer ) {
4031

4032 4033
					createParticleBuffers( geometry );
					initParticleBuffers( geometry, object );
4034

4035
					geometry.verticesNeedUpdate = true;
M
Mr.doob 已提交
4036
					geometry.colorsNeedUpdate = true;
4037

4038
				}
4039

4040
			}
4041

4042
		}
4043

4044
		if ( ! object.__webglActive ) {
4045

4046
			if ( object instanceof THREE.Mesh ) {
4047

4048
				geometry = object.geometry;
4049

4050 4051 4052 4053 4054 4055 4056 4057 4058
				if ( geometry instanceof THREE.BufferGeometry ) {

					addBuffer( scene.__webglObjects, geometry, object );

				} else {

					for ( g in geometry.geometryGroups ) {

						geometryGroup = geometry.geometryGroups[ g ];
4059

4060
						addBuffer( scene.__webglObjects, geometryGroup, object );
4061

4062
					}
4063

4064
				}
4065

4066 4067 4068
			} else if ( object instanceof THREE.Ribbon ||
						object instanceof THREE.Line ||
						object instanceof THREE.ParticleSystem ) {
4069

4070 4071
				geometry = object.geometry;
				addBuffer( scene.__webglObjects, geometry, object );
4072

4073
			} else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
4074

4075
				addBufferImmediate( scene.__webglObjectsImmediate, object );
4076

4077
			} else if ( object instanceof THREE.Sprite ) {
4078

4079
				scene.__webglSprites.push( object );
4080

4081 4082 4083 4084
			} else if ( object instanceof THREE.LensFlare ) {

				scene.__webglFlares.push( object );

4085 4086
			}

4087
			object.__webglActive = true;
4088

4089
		}
4090

4091
	};
4092

4093
	function addBuffer ( objlist, buffer, object ) {
4094

4095 4096 4097 4098 4099 4100 4101 4102
		objlist.push(
			{
				buffer: buffer,
				object: object,
				opaque: null,
				transparent: null
			}
		);
4103

4104
	};
4105

4106
	function addBufferImmediate ( objlist, object ) {
4107

4108 4109 4110 4111 4112
		objlist.push(
			{
				object: object,
				opaque: null,
				transparent: null
4113
			}
4114
		);
4115

4116
	};
4117

4118
	// Objects updates
4119

4120
	function updateObject ( object ) {
4121

4122 4123
		var geometry = object.geometry,
			geometryGroup, customAttributesDirty, material;
4124

4125
		if ( object instanceof THREE.Mesh ) {
4126

4127 4128
			if ( geometry instanceof THREE.BufferGeometry ) {

4129
				/*
M
Mr.doob 已提交
4130
				if ( geometry.verticesNeedUpdate || geometry.elementsNeedUpdate ||
M
Mr.doob 已提交
4131
					 geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
M
Mr.doob 已提交
4132
					 geometry.colorsNeedUpdate  ) {
4133

4134 4135
					// TODO
					// set buffers from typed arrays
4136

4137
				}
4138
				*/
4139

4140
				geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4141
				geometry.elementsNeedUpdate = false;
M
Mr.doob 已提交
4142
				geometry.uvsNeedUpdate = false;
M
Mr.doob 已提交
4143
				geometry.normalsNeedUpdate = false;
M
Mr.doob 已提交
4144
				geometry.colorsNeedUpdate = false;
4145

4146
			} else {
4147

4148
				// check all geometry groups
4149

4150 4151 4152 4153 4154 4155 4156 4157
				for( var i = 0, il = geometry.geometryGroupsList.length; i < il; i ++ ) {

					geometryGroup = geometry.geometryGroupsList[ i ];

					material = getBufferMaterial( object, geometryGroup );

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

4158
					if ( geometry.verticesNeedUpdate || geometry.morphTargetsNeedUpdate || geometry.elementsNeedUpdate ||
M
Mr.doob 已提交
4159
						 geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
M
Mr.doob 已提交
4160
						 geometry.colorsNeedUpdate || geometry.tangetsNeedUpdate || customAttributesDirty ) {
4161 4162 4163 4164

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

					}
4165

4166
				}
M
Mr.doob 已提交
4167

4168
				geometry.verticesNeedUpdate = false;
4169
				geometry.morphTargetsNeedUpdate = false;
M
Mr.doob 已提交
4170
				geometry.elementsNeedUpdate = false;
M
Mr.doob 已提交
4171
				geometry.uvsNeedUpdate = false;
M
Mr.doob 已提交
4172
				geometry.normalsNeedUpdate = false;
M
Mr.doob 已提交
4173
				geometry.colorsNeedUpdate = false;
M
Mr.doob 已提交
4174
				geometry.tangetsNeedUpdate = false;
4175

4176
				material.attributes && clearCustomAttributes( material );
4177

4178
			}
4179

4180
		} else if ( object instanceof THREE.Ribbon ) {
4181

M
Mr.doob 已提交
4182
			if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate ) {
4183

4184
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
4185

4186
			}
4187

4188
			geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4189
			geometry.colorsNeedUpdate = false;
4190

4191
		} else if ( object instanceof THREE.Line ) {
4192

4193
			material = getBufferMaterial( object, geometryGroup );
A
alteredq 已提交
4194

4195
			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
A
alteredq 已提交
4196

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

4199
				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
4200

4201
			}
4202

4203
			geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4204
			geometry.colorsNeedUpdate = false;
4205

4206
			material.attributes && clearCustomAttributes( material );
4207

4208
		} else if ( object instanceof THREE.ParticleSystem ) {
4209

4210
			material = getBufferMaterial( object, geometryGroup );
4211

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

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

4216
				setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
4217

4218
			}
4219

4220
			geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4221
			geometry.colorsNeedUpdate = false;
4222

4223
			material.attributes && clearCustomAttributes( material );
4224

4225
		}
4226

4227
	};
4228

4229
	// Objects updates - custom attributes check
4230

4231
	function areCustomAttributesDirty ( material ) {
4232

4233
		for ( var a in material.attributes ) {
4234

4235
			if ( material.attributes[ a ].needsUpdate ) return true;
4236

4237
		}
4238

4239
		return false;
4240

4241
	};
4242

4243 4244 4245
	function clearCustomAttributes ( material ) {

		for ( var a in material.attributes ) {
4246

4247
			material.attributes[ a ].needsUpdate = false;
4248

4249
		}
4250

4251
	};
4252

4253
	// Objects removal
4254

4255
	function removeObject ( object, scene ) {
4256

4257 4258 4259 4260
		if ( object instanceof THREE.Mesh  ||
			 object instanceof THREE.ParticleSystem ||
			 object instanceof THREE.Ribbon ||
			 object instanceof THREE.Line ) {
4261

4262
			removeInstances( scene.__webglObjects, object );
4263

4264
		} else if ( object instanceof THREE.Sprite ) {
4265

4266
			removeInstancesDirect( scene.__webglSprites, object );
4267

4268 4269 4270 4271
		} else if ( object instanceof THREE.LensFlare ) {

			removeInstancesDirect( scene.__webglFlares, object );

4272
		} else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
4273

4274
			removeInstances( scene.__webglObjectsImmediate, object );
4275

4276
		}
4277

4278
		object.__webglActive = false;
4279

4280
	};
4281

4282
	function removeInstances ( objlist, object ) {
4283

4284
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4285

4286
			if ( objlist[ o ].object === object ) {
4287

4288
				objlist.splice( o, 1 );
4289

4290
			}
4291

4292
		}
4293

4294
	};
4295

4296
	function removeInstancesDirect ( objlist, object ) {
4297

4298
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4299

4300
			if ( objlist[ o ] === object ) {
4301

4302
				objlist.splice( o, 1 );
4303

4304
			}
4305

4306
		}
4307

4308
	};
4309

4310
	// Materials
4311

4312
	this.initMaterial = function ( material, lights, fog, object ) {
4313

4314
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
4315

4316
		if ( material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
4317

4318
			shaderID = 'depth';
4319

4320
		} else if ( material instanceof THREE.MeshNormalMaterial ) {
4321

4322
			shaderID = 'normal';
M
Mr.doob 已提交
4323

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

4326
			shaderID = 'basic';
M
Mr.doob 已提交
4327

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

4330
			shaderID = 'lambert';
M
Mr.doob 已提交
4331

4332
		} else if ( material instanceof THREE.MeshPhongMaterial ) {
4333

4334
			shaderID = 'phong';
4335

4336
		} else if ( material instanceof THREE.LineBasicMaterial ) {
4337

4338
			shaderID = 'basic';
4339

4340
		} else if ( material instanceof THREE.ParticleBasicMaterial ) {
4341

4342
			shaderID = 'particle_basic';
4343 4344 4345

		}

4346
		if ( shaderID ) {
4347

4348
			setMaterialShaders( material, THREE.ShaderLib[ shaderID ] );
4349

4350
		}
4351

4352 4353
		// heuristics to create shader parameters according to lights in the scene
		// (not to blow over maxLights budget)
4354

4355
		maxLightCount = allocateLights( lights );
4356

4357
		maxShadows = allocateShadows( lights );
4358

4359
		maxBones = allocateBones( object );
4360

4361
		parameters = {
4362

A
alteredq 已提交
4363 4364 4365 4366
			map: !!material.map,
			envMap: !!material.envMap,
			lightMap: !!material.lightMap,

4367
			vertexColors: material.vertexColors,
A
alteredq 已提交
4368 4369 4370 4371

			fog: fog,
			useFog: material.fog,

4372
			sizeAttenuation: material.sizeAttenuation,
A
alteredq 已提交
4373

4374
			skinning: material.skinning,
A
alteredq 已提交
4375 4376
			maxBones: maxBones,

4377
			morphTargets: material.morphTargets,
A
alteredq 已提交
4378
			morphNormals: material.morphNormals,
4379
			maxMorphTargets: this.maxMorphTargets,
A
alteredq 已提交
4380
			maxMorphNormals: this.maxMorphNormals,
A
alteredq 已提交
4381 4382 4383 4384 4385 4386

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

			maxShadows: maxShadows,
4387 4388
			shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
			shadowMapSoft: this.shadowMapSoft,
A
alteredq 已提交
4389 4390
			shadowMapDebug: this.shadowMapDebug,
			shadowMapCascade: this.shadowMapCascade,
A
alteredq 已提交
4391

4392 4393
			alphaTest: material.alphaTest,
			metal: material.metal,
4394
			perPixel: material.perPixel,
4395
			wrapAround: material.wrapAround,
4396
			doubleSided: object && object.doubleSided
4397

4398
		};
M
Mr.doob 已提交
4399

4400
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
4401

4402
		var attributes = material.program.attributes;
4403

4404 4405 4406 4407
		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 );
4408

4409 4410 4411
		if ( material.skinning &&
			 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
M
Mr.doob 已提交
4412

4413 4414 4415 4416
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
M
Mr.doob 已提交
4417 4418

		}
4419

4420
		if ( material.attributes ) {
A
alteredq 已提交
4421

4422
			for ( a in material.attributes ) {
M
Mr.doob 已提交
4423

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

4426
			}
M
Mr.doob 已提交
4427

4428
		}
M
Mr.doob 已提交
4429

4430
		if ( material.morphTargets ) {
M
Mr.doob 已提交
4431

4432
			material.numSupportedMorphTargets = 0;
4433

4434
			var id, base = "morphTarget";
4435

4436
			for ( i = 0; i < this.maxMorphTargets; i ++ ) {
4437

4438
				id = base + i;
M
Mr.doob 已提交
4439

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

4442 4443
					_gl.enableVertexAttribArray( attributes[ id ] );
					material.numSupportedMorphTargets ++;
4444

4445
				}
4446

4447
			}
4448

4449
		}
4450

A
alteredq 已提交
4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471
		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 ++;

				}

			}

		}

4472
		material.uniformsList = [];
4473

4474
		for ( u in material.uniforms ) {
4475

4476
			material.uniformsList.push( [ material.uniforms[ u ], u ] );
4477

4478
		}
M
Mr.doob 已提交
4479

4480
	};
M
Mr.doob 已提交
4481

4482
	function setMaterialShaders( material, shaders ) {
M
Mr.doob 已提交
4483

4484 4485 4486
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
M
Mr.doob 已提交
4487

4488
	};
M
Mr.doob 已提交
4489

4490
	function setProgram( camera, lights, fog, material, object ) {
4491

A
alteredq 已提交
4492
		if ( ! material.program || material.needsUpdate ) {
4493

4494
			_this.initMaterial( material, lights, fog, object );
A
alteredq 已提交
4495
			material.needsUpdate = false;
4496

4497
		}
4498

4499
		if ( material.morphTargets ) {
4500

4501
			if ( ! object.__webglMorphTargetInfluences ) {
4502

4503
				object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );
4504

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

4507
					object.__webglMorphTargetInfluences[ i ] = 0;
4508

4509
				}
4510

4511
			}
4512

4513
		}
4514

4515
		var refreshMaterial = false;
4516

4517 4518 4519
		var program = material.program,
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
4520

4521
		if ( program !== _currentProgram ) {
4522

4523 4524
			_gl.useProgram( program );
			_currentProgram = program;
4525

4526
			refreshMaterial = true;
4527

4528
		}
4529

4530
		if ( material.id !== _currentMaterialId ) {
4531

4532 4533
			_currentMaterialId = material.id;
			refreshMaterial = true;
4534

4535
		}
4536

4537
		if ( refreshMaterial || camera !== _currentCamera ) {
4538

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

4541 4542 4543 4544 4545 4546
			if ( camera !== _currentCamera ) _currentCamera = camera;

		}

		if ( refreshMaterial ) {

4547
			// refresh uniforms common to several materials
4548

4549
			if ( fog && material.fog ) {
4550

4551
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
4552

4553
			}
M
Mr.doob 已提交
4554

4555 4556 4557
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material.lights ) {
4558

4559 4560 4561 4562 4563 4564 4565
				if ( _lightsNeedUpdate ) {

					setupLights( program, lights );
					_lightsNeedUpdate = false;

				}

4566
				refreshUniformsLights( m_uniforms, _lights );
4567

4568
			}
M
Mr.doob 已提交
4569

4570 4571 4572
			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
4573

4574
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
4575 4576 4577

			}

4578
			// refresh single material specific uniforms
M
Mr.doob 已提交
4579

4580
			if ( material instanceof THREE.LineBasicMaterial ) {
4581

4582
				refreshUniformsLine( m_uniforms, material );
M
Mr.doob 已提交
4583

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

4586
				refreshUniformsParticle( m_uniforms, material );
M
Mr.doob 已提交
4587

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

4590
				refreshUniformsPhong( m_uniforms, material );
M
Mr.doob 已提交
4591

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

4594
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
4595

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

4598 4599 4600
				m_uniforms.mNear.value = camera.near;
				m_uniforms.mFar.value = camera.far;
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4601

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

4604
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4605

4606
			}
M
Mr.doob 已提交
4607

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

4610
				refreshUniformsShadow( m_uniforms, lights );
M
Mr.doob 已提交
4611

4612
			}
M
Mr.doob 已提交
4613

4614
			// load common uniforms
M
Mr.doob 已提交
4615

4616
			loadUniformsGeneric( program, material.uniformsList );
M
Mr.doob 已提交
4617

4618 4619
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)
4620

4621 4622 4623
			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
				 material.envMap ) {
4624

4625
				if ( p_uniforms.cameraPosition !== null ) {
4626

4627 4628
					var position = camera.matrixWorld.getPosition();
					_gl.uniform3f( p_uniforms.cameraPosition, position.x, position.y, position.z );
4629

4630
				}
4631 4632 4633

			}

4634 4635 4636 4637
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {
4638

4639
				if ( p_uniforms.viewMatrix !== null ) {
4640

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

4643
				}
4644

4645
			}
M
Mr.doob 已提交
4646

4647
			if ( material.skinning ) {
4648

A
alteredq 已提交
4649
				_gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.boneMatrices );
4650

4651
			}
4652

4653
		}
M
Mr.doob 已提交
4654

4655
		loadUniformsMatrices( p_uniforms, object );
M
Mr.doob 已提交
4656

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

4659
			_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object.matrixWorld.elements );
4660

4661
		}
4662

4663
		return program;
4664

4665
	};
4666

4667
	// Uniforms (refresh uniforms objects)
A
alteredq 已提交
4668

4669
	function refreshUniformsCommon ( uniforms, material ) {
4670

4671
		uniforms.opacity.value = material.opacity;
4672

4673
		if ( _this.gammaInput ) {
4674

4675
			uniforms.diffuse.value.copyGammaToLinear( material.color );
4676

4677
		} else {
4678

4679
			uniforms.diffuse.value = material.color;
4680

4681
		}
4682

4683
		uniforms.map.texture = material.map;
4684

4685
		if ( material.map ) {
4686

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

4689
		}
M
Mr.doob 已提交
4690

4691
		uniforms.lightMap.texture = material.lightMap;
4692

4693 4694
		uniforms.envMap.texture = material.envMap;
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
4695

4696
		if ( _this.gammaInput ) {
4697

4698 4699
			//uniforms.reflectivity.value = material.reflectivity * material.reflectivity;
			uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
4700

4701
		} else {
4702

4703
			uniforms.reflectivity.value = material.reflectivity;
4704

4705
		}
4706

4707 4708 4709
		uniforms.refractionRatio.value = material.refractionRatio;
		uniforms.combine.value = material.combine;
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
M
Mr.doob 已提交
4710

4711
	};
M
Mr.doob 已提交
4712

4713
	function refreshUniformsLine ( uniforms, material ) {
M
Mr.doob 已提交
4714

4715 4716
		uniforms.diffuse.value = material.color;
		uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4717

4718
	};
M
Mr.doob 已提交
4719

4720
	function refreshUniformsParticle ( uniforms, material ) {
4721

4722 4723 4724 4725
		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.
4726

4727
		uniforms.map.texture = material.map;
4728

4729
	};
4730

4731
	function refreshUniformsFog ( uniforms, fog ) {
4732

4733
		uniforms.fogColor.value = fog.color;
4734

4735
		if ( fog instanceof THREE.Fog ) {
4736

4737 4738
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
4739

4740
		} else if ( fog instanceof THREE.FogExp2 ) {
M
Mikael Emtinger 已提交
4741

4742
			uniforms.fogDensity.value = fog.density;
M
Mikael Emtinger 已提交
4743

4744
		}
M
Mikael Emtinger 已提交
4745

4746
	};
M
Mikael Emtinger 已提交
4747

4748
	function refreshUniformsPhong ( uniforms, material ) {
M
Mikael Emtinger 已提交
4749

4750
		uniforms.shininess.value = material.shininess;
4751

4752
		if ( _this.gammaInput ) {
M
Mikael Emtinger 已提交
4753

4754
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
4755
			uniforms.emissive.value.copyGammaToLinear( material.emissive );
4756
			uniforms.specular.value.copyGammaToLinear( material.specular );
4757

4758
		} else {
4759

4760
			uniforms.ambient.value = material.ambient;
4761
			uniforms.emissive.value = material.emissive;
4762
			uniforms.specular.value = material.specular;
4763

4764
		}
4765

4766 4767 4768 4769 4770 4771
		if ( material.wrapAround ) {

			uniforms.wrapRGB.value.copy( material.wrapRGB );

		}

4772
	};
4773

4774
	function refreshUniformsLambert ( uniforms, material ) {
4775

4776
		if ( _this.gammaInput ) {
4777

4778
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
4779
			uniforms.emissive.value.copyGammaToLinear( material.emissive );
M
Mr.doob 已提交
4780

4781
		} else {
4782

4783
			uniforms.ambient.value = material.ambient;
4784
			uniforms.emissive.value = material.emissive;
4785

4786
		}
4787

4788 4789 4790 4791 4792 4793
		if ( material.wrapAround ) {

			uniforms.wrapRGB.value.copy( material.wrapRGB );

		}

4794
	};
4795

4796
	function refreshUniformsLights ( uniforms, lights ) {
4797

4798
		uniforms.ambientLightColor.value = lights.ambient;
4799

4800 4801
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
4802

4803 4804 4805
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
		uniforms.pointLightDistance.value = lights.point.distances;
4806

A
alteredq 已提交
4807 4808 4809 4810 4811 4812 4813
		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;

4814
	};
4815

4816
	function refreshUniformsShadow ( uniforms, lights ) {
M
Mr.doob 已提交
4817

4818
		if ( uniforms.shadowMatrix ) {
4819

4820
			var j = 0;
4821

4822
			for ( var i = 0, il = lights.length; i < il; i ++ ) {
4823

4824
				var light = lights[ i ];
4825

A
alteredq 已提交
4826 4827
				if ( ! light.castShadow ) continue;

4828
				if ( light instanceof THREE.SpotLight || ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) ) {
4829 4830 4831

					uniforms.shadowMap.texture[ j ] = light.shadowMap;
					uniforms.shadowMapSize.value[ j ] = light.shadowMapSize;
4832

4833 4834 4835 4836 4837 4838 4839 4840 4841 4842
					uniforms.shadowMatrix.value[ j ] = light.shadowMatrix;

					uniforms.shadowDarkness.value[ j ] = light.shadowDarkness;
					uniforms.shadowBias.value[ j ] = light.shadowBias;

					j ++;

				}

			}
4843

4844 4845
		}

4846
	};
4847

4848
	// Uniforms (load to GPU)
4849

4850
	function loadUniformsMatrices ( uniforms, object ) {
4851

4852
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrix.elements );
4853

4854
		if ( uniforms.normalMatrix ) {
4855

4856
			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrix.elements );
4857

4858
		}
4859

4860
	};
4861

4862
	function loadUniformsGeneric ( program, uniforms ) {
4863

4864
		var uniform, value, type, location, texture, i, il, j, jl, offset;
4865

M
Mr.doob 已提交
4866
		for ( j = 0, jl = uniforms.length; j < jl; j ++ ) {
4867

4868 4869
			location = program.uniforms[ uniforms[ j ][ 1 ] ];
			if ( !location ) continue;
4870

4871
			uniform = uniforms[ j ][ 0 ];
4872

4873 4874
			type = uniform.type;
			value = uniform.value;
4875

M
Mr.doob 已提交
4876
			switch ( type ) {
4877

M
Mr.doob 已提交
4878
				case "i": // single integer
4879

M
Mr.doob 已提交
4880
					_gl.uniform1i( location, value );
4881

M
Mr.doob 已提交
4882
					break;
4883

M
Mr.doob 已提交
4884
				case "f": // single float
4885

M
Mr.doob 已提交
4886
					_gl.uniform1f( location, value );
4887

M
Mr.doob 已提交
4888
					break;
4889

M
Mr.doob 已提交
4890
				case "v2": // single THREE.Vector2
4891

M
Mr.doob 已提交
4892
					_gl.uniform2f( location, value.x, value.y );
4893

M
Mr.doob 已提交
4894
					break;
4895

M
Mr.doob 已提交
4896
				case "v3": // single THREE.Vector3
4897

M
Mr.doob 已提交
4898
					_gl.uniform3f( location, value.x, value.y, value.z );
4899

M
Mr.doob 已提交
4900
					break;
4901

M
Mr.doob 已提交
4902
				case "v4": // single THREE.Vector4
4903

M
Mr.doob 已提交
4904
					_gl.uniform4f( location, value.x, value.y, value.z, value.w );
4905

M
Mr.doob 已提交
4906
					break;
4907

M
Mr.doob 已提交
4908
				case "c": // single THREE.Color
4909

M
Mr.doob 已提交
4910
					_gl.uniform3f( location, value.r, value.g, value.b );
4911

M
Mr.doob 已提交
4912
					break;
4913

M
Mr.doob 已提交
4914
				case "fv1": // flat array of floats (JS or typed array)
4915

M
Mr.doob 已提交
4916
					_gl.uniform1fv( location, value );
4917

M
Mr.doob 已提交
4918
					break;
4919

M
Mr.doob 已提交
4920
				case "fv": // flat array of floats with 3 x N size (JS or typed array)
4921

M
Mr.doob 已提交
4922
					_gl.uniform3fv( location, value );
4923

M
Mr.doob 已提交
4924
					break;
4925

M
Mr.doob 已提交
4926
				case "v2v": // array of THREE.Vector2
4927

M
Mr.doob 已提交
4928
					if ( ! uniform._array ) {
M
Mr.doob 已提交
4929

M
Mr.doob 已提交
4930
						uniform._array = new Float32Array( 2 * value.length );
A
alteredq 已提交
4931

M
Mr.doob 已提交
4932
					}
A
alteredq 已提交
4933

M
Mr.doob 已提交
4934
					for ( i = 0, il = value.length; i < il; i ++ ) {
4935

M
Mr.doob 已提交
4936
						offset = i * 2;
4937

M
Mr.doob 已提交
4938 4939
						uniform._array[ offset ] 	 = value[ i ].x;
						uniform._array[ offset + 1 ] = value[ i ].y;
4940

M
Mr.doob 已提交
4941
					}
4942

M
Mr.doob 已提交
4943
					_gl.uniform2fv( location, uniform._array );
4944

M
Mr.doob 已提交
4945
					break;
4946

M
Mr.doob 已提交
4947
				case "v3v": // array of THREE.Vector3
4948

M
Mr.doob 已提交
4949
					if ( ! uniform._array ) {
4950

M
Mr.doob 已提交
4951
						uniform._array = new Float32Array( 3 * value.length );
4952

M
Mr.doob 已提交
4953
					}
4954

M
Mr.doob 已提交
4955
					for ( i = 0, il = value.length; i < il; i ++ ) {
4956

M
Mr.doob 已提交
4957
						offset = i * 3;
4958

M
Mr.doob 已提交
4959 4960 4961
						uniform._array[ offset ] 	 = value[ i ].x;
						uniform._array[ offset + 1 ] = value[ i ].y;
						uniform._array[ offset + 2 ] = value[ i ].z;
4962

M
Mr.doob 已提交
4963
					}
M
Mr.doob 已提交
4964

M
Mr.doob 已提交
4965
					_gl.uniform3fv( location, uniform._array );
A
alteredq 已提交
4966

M
Mr.doob 已提交
4967
					break;
4968

M
Mr.doob 已提交
4969
				case "v4v": // array of THREE.Vector4
4970

M
Mr.doob 已提交
4971
					if ( ! uniform._array ) {
4972

M
Mr.doob 已提交
4973
						uniform._array = new Float32Array( 4 * value.length );
A
alteredq 已提交
4974

M
Mr.doob 已提交
4975
					}
4976

M
Mr.doob 已提交
4977
					for ( i = 0, il = value.length; i < il; i ++ ) {
A
alteredq 已提交
4978

M
Mr.doob 已提交
4979
						offset = i * 4;
M
Mr.doob 已提交
4980

M
Mr.doob 已提交
4981 4982 4983 4984
						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 已提交
4985

M
Mr.doob 已提交
4986
					}
M
Mr.doob 已提交
4987

M
Mr.doob 已提交
4988
					_gl.uniform4fv( location, uniform._array );
A
alteredq 已提交
4989

M
Mr.doob 已提交
4990
					break;
M
Mr.doob 已提交
4991

M
Mr.doob 已提交
4992
				case "m4": // single THREE.Matrix4
M
Mr.doob 已提交
4993

M
Mr.doob 已提交
4994
					if ( ! uniform._array ) {
A
alteredq 已提交
4995

M
Mr.doob 已提交
4996
						uniform._array = new Float32Array( 16 );
4997

M
Mr.doob 已提交
4998
					}
A
alteredq 已提交
4999

M
Mr.doob 已提交
5000 5001
					value.flattenToArray( uniform._array );
					_gl.uniformMatrix4fv( location, false, uniform._array );
A
alteredq 已提交
5002

M
Mr.doob 已提交
5003
					break;
A
alteredq 已提交
5004

M
Mr.doob 已提交
5005
				case "m4v": // array of THREE.Matrix4
A
alteredq 已提交
5006

M
Mr.doob 已提交
5007
					if ( ! uniform._array ) {
M
Mr.doob 已提交
5008

M
Mr.doob 已提交
5009
						uniform._array = new Float32Array( 16 * value.length );
5010

M
Mr.doob 已提交
5011
					}
5012

M
Mr.doob 已提交
5013
					for ( i = 0, il = value.length; i < il; i ++ ) {
5014

M
Mr.doob 已提交
5015
						value[ i ].flattenToArrayOffset( uniform._array, i * 16 );
M
Mr.doob 已提交
5016

M
Mr.doob 已提交
5017
					}
M
Mr.doob 已提交
5018

M
Mr.doob 已提交
5019
					_gl.uniformMatrix4fv( location, false, uniform._array );
M
Mr.doob 已提交
5020

M
Mr.doob 已提交
5021
					break;
A
alteredq 已提交
5022

M
Mr.doob 已提交
5023 5024 5025 5026 5027
				case "t": // single THREE.Texture (2d or cube)

					_gl.uniform1i( location, value );

					texture = uniform.texture;
5028

M
Mr.doob 已提交
5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041
					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 );
5042 5043

					}
A
alteredq 已提交
5044

M
Mr.doob 已提交
5045
					break;
A
alteredq 已提交
5046

M
Mr.doob 已提交
5047
				case "tv": // array of THREE.Texture (2d)
A
alteredq 已提交
5048

M
Mr.doob 已提交
5049
					if ( ! uniform._array ) {
5050

M
Mr.doob 已提交
5051
						uniform._array = [];
5052

M
Mr.doob 已提交
5053
						for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
M
Mr.doob 已提交
5054

M
Mr.doob 已提交
5055
							uniform._array[ i ] = value + i;
M
Mr.doob 已提交
5056

M
Mr.doob 已提交
5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073
						}

					}

					_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 已提交
5074

M
Mr.doob 已提交
5075
			}
M
Mr.doob 已提交
5076

M
Mr.doob 已提交
5077
		}
M
Mr.doob 已提交
5078

5079
	};
M
Mr.doob 已提交
5080

A
alteredq 已提交
5081
	function setupMatrices ( object, camera ) {
M
Mr.doob 已提交
5082

5083
		object._modelViewMatrix.multiply( camera.matrixWorldInverse, object.matrixWorld);
M
Mr.doob 已提交
5084

5085
		object._normalMatrix.getInverse( object._modelViewMatrix );
5086
		object._normalMatrix.transpose();
M
Mr.doob 已提交
5087

A
alteredq 已提交
5088
	};
M
Mr.doob 已提交
5089

5090
	function setupLights ( program, lights ) {
M
Mr.doob 已提交
5091

5092 5093 5094
		var l, ll, light, n,
		r = 0, g = 0, b = 0,
		color, position, intensity, distance,
M
Mr.doob 已提交
5095

5096
		zlights = _lights,
A
alteredq 已提交
5097

5098 5099
		dcolors = zlights.directional.colors,
		dpositions = zlights.directional.positions,
A
alteredq 已提交
5100

5101 5102 5103
		pcolors = zlights.point.colors,
		ppositions = zlights.point.positions,
		pdistances = zlights.point.distances,
5104

A
alteredq 已提交
5105 5106 5107 5108 5109 5110 5111
		scolors = zlights.spot.colors,
		spositions = zlights.spot.positions,
		sdistances = zlights.spot.distances,
		sdirections = zlights.spot.directions,
		sangles = zlights.spot.angles,
		sexponents = zlights.spot.exponents,

5112 5113
		dlength = 0,
		plength = 0,
A
alteredq 已提交
5114
		slength = 0,
5115

5116
		doffset = 0,
A
alteredq 已提交
5117 5118
		poffset = 0,
		soffset = 0;
5119

5120
		for ( l = 0, ll = lights.length; l < ll; l ++ ) {
5121

5122
			light = lights[ l ];
A
alteredq 已提交
5123

A
alteredq 已提交
5124 5125 5126
			if ( light.onlyShadow ) continue;

			color = light.color;
5127 5128
			intensity = light.intensity;
			distance = light.distance;
A
alteredq 已提交
5129

5130
			if ( light instanceof THREE.AmbientLight ) {
5131

5132
				if ( _this.gammaInput ) {
5133

5134 5135 5136
					r += color.r * color.r;
					g += color.g * color.g;
					b += color.b * color.b;
5137

5138
				} else {
5139

5140 5141 5142
					r += color.r;
					g += color.g;
					b += color.b;
5143

5144
				}
5145

5146
			} else if ( light instanceof THREE.DirectionalLight ) {
5147

5148
				doffset = dlength * 3;
5149

5150
				if ( _this.gammaInput ) {
5151

5152 5153 5154
					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;
5155

5156
				} else {
5157

5158 5159 5160
					dcolors[ doffset ]     = color.r * intensity;
					dcolors[ doffset + 1 ] = color.g * intensity;
					dcolors[ doffset + 2 ] = color.b * intensity;
A
alteredq 已提交
5161

5162
				}
A
alteredq 已提交
5163

5164 5165 5166
				_direction.copy( light.matrixWorld.getPosition() );
				_direction.subSelf( light.target.matrixWorld.getPosition() );
				_direction.normalize();
A
alteredq 已提交
5167

5168 5169 5170
				dpositions[ doffset ]     = _direction.x;
				dpositions[ doffset + 1 ] = _direction.y;
				dpositions[ doffset + 2 ] = _direction.z;
A
alteredq 已提交
5171

5172
				dlength += 1;
A
alteredq 已提交
5173

A
alteredq 已提交
5174
			} else if( light instanceof THREE.PointLight ) {
M
Mr.doob 已提交
5175

5176
				poffset = plength * 3;
M
Mr.doob 已提交
5177

5178
				if ( _this.gammaInput ) {
5179

5180 5181 5182
					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 已提交
5183

5184
				} else {
A
alteredq 已提交
5185

5186 5187 5188
					pcolors[ poffset ]     = color.r * intensity;
					pcolors[ poffset + 1 ] = color.g * intensity;
					pcolors[ poffset + 2 ] = color.b * intensity;
A
alteredq 已提交
5189

5190
				}
A
alteredq 已提交
5191

A
alteredq 已提交
5192 5193
				position = light.matrixWorld.getPosition();

5194 5195 5196
				ppositions[ poffset ]     = position.x;
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
A
alteredq 已提交
5197

5198
				pdistances[ plength ] = distance;
A
alteredq 已提交
5199

5200
				plength += 1;
5201

A
alteredq 已提交
5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240
			} 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;

5241
			}
5242

5243
		}
A
alteredq 已提交
5244

5245 5246
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
A
alteredq 已提交
5247

5248 5249
		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 已提交
5250
		for ( l = slength * 3, ll = scolors.length; l < ll; l ++ ) scolors[ l ] = 0.0;
A
alteredq 已提交
5251

5252
		zlights.directional.length = dlength;
A
alteredq 已提交
5253 5254
		zlights.point.length = plength;
		zlights.spot.length = slength;
A
alteredq 已提交
5255

5256 5257 5258
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
5259

5260
	};
M
Mr.doob 已提交
5261

5262
	// GL state setting
M
Mr.doob 已提交
5263

5264
	this.setFaceCulling = function ( cullFace, frontFace ) {
M
Mr.doob 已提交
5265

5266
		if ( cullFace ) {
M
Mr.doob 已提交
5267

5268
			if ( !frontFace || frontFace === "ccw" ) {
5269

5270
				_gl.frontFace( _gl.CCW );
5271

5272
			} else {
5273

5274
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
5275

5276
			}
M
Mr.doob 已提交
5277

5278
			if( cullFace === "back" ) {
5279

5280
				_gl.cullFace( _gl.BACK );
5281

5282
			} else if( cullFace === "front" ) {
5283

5284
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
5285

5286
			} else {
5287

5288
				_gl.cullFace( _gl.FRONT_AND_BACK );
5289

5290
			}
5291

5292
			_gl.enable( _gl.CULL_FACE );
5293

5294
		} else {
5295

5296
			_gl.disable( _gl.CULL_FACE );
5297 5298 5299 5300 5301

		}

	};

A
alteredq 已提交
5302
	this.setObjectFaces = function ( object ) {
5303

5304
		if ( _oldDoubleSided !== object.doubleSided ) {
M
Mr.doob 已提交
5305

M
Mr.doob 已提交
5306
			if ( object.doubleSided ) {
M
Mr.doob 已提交
5307

5308
				_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
5309

5310
			} else {
5311

5312
				_gl.enable( _gl.CULL_FACE );
5313

5314
			}
5315

5316
			_oldDoubleSided = object.doubleSided;
5317

5318
		}
5319

5320
		if ( _oldFlipSided !== object.flipSided ) {
5321

M
Mr.doob 已提交
5322
			if ( object.flipSided ) {
5323

5324
				_gl.frontFace( _gl.CW );
5325

5326
			} else {
5327

5328
				_gl.frontFace( _gl.CCW );
5329

5330
			}
5331

5332
			_oldFlipSided = object.flipSided;
5333

5334
		}
5335

5336
	};
5337

A
alteredq 已提交
5338
	this.setDepthTest = function ( depthTest ) {
5339

5340
		if ( _oldDepthTest !== depthTest ) {
5341

5342
			if ( depthTest ) {
5343

5344
				_gl.enable( _gl.DEPTH_TEST );
5345

5346
			} else {
5347

5348
				_gl.disable( _gl.DEPTH_TEST );
5349 5350 5351

			}

5352
			_oldDepthTest = depthTest;
5353

5354
		}
5355

5356
	};
5357

5358
	this.setDepthWrite = function ( depthWrite ) {
A
alteredq 已提交
5359

5360
		if ( _oldDepthWrite !== depthWrite ) {
A
alteredq 已提交
5361

5362 5363
			_gl.depthMask( depthWrite );
			_oldDepthWrite = depthWrite;
A
alteredq 已提交
5364 5365 5366 5367 5368

		}

	};

5369
	function setLineWidth ( width ) {
5370

5371
		if ( width !== _oldLineWidth ) {
5372

5373 5374 5375
			_gl.lineWidth( width );

			_oldLineWidth = width;
5376 5377 5378

		}

5379
	};
5380

5381
	function setPolygonOffset ( polygonoffset, factor, units ) {
5382

5383
		if ( _oldPolygonOffset !== polygonoffset ) {
M
Mr.doob 已提交
5384

5385
			if ( polygonoffset ) {
5386

5387
				_gl.enable( _gl.POLYGON_OFFSET_FILL );
5388

5389
			} else {
5390

5391
				_gl.disable( _gl.POLYGON_OFFSET_FILL );
5392

5393
			}
5394

5395
			_oldPolygonOffset = polygonoffset;
5396

5397
		}
5398

5399
		if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
5400

5401
			_gl.polygonOffset( factor, units );
M
Mr.doob 已提交
5402

5403 5404
			_oldPolygonOffsetFactor = factor;
			_oldPolygonOffsetUnits = units;
M
Mr.doob 已提交
5405

5406
		}
M
Mr.doob 已提交
5407

5408
	};
M
Mr.doob 已提交
5409

5410
	this.setBlending = function ( blending, blendEquation, blendSrc, blendDst ) {
M
Mr.doob 已提交
5411

5412
		if ( blending !== _oldBlending ) {
M
Mr.doob 已提交
5413

5414
			switch ( blending ) {
M
Mr.doob 已提交
5415

5416
				case THREE.NoBlending:
5417 5418 5419 5420

					_gl.disable( _gl.BLEND );

					break;
5421

5422
				case THREE.AdditiveBlending:
M
Mr.doob 已提交
5423

5424
					_gl.enable( _gl.BLEND );
5425 5426
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
M
Mr.doob 已提交
5427

5428
					break;
M
Mr.doob 已提交
5429

5430
				case THREE.SubtractiveBlending:
M
Mr.doob 已提交
5431

5432
					// TODO: Find blendFuncSeparate() combination
5433
					_gl.enable( _gl.BLEND );
5434 5435
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
M
Mr.doob 已提交
5436

5437
					break;
M
Mr.doob 已提交
5438

5439
				case THREE.MultiplyBlending:
M
Mr.doob 已提交
5440

5441
					// TODO: Find blendFuncSeparate() combination
5442
					_gl.enable( _gl.BLEND );
5443 5444
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
M
Mr.doob 已提交
5445

5446
					break;
5447

5448 5449 5450 5451 5452 5453
				case THREE.CustomBlending:

					_gl.enable( _gl.BLEND );

					break;

5454
				default:
N
Nicolas Garcia Belmonte 已提交
5455

5456
					_gl.enable( _gl.BLEND );
5457 5458
					_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 );
5459

5460
					break;
5461

5462
			}
5463

5464
			_oldBlending = blending;
5465

5466
		}
5467

5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494
		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;

		}

5495
	};
5496

5497 5498 5499
	// Shaders

	function buildProgram ( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
5500

5501
		var p, pl, program, code;
5502
		var chunks = [];
5503 5504 5505

		// Generate code

5506 5507 5508 5509 5510 5511 5512 5513 5514 5515
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

			chunks.push( fragmentShader );
			chunks.push( vertexShader );

		}
5516 5517 5518

		for ( p in parameters ) {

5519 5520
			chunks.push( p );
			chunks.push( parameters[ p ] );
5521 5522 5523

		}

5524 5525
		code = chunks.join();

5526 5527 5528 5529
		// Check if code has been already compiled

		for ( p = 0, pl = _programs.length; p < pl; p ++ ) {

A
alteredq 已提交
5530 5531 5532
			var programInfo = _programs[ p ];

			if ( programInfo.code === code ) {
5533 5534

				// console.log( "Code already compiled." /*: \n\n" + code*/ );
5535

A
alteredq 已提交
5536 5537 5538
				programInfo.usedTimes ++;

				return programInfo.program;
5539 5540 5541 5542

			}

		}
5543

5544
		//console.log( "building new program " );
5545 5546 5547

		//

5548
		program = _gl.createProgram();
M
Mr.doob 已提交
5549

5550
		var prefix_vertex = [
M
Mr.doob 已提交
5551

5552 5553
			"precision " + _precision + " float;",

5554
			( _maxVertexTextures > 0 ) ? "#define VERTEX_TEXTURES" : "",
5555

5556 5557 5558 5559
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

5560 5561
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
5562
			"#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
5563

5564 5565
			"#define MAX_SHADOWS " + parameters.maxShadows,

5566 5567
			"#define MAX_BONES " + parameters.maxBones,

5568
			parameters.map ? "#define USE_MAP" : "",
5569 5570 5571
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5572
			parameters.skinning ? "#define USE_SKINNING" : "",
5573
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
A
alteredq 已提交
5574
			parameters.morphNormals ? "#define USE_MORPHNORMALS" : "",
A
alteredq 已提交
5575
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
5576
			parameters.wrapAround ? "#define WRAP_AROUND" : "",
5577
			parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
5578

5579
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5580
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
A
alteredq 已提交
5581 5582
			parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
			parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
5583

5584 5585
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
5586 5587 5588
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
5589 5590
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
5591
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
5592

M
Mr.doob 已提交
5593 5594 5595
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
5596
			"attribute vec2 uv2;",
5597

5598
			"#ifdef USE_COLOR",
5599

5600
				"attribute vec3 color;",
5601

5602 5603
			"#endif",

5604
			"#ifdef USE_MORPHTARGETS",
5605

5606 5607 5608 5609
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
A
alteredq 已提交
5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625

				"#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",
5626

5627 5628 5629
			"#endif",

			"#ifdef USE_SKINNING",
5630

5631 5632 5633 5634
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
5635

5636
			"#endif",
5637

M
Mr.doob 已提交
5638
			""
A
alteredq 已提交
5639

M
Mr.doob 已提交
5640
		].join("\n");
5641

M
Mr.doob 已提交
5642 5643
		var prefix_fragment = [

5644
			"precision " + _precision + " float;",
M
Mr.doob 已提交
5645 5646 5647

			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
5648
			"#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
M
Mr.doob 已提交
5649

5650 5651
			"#define MAX_SHADOWS " + parameters.maxShadows,

5652 5653
			parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",

5654 5655 5656 5657
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

M
Mr.doob 已提交
5658 5659
			( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
			( parameters.useFog && parameters.fog instanceof THREE.FogExp2 ) ? "#define FOG_EXP2" : "",
M
Mr.doob 已提交
5660 5661 5662 5663 5664

			parameters.map ? "#define USE_MAP" : "",
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5665

5666 5667
			parameters.metal ? "#define METAL" : "",
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
5668
			parameters.wrapAround ? "#define WRAP_AROUND" : "",
5669
			parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
5670

5671
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5672
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
A
alteredq 已提交
5673 5674
			parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
			parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
M
Mr.doob 已提交
5675 5676 5677 5678 5679 5680 5681

			"uniform mat4 viewMatrix;",
			"uniform vec3 cameraPosition;",
			""

		].join("\n");

5682 5683 5684 5685 5686
		var glFragmentShader = getShader( "fragment", prefix_fragment + fragmentShader );
		var glVertexShader = getShader( "vertex", prefix_vertex + vertexShader );

		_gl.attachShader( program, glVertexShader );
		_gl.attachShader( program, glFragmentShader );
M
Mr.doob 已提交
5687

M
Mr.doob 已提交
5688
		_gl.linkProgram( program );
N
Nicolas Garcia Belmonte 已提交
5689

M
Mr.doob 已提交
5690
		if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
N
Nicolas Garcia Belmonte 已提交
5691

5692
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
5693

N
Nicolas Garcia Belmonte 已提交
5694
		}
5695

5696 5697 5698 5699 5700
		// clean up

		_gl.deleteShader( glFragmentShader );
		_gl.deleteShader( glVertexShader );

5701 5702
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
5703

M
Mr.doob 已提交
5704
		program.uniforms = {};
5705
		program.attributes = {};
M
Mr.doob 已提交
5706

5707 5708 5709 5710
		var identifiers, u, a, i;

		// cache uniform locations

5711
		identifiers = [
5712

5713
			'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
A
alteredq 已提交
5714
			'boneGlobalMatrices', 'morphTargetInfluences'
M
Mr.doob 已提交
5715

5716
		];
M
Mr.doob 已提交
5717

5718
		for ( u in uniforms ) {
M
Mr.doob 已提交
5719

5720
			identifiers.push( u );
M
Mr.doob 已提交
5721

5722
		}
M
Mr.doob 已提交
5723

5724
		cacheUniformLocations( program, identifiers );
M
Mr.doob 已提交
5725

5726
		// cache attributes locations
M
Mr.doob 已提交
5727

5728
		identifiers = [
A
alteredq 已提交
5729

5730 5731
			"position", "normal", "uv", "uv2", "tangent", "color",
			"skinVertexA", "skinVertexB", "skinIndex", "skinWeight"
A
alteredq 已提交
5732

5733
		];
M
Mr.doob 已提交
5734

5735
		for ( i = 0; i < parameters.maxMorphTargets; i ++ ) {
M
Mr.doob 已提交
5736

5737
			identifiers.push( "morphTarget" + i );
M
Mr.doob 已提交
5738

5739
		}
5740

A
alteredq 已提交
5741 5742 5743 5744 5745 5746
		for ( i = 0; i < parameters.maxMorphNormals; i ++ ) {

			identifiers.push( "morphNormal" + i );

		}

5747
		for ( a in attributes ) {
5748

5749
			identifiers.push( a );
5750

5751
		}
5752

5753
		cacheAttributeLocations( program, identifiers );
5754

A
alteredq 已提交
5755
		program.id = _programs_counter ++;
5756

A
alteredq 已提交
5757
		_programs.push( { program: program, code: code, usedTimes: 1 } );
5758

5759
		_this.info.memory.programs = _programs.length;
5760

5761
		return program;
5762

5763
	};
5764

5765
	// Shader parameters cache
5766

5767
	function cacheUniformLocations ( program, identifiers ) {
5768

5769
		var i, l, id;
5770

5771
		for( i = 0, l = identifiers.length; i < l; i ++ ) {
5772

5773 5774
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
5775

5776
		}
M
Mr.doob 已提交
5777

5778
	};
M
Mr.doob 已提交
5779

5780
	function cacheAttributeLocations ( program, identifiers ) {
A
alteredq 已提交
5781

5782
		var i, l, id;
A
alteredq 已提交
5783

5784
		for( i = 0, l = identifiers.length; i < l; i ++ ) {
A
alteredq 已提交
5785

5786 5787
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
A
alteredq 已提交
5788

5789
		}
5790

5791
	};
A
alteredq 已提交
5792

5793
	function getShader ( type, string ) {
A
alteredq 已提交
5794

5795
		var shader;
5796

5797
		if ( type === "fragment" ) {
A
alteredq 已提交
5798

5799
			shader = _gl.createShader( _gl.FRAGMENT_SHADER );
A
alteredq 已提交
5800

5801
		} else if ( type === "vertex" ) {
A
alteredq 已提交
5802

5803
			shader = _gl.createShader( _gl.VERTEX_SHADER );
A
alteredq 已提交
5804

5805
		}
A
alteredq 已提交
5806

5807 5808
		_gl.shaderSource( shader, string );
		_gl.compileShader( shader );
5809

5810
		if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {
5811

5812 5813 5814
			console.error( _gl.getShaderInfoLog( shader ) );
			console.error( string );
			return null;
5815

A
alteredq 已提交
5816 5817
		}

5818 5819
		return shader;

A
alteredq 已提交
5820
	};
5821

5822 5823
	// Textures

5824 5825 5826 5827 5828 5829 5830

	function isPowerOfTwo ( value ) {

		return ( value & ( value - 1 ) ) === 0;

	};

5831
	function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {
5832

5833
		if ( isImagePowerOfTwo ) {
M
Mr.doob 已提交
5834

5835 5836
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
5837

5838 5839
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
5840

5841
		} else {
M
Mr.doob 已提交
5842

5843 5844
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
5845

5846 5847
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
5848

5849
		}
M
Mr.doob 已提交
5850

5851
	};
5852

5853
	this.setTexture = function ( texture, slot ) {
5854

5855
		if ( texture.needsUpdate ) {
A
alteredq 已提交
5856

5857
			if ( ! texture.__webglInit ) {
M
Mr.doob 已提交
5858

5859
				texture.__webglInit = true;
5860
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5861

M
Mr.doob 已提交
5862 5863
				_this.info.memory.textures ++;

5864
			}
M
Mr.doob 已提交
5865

5866
			_gl.activeTexture( _gl.TEXTURE0 + slot );
5867 5868
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );

5869 5870
			_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );

5871 5872
			var image = texture.image,
			isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
5873 5874
			glFormat = paramThreeToGL( texture.format ),
			glType = paramThreeToGL( texture.type );
5875

5876 5877
			setTextureParameters( _gl.TEXTURE_2D, texture, isImagePowerOfTwo );

5878
			if ( texture instanceof THREE.DataTexture ) {
5879

5880
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );
M
Mr.doob 已提交
5881

A
alteredq 已提交
5882
			} else {
M
Mr.doob 已提交
5883

5884
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, texture.image );
M
Mr.doob 已提交
5885 5886 5887

			}

5888
			if ( texture.generateMipmaps && isImagePowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
M
Mr.doob 已提交
5889

A
alteredq 已提交
5890
			texture.needsUpdate = false;
5891

5892
			if ( texture.onUpdate ) texture.onUpdate();
5893

5894
		} else {
5895

5896 5897
			_gl.activeTexture( _gl.TEXTURE0 + slot );
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
5898 5899

		}
M
Mr.doob 已提交
5900

5901
	};
M
Mr.doob 已提交
5902

5903 5904 5905 5906 5907 5908 5909 5910 5911 5912
	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.
5913

5914 5915 5916 5917 5918 5919 5920
		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;
5921

5922
		var ctx = canvas.getContext( "2d" );
5923 5924
		ctx.drawImage( image, 0, 0, image.width, image.height, 0, 0, newWidth, newHeight );

5925 5926 5927 5928
		return canvas;

	}

5929
	function setCubeTexture ( texture, slot ) {
5930

5931
		if ( texture.image.length === 6 ) {
5932 5933 5934

			if ( texture.needsUpdate ) {

A
alteredq 已提交
5935
				if ( ! texture.image.__webglTextureCube ) {
5936 5937

					texture.image.__webglTextureCube = _gl.createTexture();
5938

A
alteredq 已提交
5939
				}
5940

A
alteredq 已提交
5941 5942
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5943

5944
				var cubeImage = [];
5945

A
alteredq 已提交
5946
				for ( var i = 0; i < 6; i ++ ) {
5947

5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959
					if ( _this.autoScaleCubemaps ) {

						cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize );

					} else {

						cubeImage[ i ] = texture.image[ i ];

					}

				}

5960 5961
				var image = cubeImage[ 0 ],
				isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
5962 5963
				glFormat = paramThreeToGL( texture.format ),
				glType = paramThreeToGL( texture.type );
5964

5965 5966
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo );

A
alteredq 已提交
5967
				for ( var i = 0; i < 6; i ++ ) {
5968

5969
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
5970

A
alteredq 已提交
5971
				}
5972

5973
				if ( texture.generateMipmaps && isImagePowerOfTwo )	_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
5974

A
alteredq 已提交
5975
				texture.needsUpdate = false;
5976

5977
				if ( texture.onUpdate ) texture.onUpdate();
5978

A
alteredq 已提交
5979
			} else {
5980

A
alteredq 已提交
5981 5982
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5983

A
alteredq 已提交
5984
			}
5985

A
alteredq 已提交
5986
		}
5987

A
alteredq 已提交
5988
	};
5989

5990
	function setCubeTextureDynamic ( texture, slot ) {
5991

A
alteredq 已提交
5992 5993
		_gl.activeTexture( _gl.TEXTURE0 + slot );
		_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
5994 5995 5996

	};

5997 5998 5999
	// Render targets

	function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
6000

6001 6002
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
A
alteredq 已提交
6003

6004
	};
M
Mr.doob 已提交
6005

6006
	function setupRenderBuffer ( renderbuffer, renderTarget  ) {
M
Mikael Emtinger 已提交
6007

6008
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
6009

6010
		if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
M
Mr.doob 已提交
6011

6012 6013
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
6014

6015 6016
		/* For some reason this is not working. Defaulting to RGBA4.
		} else if( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
A
alteredq 已提交
6017

6018 6019 6020 6021
			_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 已提交
6022

6023 6024
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
6025

6026
		} else {
A
alteredq 已提交
6027

6028
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
A
alteredq 已提交
6029

6030
		}
A
alteredq 已提交
6031

6032
	};
A
alteredq 已提交
6033

A
alteredq 已提交
6034
	this.setRenderTarget = function ( renderTarget ) {
A
alteredq 已提交
6035

6036
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
A
alteredq 已提交
6037

6038
		if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
A
alteredq 已提交
6039

6040 6041
			if( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
			if( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
A
alteredq 已提交
6042

6043
			renderTarget.__webglTexture = _gl.createTexture();
A
alteredq 已提交
6044

6045
			// Setup texture, create render and frame buffers
6046

6047 6048
			var isTargetPowerOfTwo = isPowerOfTwo( renderTarget.width ) && isPowerOfTwo( renderTarget.height ),
				glFormat = paramThreeToGL( renderTarget.format ),
6049 6050
				glType = paramThreeToGL( renderTarget.type );

6051
			if ( isCube ) {
M
Mr.doob 已提交
6052

6053 6054
				renderTarget.__webglFramebuffer = [];
				renderTarget.__webglRenderbuffer = [];
M
Mikael Emtinger 已提交
6055

6056
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
6057
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, isTargetPowerOfTwo );
A
alteredq 已提交
6058

6059
				for ( var i = 0; i < 6; i ++ ) {
A
alteredq 已提交
6060

6061 6062
					renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
					renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
A
alteredq 已提交
6063

6064
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
A
alteredq 已提交
6065

6066 6067
					setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
					setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
A
alteredq 已提交
6068

6069
				}
6070

6071 6072
				if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

6073
			} else {
6074

6075 6076
				renderTarget.__webglFramebuffer = _gl.createFramebuffer();
				renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
6077

6078
				_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
6079
				setTextureParameters( _gl.TEXTURE_2D, renderTarget, isTargetPowerOfTwo );
6080

6081
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
6082

6083 6084
				setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
				setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
6085

6086 6087
				if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );

M
Mikael Emtinger 已提交
6088
			}
6089

6090
			// Release everything
M
Mr.doob 已提交
6091

A
alteredq 已提交
6092 6093 6094 6095 6096 6097 6098 6099 6100 6101
			if ( isCube ) {

				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

			} else {

				_gl.bindTexture( _gl.TEXTURE_2D, null );

			}

6102 6103
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
6104

6105 6106
		}

6107
		var framebuffer, width, height, vx, vy;
M
Mr.doob 已提交
6108

6109
		if ( renderTarget ) {
M
Mr.doob 已提交
6110

A
alteredq 已提交
6111 6112
			if ( isCube ) {

6113
				framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
A
alteredq 已提交
6114 6115 6116

			} else {

6117
				framebuffer = renderTarget.__webglFramebuffer;
A
alteredq 已提交
6118 6119 6120

			}

6121 6122
			width = renderTarget.width;
			height = renderTarget.height;
M
Mr.doob 已提交
6123

6124 6125 6126
			vx = 0;
			vy = 0;

6127
		} else {
M
Mr.doob 已提交
6128

6129
			framebuffer = null;
6130

6131 6132
			width = _viewportWidth;
			height = _viewportHeight;
6133

6134 6135
			vx = _viewportX;
			vy = _viewportY;
M
Mr.doob 已提交
6136

6137
		}
M
Mr.doob 已提交
6138

6139
		if ( framebuffer !== _currentFramebuffer ) {
M
Mr.doob 已提交
6140

6141
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
6142
			_gl.viewport( vx, vy, width, height );
M
Mr.doob 已提交
6143

6144
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
6145

6146
		}
6147

A
alteredq 已提交
6148 6149 6150
		_currentWidth = width;
		_currentHeight = height;

6151
	};
M
Mr.doob 已提交
6152

6153
	function updateRenderTargetMipmap ( renderTarget ) {
M
Mr.doob 已提交
6154

A
alteredq 已提交
6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167
		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 已提交
6168 6169

	};
6170

6171
	// Fallback filters for non-power-of-2 textures
6172

6173
	function filterFallback ( f ) {
6174

6175 6176 6177 6178 6179 6180 6181 6182
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mr.doob 已提交
6183
			case THREE.LinearMipMapLinearFilter:
M
Mikael Emtinger 已提交
6184
			default:
6185

M
Mikael Emtinger 已提交
6186
				return _gl.LINEAR; break;
6187 6188

		}
6189

6190
	};
6191

6192 6193
	// Map three.js constants to WebGL constants

6194
	function paramThreeToGL ( p ) {
M
Mr.doob 已提交
6195

6196
		switch ( p ) {
M
Mr.doob 已提交
6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209

			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;

6210 6211 6212 6213 6214
			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;
6215
			case THREE.UnsignedIntType: return _gl.UNSIGNED_INT; break;
6216 6217 6218 6219 6220 6221 6222 6223
			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;

6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240
			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;

6241
		}
M
Mr.doob 已提交
6242

6243
		return 0;
M
Mr.doob 已提交
6244

6245 6246
	};

6247
	// Allocations
6248

6249
	function allocateBones ( object ) {
6250

6251 6252 6253 6254 6255 6256 6257
		// 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)
6258

6259
		var maxBones = 50;
6260

6261
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
6262

6263 6264 6265 6266 6267
			maxBones = object.bones.length;

		}

		return maxBones;
6268

6269
	};
6270

6271
	function allocateLights ( lights ) {
6272

A
alteredq 已提交
6273
		var l, ll, light, dirLights, pointLights, spotLights, maxDirLights, maxPointLights, maxSpotLights;
6274

A
alteredq 已提交
6275 6276 6277
		dirLights = pointLights = spotLights = maxDirLights = maxPointLights = maxSpotLights = 0;

		for ( l = 0, ll = lights.length; l < ll; l ++ ) {
6278

6279
			light = lights[ l ];
6280

A
alteredq 已提交
6281 6282
			if ( light.onlyShadow ) continue;

6283 6284
			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
			if ( light instanceof THREE.PointLight ) pointLights ++;
A
alteredq 已提交
6285
			if ( light instanceof THREE.SpotLight ) spotLights ++;
6286

6287
		}
6288

A
alteredq 已提交
6289
		if ( ( pointLights + spotLights + dirLights ) <= _maxLights ) {
6290

6291 6292
			maxDirLights = dirLights;
			maxPointLights = pointLights;
A
alteredq 已提交
6293
			maxSpotLights = spotLights;
6294

6295
		} else {
6296

6297 6298
			maxDirLights = Math.ceil( _maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = _maxLights - maxDirLights;
A
alteredq 已提交
6299
			maxSpotLights = maxPointLights; // this is not really correct
6300 6301 6302

		}

A
alteredq 已提交
6303
		return { 'directional' : maxDirLights, 'point' : maxPointLights, 'spot': maxSpotLights };
6304 6305

	};
M
Mr.doob 已提交
6306

6307
	function allocateShadows ( lights ) {
6308

M
Mr.doob 已提交
6309
		var l, ll, light, maxShadows = 0;
6310 6311 6312 6313 6314

		for ( l = 0, ll = lights.length; l < ll; l++ ) {

			light = lights[ l ];

A
alteredq 已提交
6315 6316
			if ( ! light.castShadow ) continue;

6317 6318
			if ( light instanceof THREE.SpotLight ) maxShadows ++;
			if ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) maxShadows ++;
6319 6320 6321 6322 6323 6324 6325

		}

		return maxShadows;

	};

6326
	// Initialization
M
Mr.doob 已提交
6327

6328 6329 6330 6331 6332 6333
	function initGL () {

		var gl;

		try {

6334
			if ( ! ( gl = _canvas.getContext( 'experimental-webgl', { alpha: _alpha, premultipliedAlpha: _premultipliedAlpha, antialias: _antialias, stencil: _stencil, preserveDrawingBuffer: _preserveDrawingBuffer } ) ) ) {
6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345

				throw 'Error creating WebGL context.';

			}

		} catch ( error ) {

			console.error( error );

		}

6346 6347 6348 6349 6350 6351
		if ( ! gl.getExtension( 'OES_texture_float' ) ) {

			console.log( 'THREE.WebGLRenderer: Float textures not supported.' );

		}

6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376
		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 );

	};

6377 6378
	// default plugins (order is important)

A
alteredq 已提交
6379 6380 6381 6382 6383
	this.shadowMapPlugin = new THREE.ShadowMapPlugin();
	this.addPrePlugin( this.shadowMapPlugin );

	this.addPostPlugin( new THREE.SpritePlugin() );
	this.addPostPlugin( new THREE.LensFlarePlugin() );
6384

6385
};