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

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

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 ),
25
	_clearAlpha = parameters.clearAlpha !== undefined ? parameters.clearAlpha : 0;
26

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

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

	// clearing
M
Mr.doob 已提交
33

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

39 40
	// scene graph

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

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

	// physically based shading

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

52 53 54
	// shadow map

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

61
	// morphs
62

63
	this.maxMorphTargets = 8;
A
alteredq 已提交
64
	this.maxMorphNormals = 4;
65

66 67 68 69
	// flags

	this.autoScaleCubemaps = true;

70 71
	// custom render plugins

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

75
	// info
76

77
	this.info = {
78

79
		memory: {
80

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

85
		},
86

87
		render: {
88

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

		}

96
	};
M
Mr.doob 已提交
97

98
	// internal properties
99

100
	var _this = this,
101

102
	_programs = [],
A
alteredq 已提交
103
	_programs_counter = 0,
104

105
	// internal state cache
106

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

114 115
	_usedTextureUnits = 0,

116
	// GL state cache
117

118 119
	_oldDoubleSided = -1,
	_oldFlipSided = -1,
120

121
	_oldBlending = -1,
122

123 124 125
	_oldBlendEquation = -1,
	_oldBlendSrc = -1,
	_oldBlendDst = -1,
126

127 128
	_oldDepthTest = -1,
	_oldDepthWrite = -1,
129

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

134
	_oldLineWidth = null,
135

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

143 144
	_enabledAttributes = {},

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
		point: { length: 0, colors: new Array(), positions: new Array(), distances: new Array() },
167
		spot: { length: 0, colors: new Array(), positions: new Array(), distances: new Array(), directions: new Array(), anglesCos: new Array(), exponents: new Array() },
A
alteredq 已提交
168
		hemi: { length: 0, skyColors: new Array(), groundColors: new Array(), positions: new Array() }
M
Mr.doob 已提交
169

170
	};
M
Mr.doob 已提交
171

172
	// initialize
M
Mikael Emtinger 已提交
173

174
	var _gl;
A
alteredq 已提交
175

176
	var _glExtensionTextureFloat;
A
alteredq 已提交
177
	var _glExtensionStandardDerivatives;
178
	var _glExtensionTextureFilterAnisotropic;
179
	var _glExtensionCompressedTextureS3TC;
180 181

	initGL();
M
Mikael Emtinger 已提交
182

183
	setDefaultGLState();
M
Mikael Emtinger 已提交
184

185
	this.context = _gl;
M
Mikael Emtinger 已提交
186

187 188
	// GPU capabilities

189 190 191 192
	var _maxTextures = _gl.getParameter( _gl.MAX_TEXTURE_IMAGE_UNITS );
	var _maxVertexTextures = _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );
	var _maxTextureSize = _gl.getParameter( _gl.MAX_TEXTURE_SIZE );
	var _maxCubemapSize = _gl.getParameter( _gl.MAX_CUBE_MAP_TEXTURE_SIZE );
M
Mr.doob 已提交
193

194 195
	var _maxAnisotropy = _glExtensionTextureFilterAnisotropic ? _gl.getParameter( _glExtensionTextureFilterAnisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT ) : 0;

196 197 198
	var _supportsVertexTextures = ( _maxVertexTextures > 0 );
	var _supportsBoneTextures = _supportsVertexTextures && _glExtensionTextureFloat;

199 200
	var _compressedTextureFormats = _glExtensionCompressedTextureS3TC ? _gl.getParameter( _gl.COMPRESSED_TEXTURE_FORMATS ) : [];

201
	// API
M
Mr.doob 已提交
202

203
	this.getContext = function () {
M
Mr.doob 已提交
204

205
		return _gl;
M
Mr.doob 已提交
206

207
	};
M
Mr.doob 已提交
208

209
	this.supportsVertexTextures = function () {
M
Mikael Emtinger 已提交
210

211
		return _supportsVertexTextures;
M
Mikael Emtinger 已提交
212

213
	};
M
Mikael Emtinger 已提交
214

215 216 217 218 219 220
	this.getMaxAnisotropy  = function () {

		return _maxAnisotropy;

	};

N
Nicolas Garcia Belmonte 已提交
221 222 223 224
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
225

226 227 228
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
229

230
	this.setViewport = function ( x, y, width, height ) {
231

232 233
		_viewportX = x !== undefined ? x : 0;
		_viewportY = y !== undefined ? y : 0;
234

235 236
		_viewportWidth = width !== undefined ? width : _canvas.width;
		_viewportHeight = height !== undefined ? height : _canvas.height;
237

238
		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
239

N
Nicolas Garcia Belmonte 已提交
240
	};
241

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

244
		_gl.scissor( x, y, width, height );
245

246
	};
247

248
	this.enableScissorTest = function ( enable ) {
249

M
Mr.doob 已提交
250
		enable ? _gl.enable( _gl.SCISSOR_TEST ) : _gl.disable( _gl.SCISSOR_TEST );
251 252

	};
253

254 255
	// Clearing

256
	this.setClearColorHex = function ( hex, alpha ) {
257

258 259 260 261
		_clearColor.setHex( hex );
		_clearAlpha = alpha;

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

263
	};
A
alteredq 已提交
264

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

267 268 269 270
		_clearColor.copy( color );
		_clearAlpha = alpha;

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

	};
273

M
Mr.doob 已提交
274 275 276 277 278 279 280
	this.getClearColor = function () {

		return _clearColor;

	};

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

M
Mr.doob 已提交
282 283 284 285 286 287 288 289
		return _clearAlpha;

	};

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

		var bits = 0;

290 291 292
		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 已提交
293 294

		_gl.clear( bits );
N
Nicolas Garcia Belmonte 已提交
295 296 297

	};

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

A
alteredq 已提交
300
		this.setRenderTarget( renderTarget );
301
		this.clear( color, depth, stencil );
M
Mr.doob 已提交
302 303 304

	};

305 306
	// Plugins

A
alteredq 已提交
307
	this.addPostPlugin = function ( plugin ) {
308 309

		plugin.init( this );
A
alteredq 已提交
310
		this.renderPluginsPost.push( plugin );
311 312 313

	};

A
alteredq 已提交
314 315 316 317 318 319
	this.addPrePlugin = function ( plugin ) {

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

	};
320

321 322
	// Deallocation

323 324 325 326 327 328 329
	this.deallocateObject = function ( object ) {

		if ( ! object.__webglInit ) return;

		object.__webglInit = false;

		delete object._modelViewMatrix;
330
		delete object._normalMatrix;
331 332 333

		if ( object instanceof THREE.Mesh ) {

334
			for ( var g in object.geometry.geometryGroups ) {
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362

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

365 366
	};

367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390
	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 已提交
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 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453
	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 --;

		}

	};

454
	// Rendering
455

456
	this.updateShadowMap = function ( scene, camera ) {
457

A
alteredq 已提交
458 459 460 461 462 463
		_currentProgram = null;
		_oldBlending = -1;
		_oldDepthTest = -1;
		_oldDepthWrite = -1;
		_currentGeometryGroupHash = -1;
		_currentMaterialId = -1;
464 465 466
		_lightsNeedUpdate = true;
		_oldDoubleSided = -1;
		_oldFlipSided = -1;
A
alteredq 已提交
467 468

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

470
	};
M
Mr.doob 已提交
471

472
	// Internal functions
473

474
	// Buffer allocation
475

476
	function createParticleBuffers ( geometry ) {
477

478 479
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
480

481
		_this.info.memory.geometries ++;
482

483
	};
484

485
	function createLineBuffers ( geometry ) {
486

487 488
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
489
		geometry.__webglLineDistanceBuffer = _gl.createBuffer();
490

491
		_this.info.memory.geometries ++;
492

493
	};
494

495
	function createRibbonBuffers ( geometry ) {
496

497 498
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
499
		geometry.__webglNormalBuffer = _gl.createBuffer();
500

501
		_this.info.memory.geometries ++;
M
Mr.doob 已提交
502

503
	};
504

505
	function createMeshBuffers ( geometryGroup ) {
506

507 508 509 510 511 512
		geometryGroup.__webglVertexBuffer = _gl.createBuffer();
		geometryGroup.__webglNormalBuffer = _gl.createBuffer();
		geometryGroup.__webglTangentBuffer = _gl.createBuffer();
		geometryGroup.__webglColorBuffer = _gl.createBuffer();
		geometryGroup.__webglUVBuffer = _gl.createBuffer();
		geometryGroup.__webglUV2Buffer = _gl.createBuffer();
513

514 515
		geometryGroup.__webglSkinIndicesBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinWeightsBuffer = _gl.createBuffer();
516

517 518
		geometryGroup.__webglFaceBuffer = _gl.createBuffer();
		geometryGroup.__webglLineBuffer = _gl.createBuffer();
519

520
		var m, ml;
521

522
		if ( geometryGroup.numMorphTargets ) {
523

524
			geometryGroup.__webglMorphTargetsBuffers = [];
525

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

528
				geometryGroup.__webglMorphTargetsBuffers.push( _gl.createBuffer() );
529 530 531 532 533 534 535 536 537 538 539

			}

		}

		if ( geometryGroup.numMorphNormals ) {

			geometryGroup.__webglMorphNormalsBuffers = [];

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

A
alteredq 已提交
540
				geometryGroup.__webglMorphNormalsBuffers.push( _gl.createBuffer() );
541

542
			}
543

544
		}
545

546
		_this.info.memory.geometries ++;
547

548
	};
549

550
	// Buffer deallocation
551

552
	function deleteParticleBuffers ( geometry ) {
553

554 555
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
556

557 558
		deleteCustomAttributesBuffers( geometry );

559
		_this.info.memory.geometries --;
560

561
	};
562

563
	function deleteLineBuffers ( geometry ) {
564

565 566
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
567
		_gl.deleteBuffer( geometry.__webglLineDistanceBuffer );
568

569 570
		deleteCustomAttributesBuffers( geometry );

M
Mr.doob 已提交
571 572
		_this.info.memory.geometries --;

573 574
	};

575
	function deleteRibbonBuffers ( geometry ) {
576 577 578

		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
579
		_gl.deleteBuffer( geometry.__webglNormalBuffer );
580

581 582
		deleteCustomAttributesBuffers( geometry );

M
Mr.doob 已提交
583 584
		_this.info.memory.geometries --;

585 586
	};

587
	function deleteMeshBuffers ( geometryGroup ) {
588 589 590 591 592 593 594 595 596 597 598 599 600 601

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

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

602 603
		var m, ml;

604 605
		if ( geometryGroup.numMorphTargets ) {

606
			for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
607 608

				_gl.deleteBuffer( geometryGroup.__webglMorphTargetsBuffers[ m ] );
609 610 611 612 613 614 615 616 617

			}

		}

		if ( geometryGroup.numMorphNormals ) {

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

A
alteredq 已提交
618
				_gl.deleteBuffer( geometryGroup.__webglMorphNormalsBuffers[ m ] );
619 620 621 622 623

			}

		}

624
		deleteCustomAttributesBuffers( geometryGroup );
625

626 627 628
		_this.info.memory.geometries --;

	};
629

630
	function deleteCustomAttributesBuffers( geometry ) {
631

632 633 634 635 636
		if ( geometry.__webglCustomAttributesList ) {

			for ( var id in geometry.__webglCustomAttributesList ) {

				_gl.deleteBuffer( geometry.__webglCustomAttributesList[ id ].buffer );
637 638 639 640 641

			}

		}

642 643
	};

644
	// Buffer initialization
645

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

648 649
		var nvertices = geometry.vertices.length;

650
		var material = object.material;
651

652
		if ( material.attributes ) {
653

654
			if ( geometry.__webglCustomAttributesList === undefined ) {
655

656
				geometry.__webglCustomAttributesList = [];
657

658
			}
659

660
			for ( var a in material.attributes ) {
661

662
				var attribute = material.attributes[ a ];
663

664
				if ( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
665

666
					attribute.__webglInitialized = true;
667

A
alteredq 已提交
668
					var size = 1;		// "f" and "i"
669

670 671 672 673
					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;
674

675
					attribute.size = size;
A
alteredq 已提交
676

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

679 680
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
681

682
					attribute.needsUpdate = true;
683

684
				}
685

686
				geometry.__webglCustomAttributesList.push( attribute );
687

688
			}
689

690
		}
691

692
	};
693

694
	function initParticleBuffers ( geometry, object ) {
A
alteredq 已提交
695 696 697 698 699 700

		var nvertices = geometry.vertices.length;

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

701 702 703
		geometry.__sortArray = [];

		geometry.__webglParticleCount = nvertices;
A
alteredq 已提交
704 705 706 707 708

		initCustomAttributes ( geometry, object );

	};

709
	function initLineBuffers ( geometry, object ) {
A
alteredq 已提交
710 711 712 713 714

		var nvertices = geometry.vertices.length;

		geometry.__vertexArray = new Float32Array( nvertices * 3 );
		geometry.__colorArray = new Float32Array( nvertices * 3 );
715
		geometry.__lineDistanceArray = new Float32Array( nvertices * 1 );
A
alteredq 已提交
716

717
		geometry.__webglLineCount = nvertices;
A
alteredq 已提交
718 719 720 721 722

		initCustomAttributes ( geometry, object );

	};

723
	function initRibbonBuffers ( geometry, object ) {
A
alteredq 已提交
724 725 726 727 728

		var nvertices = geometry.vertices.length;

		geometry.__vertexArray = new Float32Array( nvertices * 3 );
		geometry.__colorArray = new Float32Array( nvertices * 3 );
729
		geometry.__normalArray = new Float32Array( nvertices * 3 );
A
alteredq 已提交
730 731 732

		geometry.__webglVertexCount = nvertices;

733 734
		initCustomAttributes ( geometry, object );

A
alteredq 已提交
735 736
	};

M
Mr.doob 已提交
737
	function initMeshBuffers ( geometryGroup, object ) {
M
Mr.doob 已提交
738

739 740 741
		var geometry = object.geometry,
			faces3 = geometryGroup.faces3,
			faces4 = geometryGroup.faces4,
M
Mr.doob 已提交
742

743 744 745
			nvertices = faces3.length * 3 + faces4.length * 4,
			ntris     = faces3.length * 1 + faces4.length * 2,
			nlines    = faces3.length * 3 + faces4.length * 4,
746

747
			material = getBufferMaterial( object, geometryGroup ),
748

749 750 751
			uvType = bufferGuessUVType( material ),
			normalType = bufferGuessNormalType( material ),
			vertexColorType = bufferGuessVertexColorType( material );
A
alteredq 已提交
752

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

755
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
756

757
		if ( normalType ) {
M
Mr.doob 已提交
758

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

761
		}
762

763
		if ( geometry.hasTangents ) {
764

765
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
766

767
		}
768

769
		if ( vertexColorType ) {
770

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

773
		}
M
Mr.doob 已提交
774

775
		if ( uvType ) {
776

777
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
778

779 780 781 782 783
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

785 786 787 788 789 790 791 792 793 794 795 796 797
				geometryGroup.__uv2Array = new Float32Array( nvertices * 2 );

			}

		}

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

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

		}

798
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
799
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
800

801 802
		var m, ml;

803 804
		if ( geometryGroup.numMorphTargets ) {

M
Mr.doob 已提交
805
			geometryGroup.__morphTargetsArrays = [];
806

807
			for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
808

809
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );
810 811 812 813 814 815 816 817 818 819 820

			}

		}

		if ( geometryGroup.numMorphNormals ) {

			geometryGroup.__morphNormalsArrays = [];

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

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

823 824 825
			}

		}
826

827
		geometryGroup.__webglFaceCount = ntris * 3;
828
		geometryGroup.__webglLineCount = nlines * 2;
829

M
Mr.doob 已提交
830

831
		// custom attributes
M
Mr.doob 已提交
832

833
		if ( material.attributes ) {
834

835
			if ( geometryGroup.__webglCustomAttributesList === undefined ) {
836

837
				geometryGroup.__webglCustomAttributesList = [];
838

839
			}
840

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

843 844
				// Do a shallow copy of the attribute object so different geometryGroup chunks use different
				// attribute buffers which are correctly indexed in the setMeshBuffers function
845

846
				var originalAttribute = material.attributes[ a ];
847

848
				var attribute = {};
849

850
				for ( var property in originalAttribute ) {
M
Mr.doob 已提交
851

852
					attribute[ property ] = originalAttribute[ property ];
853

854
				}
855

A
alteredq 已提交
856
				if ( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
857

858
					attribute.__webglInitialized = true;
859

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

862 863 864 865
					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;
866

867
					attribute.size = size;
A
alteredq 已提交
868

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

871 872
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
873

874 875
					originalAttribute.needsUpdate = true;
					attribute.__original = originalAttribute;
876 877 878

				}

879 880
				geometryGroup.__webglCustomAttributesList.push( attribute );

881
			}
M
Mr.doob 已提交
882

883
		}
884

885 886
		geometryGroup.__inittedArrays = true;

887
	};
M
Mr.doob 已提交
888

889
	function getBufferMaterial( object, geometryGroup ) {
890

891 892 893
		return object.material instanceof THREE.MeshFaceMaterial
			? object.material.materials[ geometryGroup.materialIndex ]
			: object.material;
894

895
	};
M
Mr.doob 已提交
896

897
	function materialNeedsSmoothNormals ( material ) {
898

899
		return material && material.shading !== undefined && material.shading === THREE.SmoothShading;
900

901
	};
M
Mr.doob 已提交
902

903
	function bufferGuessNormalType ( material ) {
904

905
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
906

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

909
			return false;
910

911
		}
912

913
		if ( materialNeedsSmoothNormals( material ) ) {
914

915
			return THREE.SmoothShading;
M
Mr.doob 已提交
916

917
		} else {
918

919
			return THREE.FlatShading;
920

921
		}
922

923
	};
924

925
	function bufferGuessVertexColorType ( material ) {
926

927
		if ( material.vertexColors ) {
928

929
			return material.vertexColors;
930

931
		}
M
Mr.doob 已提交
932

933
		return false;
M
Mr.doob 已提交
934

935
	};
M
Mr.doob 已提交
936

937
	function bufferGuessUVType ( material ) {
938

939 940
		// material must use some texture to require uvs

941
		if ( material.map || material.lightMap || material.bumpMap || material.normalMap || material.specularMap || material instanceof THREE.ShaderMaterial ) {
942 943 944 945 946 947 948 949 950

			return true;

		}

		return false;

	};

951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979
	//

	function initDirectBuffers( geometry ) {

		var a, attribute, type;

		for ( a in geometry.attributes ) {

			if ( a === "index" ) {

				type = _gl.ELEMENT_ARRAY_BUFFER;

			} else {

				type = _gl.ARRAY_BUFFER;

			}

			attribute = geometry.attributes[ a ];

			attribute.buffer = _gl.createBuffer();

			_gl.bindBuffer( type, attribute.buffer );
			_gl.bufferData( type, attribute.array, _gl.STATIC_DRAW );

		}

	};

980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996
	// 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,

997
		dirtyVertices = geometry.verticesNeedUpdate,
M
Mr.doob 已提交
998
		dirtyElements = geometry.elementsNeedUpdate,
M
Mr.doob 已提交
999
		dirtyColors = geometry.colorsNeedUpdate,
1000 1001 1002 1003 1004 1005 1006 1007

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

		if ( object.sortParticles ) {

A
alteredq 已提交
1008 1009
			_projScreenMatrixPS.copy( _projScreenMatrix );
			_projScreenMatrixPS.multiplySelf( object.matrixWorld );
1010 1011 1012

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

1013
				vertex = vertices[ v ];
1014 1015

				_vector3.copy( vertex );
A
alteredq 已提交
1016
				_projScreenMatrixPS.multiplyVector3( _vector3 );
1017 1018 1019 1020 1021 1022 1023 1024 1025

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

			}

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

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

1026
				vertex = vertices[ sortArray[v][1] ];
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149

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

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

					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 &&
1185
						 ( customAttribute.boundTo === undefined ||
1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305
						   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 ) {

1306
		var v, c, d, vertex, offset, color,
1307 1308 1309

		vertices = geometry.vertices,
		colors = geometry.colors,
1310 1311
		lineDistances = geometry.lineDistances,

1312 1313
		vl = vertices.length,
		cl = colors.length,
1314
		dl = lineDistances.length,
1315 1316 1317

		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
1318
		lineDistanceArray = geometry.__lineDistanceArray,
1319

1320
		dirtyVertices = geometry.verticesNeedUpdate,
M
Mr.doob 已提交
1321
		dirtyColors = geometry.colorsNeedUpdate,
1322
		dirtyLineDistances = geometry.lineDistancesNeedUpdate,
1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333

		customAttributes = geometry.__webglCustomAttributesList,

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

		if ( dirtyVertices ) {

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

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

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

		}

1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380
		if ( dirtyLineDistances ) {

			for ( d = 0; d < dl; d ++ ) {

				lineDistanceArray[ d ] = lineDistances[ d ];

			}

			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglLineDistanceBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, lineDistanceArray, hint );

		}

1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477
		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 ) {

1478
		var v, c, n, vertex, offset, color, normal,
1479

1480 1481
		i, il, ca, cal, customAttribute, value,

1482 1483
		vertices = geometry.vertices,
		colors = geometry.colors,
1484 1485
		normals = geometry.normals,

1486 1487
		vl = vertices.length,
		cl = colors.length,
1488
		nl = normals.length,
1489 1490 1491

		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
1492
		normalArray = geometry.__normalArray,
1493

1494
		dirtyVertices = geometry.verticesNeedUpdate,
1495
		dirtyColors = geometry.colorsNeedUpdate,
1496 1497 1498
		dirtyNormals = geometry.normalsNeedUpdate,

		customAttributes = geometry.__webglCustomAttributesList;
1499 1500 1501 1502 1503

		if ( dirtyVertices ) {

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

1504
				vertex = vertices[ v ];
1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537

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

		}

1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556
		if ( dirtyNormals ) {

			for ( n = 0; n < nl; n ++ ) {

				normal = normals[ n ];

				offset = n * 3;

				normalArray[ offset ]     = normal.x;
				normalArray[ offset + 1 ] = normal.y;
				normalArray[ offset + 2 ] = normal.z;

			}

			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglNormalBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );

		}

1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649
		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 );

				}

			}

		}

1650 1651
	};

1652
	function setMeshBuffers( geometryGroup, object, hint, dispose, material ) {
1653 1654 1655 1656 1657 1658 1659

		if ( ! geometryGroup.__inittedArrays ) {

			return;

		}

1660 1661 1662 1663 1664 1665
		var normalType = bufferGuessNormalType( material ),
		vertexColorType = bufferGuessVertexColorType( material ),
		uvType = bufferGuessUVType( material ),

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

1666 1667 1668 1669
		var f, fl, fi, face,
		vertexNormals, faceNormal, normal,
		vertexColors, faceColor,
		vertexTangents,
A
alteredq 已提交
1670
		uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4, n1, n2, n3, n4,
1671 1672 1673 1674 1675 1676 1677 1678
		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 已提交
1679
		nka, chf, faceVertexNormals,
1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709
		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,

		skinIndexArray = geometryGroup.__skinIndexArray,
		skinWeightArray = geometryGroup.__skinWeightArray,

		morphTargetsArrays = geometryGroup.__morphTargetsArrays,
A
alteredq 已提交
1710
		morphNormalsArrays = geometryGroup.__morphNormalsArrays,
1711 1712 1713 1714 1715 1716 1717 1718 1719

		customAttributes = geometryGroup.__webglCustomAttributesList,
		customAttribute,

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

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

1720
		dirtyVertices = geometry.verticesNeedUpdate,
M
Mr.doob 已提交
1721
		dirtyElements = geometry.elementsNeedUpdate,
M
Mr.doob 已提交
1722
		dirtyUvs = geometry.uvsNeedUpdate,
M
Mr.doob 已提交
1723
		dirtyNormals = geometry.normalsNeedUpdate,
1724
		dirtyTangents = geometry.tangentsNeedUpdate,
M
Mr.doob 已提交
1725
		dirtyColors = geometry.colorsNeedUpdate,
1726
		dirtyMorphTargets = geometry.morphTargetsNeedUpdate,
1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740

		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_skinIndices = geometry.skinIndices,
		obj_skinWeights = geometry.skinWeights,

A
alteredq 已提交
1741 1742
		morphTargets = geometry.morphTargets,
		morphNormals = geometry.morphNormals;
1743 1744 1745 1746 1747 1748 1749

		if ( dirtyVertices ) {

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

				face = obj_faces[ chunk_faces3[ f ] ];

1750 1751 1752
				v1 = vertices[ face.a ];
				v2 = vertices[ face.b ];
				v3 = vertices[ face.c ];
1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764

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

1766
				offset += 9;
M
Mr.doob 已提交
1767

1768
			}
1769

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

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

1774 1775 1776 1777
				v1 = vertices[ face.a ];
				v2 = vertices[ face.b ];
				v3 = vertices[ face.c ];
				v4 = vertices[ face.d ];
1778

A
alteredq 已提交
1779 1780 1781
				vertexArray[ offset ]     = v1.x;
				vertexArray[ offset + 1 ] = v1.y;
				vertexArray[ offset + 2 ] = v1.z;
1782

A
alteredq 已提交
1783 1784 1785
				vertexArray[ offset + 3 ] = v2.x;
				vertexArray[ offset + 4 ] = v2.y;
				vertexArray[ offset + 5 ] = v2.z;
1786

A
alteredq 已提交
1787 1788 1789
				vertexArray[ offset + 6 ] = v3.x;
				vertexArray[ offset + 7 ] = v3.y;
				vertexArray[ offset + 8 ] = v3.z;
1790

A
alteredq 已提交
1791 1792 1793
				vertexArray[ offset + 9 ]  = v4.x;
				vertexArray[ offset + 10 ] = v4.y;
				vertexArray[ offset + 11 ] = v4.z;
1794

A
alteredq 已提交
1795
				offset += 12;
1796

A
alteredq 已提交
1797
			}
1798

A
alteredq 已提交
1799 1800
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1801

A
alteredq 已提交
1802
		}
M
Mr.doob 已提交
1803

A
alteredq 已提交
1804
		if ( dirtyMorphTargets ) {
M
Mr.doob 已提交
1805

1806
			for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {
1807

1808
				offset_morphTarget = 0;
1809

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

A
alteredq 已提交
1812 1813 1814 1815
					chf = chunk_faces3[ f ];
					face = obj_faces[ chf ];

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

1817 1818 1819
					v1 = morphTargets[ vk ].vertices[ face.a ];
					v2 = morphTargets[ vk ].vertices[ face.b ];
					v3 = morphTargets[ vk ].vertices[ face.c ];
M
Mr.doob 已提交
1820

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

A
alteredq 已提交
1823 1824 1825
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
M
Mr.doob 已提交
1826

A
alteredq 已提交
1827 1828 1829
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
M
Mr.doob 已提交
1830

A
alteredq 已提交
1831 1832 1833
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
M
Mr.doob 已提交
1834

A
alteredq 已提交
1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872
					// 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;

					}

					//

1873
					offset_morphTarget += 9;
1874

1875
				}
1876

1877
				for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
1878

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

					// morph positions
1883

1884 1885 1886 1887
					v1 = morphTargets[ vk ].vertices[ face.a ];
					v2 = morphTargets[ vk ].vertices[ face.b ];
					v3 = morphTargets[ vk ].vertices[ face.c ];
					v4 = morphTargets[ vk ].vertices[ face.d ];
1888

1889
					vka = morphTargetsArrays[ vk ];
1890

1891 1892 1893
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
1894

1895 1896 1897
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
1898

1899 1900 1901
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
1902

A
alteredq 已提交
1903 1904 1905 1906
					vka[ offset_morphTarget + 9 ]  = v4.x;
					vka[ offset_morphTarget + 10 ] = v4.y;
					vka[ offset_morphTarget + 11 ] = v4.z;

A
alteredq 已提交
1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950
					// 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;

					}

					//

1951
					offset_morphTarget += 12;
A
alteredq 已提交
1952

1953
				}
A
alteredq 已提交
1954 1955 1956

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

A
alteredq 已提交
1958 1959 1960 1961 1962 1963 1964
				if ( material.morphNormals ) {

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

				}

1965
			}
1966

A
alteredq 已提交
1967 1968 1969 1970 1971 1972 1973
		}

		if ( obj_skinWeights.length ) {

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

				face = obj_faces[ chunk_faces3[ f ]	];
1974

1975
				// weights
A
alteredq 已提交
1976

1977 1978 1979
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
A
alteredq 已提交
1980

1981 1982 1983 1984
				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 已提交
1985

1986 1987 1988 1989
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1990

1991 1992 1993 1994
				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 已提交
1995

1996
				// indices
A
alteredq 已提交
1997

1998 1999 2000
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
A
alteredq 已提交
2001

2002 2003 2004 2005
				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 已提交
2006

2007 2008 2009 2010
				skinIndexArray[ offset_skin + 4 ] = si2.x;
				skinIndexArray[ offset_skin + 5 ] = si2.y;
				skinIndexArray[ offset_skin + 6 ] = si2.z;
				skinIndexArray[ offset_skin + 7 ] = si2.w;
2011

2012 2013 2014 2015
				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 已提交
2016

2017
				offset_skin += 12;
2018

2019
			}
2020

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

A
alteredq 已提交
2023
				face = obj_faces[ chunk_faces4[ f ] ];
2024

A
alteredq 已提交
2025
				// weights
2026

A
alteredq 已提交
2027 2028 2029 2030
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
				sw4 = obj_skinWeights[ face.d ];
2031

A
alteredq 已提交
2032 2033 2034 2035
				skinWeightArray[ offset_skin ]     = sw1.x;
				skinWeightArray[ offset_skin + 1 ] = sw1.y;
				skinWeightArray[ offset_skin + 2 ] = sw1.z;
				skinWeightArray[ offset_skin + 3 ] = sw1.w;
2036

A
alteredq 已提交
2037 2038 2039 2040
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
2041

A
alteredq 已提交
2042 2043 2044 2045
				skinWeightArray[ offset_skin + 8 ]  = sw3.x;
				skinWeightArray[ offset_skin + 9 ]  = sw3.y;
				skinWeightArray[ offset_skin + 10 ] = sw3.z;
				skinWeightArray[ offset_skin + 11 ] = sw3.w;
2046

A
alteredq 已提交
2047 2048 2049 2050
				skinWeightArray[ offset_skin + 12 ] = sw4.x;
				skinWeightArray[ offset_skin + 13 ] = sw4.y;
				skinWeightArray[ offset_skin + 14 ] = sw4.z;
				skinWeightArray[ offset_skin + 15 ] = sw4.w;
2051

A
alteredq 已提交
2052
				// indices
2053

A
alteredq 已提交
2054 2055 2056 2057
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
				si4 = obj_skinIndices[ face.d ];
2058

A
alteredq 已提交
2059 2060 2061 2062
				skinIndexArray[ offset_skin ]     = si1.x;
				skinIndexArray[ offset_skin + 1 ] = si1.y;
				skinIndexArray[ offset_skin + 2 ] = si1.z;
				skinIndexArray[ offset_skin + 3 ] = si1.w;
2063

A
alteredq 已提交
2064 2065 2066 2067
				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 已提交
2068

A
alteredq 已提交
2069 2070 2071 2072
				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 已提交
2073

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

A
alteredq 已提交
2079
				offset_skin += 16;
M
Mr.doob 已提交
2080

A
alteredq 已提交
2081
			}
M
Mr.doob 已提交
2082

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

A
alteredq 已提交
2085 2086 2087 2088 2089
				_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 );
2090

2091
			}
2092

A
alteredq 已提交
2093
		}
M
Mr.doob 已提交
2094

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

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

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

A
alteredq 已提交
2101 2102
				vertexColors = face.vertexColors;
				faceColor = face.color;
2103

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

A
alteredq 已提交
2106 2107 2108
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
2109

A
alteredq 已提交
2110
				} else {
2111

A
alteredq 已提交
2112 2113 2114
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
2115

A
alteredq 已提交
2116
				}
2117

A
alteredq 已提交
2118 2119 2120
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
2121

A
alteredq 已提交
2122 2123 2124
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
2125

A
alteredq 已提交
2126 2127 2128
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
2129

A
alteredq 已提交
2130
				offset_color += 9;
M
Mr.doob 已提交
2131

A
alteredq 已提交
2132
			}
M
Mr.doob 已提交
2133

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

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

A
alteredq 已提交
2138 2139
				vertexColors = face.vertexColors;
				faceColor = face.color;
M
Mr.doob 已提交
2140

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

A
alteredq 已提交
2143 2144 2145 2146
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
					c4 = vertexColors[ 3 ];
2147

A
alteredq 已提交
2148
				} else {
M
Mr.doob 已提交
2149

A
alteredq 已提交
2150 2151 2152 2153
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
					c4 = faceColor;
M
Mr.doob 已提交
2154

A
alteredq 已提交
2155
				}
2156

A
alteredq 已提交
2157 2158 2159
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
2160

A
alteredq 已提交
2161 2162 2163
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
M
Mr.doob 已提交
2164

A
alteredq 已提交
2165 2166 2167
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
M
Mr.doob 已提交
2168

A
alteredq 已提交
2169 2170 2171
				colorArray[ offset_color + 9 ]  = c4.r;
				colorArray[ offset_color + 10 ] = c4.g;
				colorArray[ offset_color + 11 ] = c4.b;
M
Mr.doob 已提交
2172

A
alteredq 已提交
2173
				offset_color += 12;
2174

2175
			}
2176

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

A
alteredq 已提交
2179 2180
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
M
Mr.doob 已提交
2181

2182
			}
2183

A
alteredq 已提交
2184
		}
M
Mr.doob 已提交
2185

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

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

A
alteredq 已提交
2190
				face = obj_faces[ chunk_faces3[ f ]	];
2191

A
alteredq 已提交
2192
				vertexTangents = face.vertexTangents;
M
Mr.doob 已提交
2193

A
alteredq 已提交
2194 2195 2196
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
2197

A
alteredq 已提交
2198 2199 2200 2201
				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 已提交
2202

A
alteredq 已提交
2203 2204 2205 2206
				tangentArray[ offset_tangent + 4 ] = t2.x;
				tangentArray[ offset_tangent + 5 ] = t2.y;
				tangentArray[ offset_tangent + 6 ] = t2.z;
				tangentArray[ offset_tangent + 7 ] = t2.w;
2207

A
alteredq 已提交
2208 2209 2210 2211
				tangentArray[ offset_tangent + 8 ]  = t3.x;
				tangentArray[ offset_tangent + 9 ]  = t3.y;
				tangentArray[ offset_tangent + 10 ] = t3.z;
				tangentArray[ offset_tangent + 11 ] = t3.w;
2212

A
alteredq 已提交
2213
				offset_tangent += 12;
2214

2215
			}
2216

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

A
alteredq 已提交
2219
				face = obj_faces[ chunk_faces4[ f ] ];
2220

A
alteredq 已提交
2221
				vertexTangents = face.vertexTangents;
2222

A
alteredq 已提交
2223 2224 2225 2226
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
				t4 = vertexTangents[ 3 ];
2227

A
alteredq 已提交
2228 2229 2230 2231
				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 已提交
2232

A
alteredq 已提交
2233 2234 2235 2236
				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 已提交
2237

A
alteredq 已提交
2238 2239 2240 2241
				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 已提交
2242

A
alteredq 已提交
2243 2244 2245 2246
				tangentArray[ offset_tangent + 12 ] = t4.x;
				tangentArray[ offset_tangent + 13 ] = t4.y;
				tangentArray[ offset_tangent + 14 ] = t4.z;
				tangentArray[ offset_tangent + 15 ] = t4.w;
2247

A
alteredq 已提交
2248
				offset_tangent += 16;
2249

A
alteredq 已提交
2250
			}
2251

A
alteredq 已提交
2252 2253
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
2254

A
alteredq 已提交
2255
		}
2256

A
alteredq 已提交
2257
		if ( dirtyNormals && normalType ) {
2258

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

A
alteredq 已提交
2261
				face = obj_faces[ chunk_faces3[ f ]	];
2262

A
alteredq 已提交
2263 2264
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
2265

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

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

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

A
alteredq 已提交
2272 2273 2274
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
2275

A
alteredq 已提交
2276
						offset_normal += 3;
2277

A
alteredq 已提交
2278
					}
2279

A
alteredq 已提交
2280
				} else {
M
Mr.doob 已提交
2281

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

A
alteredq 已提交
2284 2285 2286
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
2287

A
alteredq 已提交
2288
						offset_normal += 3;
M
Mr.doob 已提交
2289

A
alteredq 已提交
2290
					}
2291

A
alteredq 已提交
2292
				}
2293

A
alteredq 已提交
2294
			}
2295

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

A
alteredq 已提交
2298
				face = obj_faces[ chunk_faces4[ f ] ];
2299

A
alteredq 已提交
2300 2301
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
2302

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

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

A
alteredq 已提交
2307
						vn = vertexNormals[ i ];
2308

A
alteredq 已提交
2309 2310 2311
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
2312

A
alteredq 已提交
2313
						offset_normal += 3;
2314

A
alteredq 已提交
2315
					}
M
Mr.doob 已提交
2316

A
alteredq 已提交
2317
				} else {
2318

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

A
alteredq 已提交
2321 2322 2323
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
2324

A
alteredq 已提交
2325
						offset_normal += 3;
M
Mr.doob 已提交
2326

A
alteredq 已提交
2327
					}
2328

A
alteredq 已提交
2329
				}
2330

A
alteredq 已提交
2331
			}
M
Mr.doob 已提交
2332

A
alteredq 已提交
2333 2334
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
2335

A
alteredq 已提交
2336
		}
M
Mr.doob 已提交
2337

A
alteredq 已提交
2338
		if ( dirtyUvs && obj_uvs && uvType ) {
2339

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

A
alteredq 已提交
2342
				fi = chunk_faces3[ f ];
2343

A
alteredq 已提交
2344
				uv = obj_uvs[ fi ];
2345

A
alteredq 已提交
2346
				if ( uv === undefined ) continue;
2347

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

A
alteredq 已提交
2350
					uvi = uv[ i ];
2351

A
alteredq 已提交
2352 2353
					uvArray[ offset_uv ]     = uvi.u;
					uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
2354

A
alteredq 已提交
2355
					offset_uv += 2;
M
Mr.doob 已提交
2356

A
alteredq 已提交
2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376
				}

			}

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

				fi = chunk_faces4[ f ];

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

2378 2379
				}

2380
			}
2381

A
alteredq 已提交
2382
			if ( offset_uv > 0 ) {
2383

A
alteredq 已提交
2384 2385
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
2386

A
alteredq 已提交
2387
			}
2388

A
alteredq 已提交
2389
		}
2390

A
alteredq 已提交
2391
		if ( dirtyUvs && obj_uvs2 && uvType ) {
2392

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

A
alteredq 已提交
2395
				fi = chunk_faces3[ f ];
2396

A
alteredq 已提交
2397
				uv2 = obj_uvs2[ fi ];
2398

A
alteredq 已提交
2399 2400 2401 2402 2403 2404 2405 2406 2407 2408
				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;
2409

2410 2411
				}

A
alteredq 已提交
2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431
			}

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

				fi = chunk_faces4[ f ];

				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;

				}
2432

2433
			}
2434

A
alteredq 已提交
2435
			if ( offset_uv2 > 0 ) {
2436

A
alteredq 已提交
2437 2438
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );
2439

A
alteredq 已提交
2440
			}
2441

A
alteredq 已提交
2442
		}
2443

A
alteredq 已提交
2444
		if ( dirtyElements ) {
2445

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

A
alteredq 已提交
2448 2449 2450
				faceArray[ offset_face ] 	 = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 2;
2451

A
alteredq 已提交
2452
				offset_face += 3;
2453

A
alteredq 已提交
2454 2455
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2456

A
alteredq 已提交
2457 2458
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 2;
2459

A
alteredq 已提交
2460 2461
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
2462

A
alteredq 已提交
2463
				offset_line += 6;
2464

A
alteredq 已提交
2465
				vertexIndex += 3;
2466

A
alteredq 已提交
2467
			}
2468

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

A
alteredq 已提交
2471 2472 2473
				faceArray[ offset_face ]     = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 3;
2474

A
alteredq 已提交
2475 2476 2477
				faceArray[ offset_face + 3 ] = vertexIndex + 1;
				faceArray[ offset_face + 4 ] = vertexIndex + 2;
				faceArray[ offset_face + 5 ] = vertexIndex + 3;
2478

A
alteredq 已提交
2479
				offset_face += 6;
2480

A
alteredq 已提交
2481 2482
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2483

A
alteredq 已提交
2484 2485
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 3;
2486

A
alteredq 已提交
2487 2488
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
2489

A
alteredq 已提交
2490 2491
				lineArray[ offset_line + 6 ] = vertexIndex + 2;
				lineArray[ offset_line + 7 ] = vertexIndex + 3;
2492

A
alteredq 已提交
2493
				offset_line += 8;
2494

A
alteredq 已提交
2495
				vertexIndex += 4;
2496

2497
			}
2498

A
alteredq 已提交
2499 2500
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
2501

A
alteredq 已提交
2502 2503
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
2504

A
alteredq 已提交
2505
		}
2506

A
alteredq 已提交
2507
		if ( customAttributes ) {
2508

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

2511
				customAttribute = customAttributes[ i ];
2512

2513
				if ( ! customAttribute.__original.needsUpdate ) continue;
2514

2515 2516
				offset_custom = 0;
				offset_customSrc = 0;
2517

2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550
				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 ++ ) {

2551
							value = customAttribute.value[ chunk_faces3[ f ] ];
2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562

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

2563
							value = customAttribute.value[ chunk_faces4[ f ] ];
2564 2565 2566 2567 2568 2569 2570 2571 2572

							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;

						}
2573

2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592
					}

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

2594 2595
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2596

2597
							offset_custom += 6;
A
alteredq 已提交
2598

2599
						}
A
alteredq 已提交
2600

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

2603
							face = obj_faces[ chunk_faces4[ f ] ];
A
alteredq 已提交
2604

2605 2606 2607 2608
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
A
alteredq 已提交
2609

2610 2611
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2612

2613 2614
							customAttribute.array[ offset_custom + 2 ] = v2.x;
							customAttribute.array[ offset_custom + 3 ] = v2.y;
A
alteredq 已提交
2615

2616 2617
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2618

2619 2620
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
A
alteredq 已提交
2621

2622
							offset_custom += 8;
A
alteredq 已提交
2623

2624
						}
A
alteredq 已提交
2625

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

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

2630
							value = customAttribute.value[ chunk_faces3[ f ] ];
A
alteredq 已提交
2631

2632 2633 2634
							v1 = value;
							v2 = value;
							v3 = value;
A
alteredq 已提交
2635

2636 2637
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2638

2639 2640
							customAttribute.array[ offset_custom + 2 ] = v2.x;
							customAttribute.array[ offset_custom + 3 ] = v2.y;
A
alteredq 已提交
2641

2642 2643
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2644

2645
							offset_custom += 6;
A
alteredq 已提交
2646

2647
						}
A
alteredq 已提交
2648

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

2651
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2652

2653 2654 2655 2656
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2657

2658 2659
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2660

2661 2662
							customAttribute.array[ offset_custom + 2 ] = v2.x;
							customAttribute.array[ offset_custom + 3 ] = v2.y;
A
alteredq 已提交
2663

2664 2665
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2666

2667 2668
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
2669

2670
							offset_custom += 8;
M
Mr.doob 已提交
2671

2672
						}
M
Mr.doob 已提交
2673

M
Mr.doob 已提交
2674
					}
M
Mr.doob 已提交
2675

2676
				} else if ( customAttribute.size === 3 ) {
2677

2678
					var pp;
2679

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

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

2684
					} else {
M
Mr.doob 已提交
2685

2686
						pp = [ "x", "y", "z" ];
2687

2688
					}
2689

2690
					if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
2691

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

2694
							face = obj_faces[ chunk_faces3[ f ]	];
2695

2696 2697 2698
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
2699

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

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

2708 2709 2710
							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 已提交
2711

2712
							offset_custom += 9;
M
Mr.doob 已提交
2713

2714
						}
M
Mr.doob 已提交
2715

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

2718
							face = obj_faces[ chunk_faces4[ f ] ];
M
Mr.doob 已提交
2719

2720 2721 2722 2723
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
M
Mr.doob 已提交
2724

2725 2726 2727
							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 已提交
2728

2729 2730 2731
							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 已提交
2732

2733 2734 2735
							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 已提交
2736

2737 2738 2739
							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 已提交
2740

2741
							offset_custom += 12;
M
Mr.doob 已提交
2742

2743
						}
M
Mr.doob 已提交
2744

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

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

2749
							value = customAttribute.value[ chunk_faces3[ f ] ];
2750

2751 2752 2753
							v1 = value;
							v2 = value;
							v3 = value;
M
Mr.doob 已提交
2754

2755 2756 2757
							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 已提交
2758

2759 2760 2761
							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 已提交
2762

2763 2764 2765
							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 已提交
2766

2767
							offset_custom += 9;
M
Mr.doob 已提交
2768

2769
						}
2770

2771
						for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
2772

2773
							value = customAttribute.value[ chunk_faces4[ f ] ];
2774

2775 2776 2777 2778
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
2779

2780 2781 2782
							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
2783

2784
							customAttribute.array[ offset_custom + 3  ] = v2[ pp[ 0 ] ];
2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839
							customAttribute.array[ offset_custom + 4  ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5  ] = v2[ pp[ 2 ] ];

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

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

							offset_custom += 12;

						}

					} else if ( customAttribute.boundTo === "faceVertices" ) {

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

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

							v1 = value[ 0 ];
							v2 = value[ 1 ];
							v3 = value[ 2 ];

							customAttribute.array[ offset_custom ] 	   = v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];

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

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

							offset_custom += 9;

						}

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

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

							v1 = value[ 0 ];
							v2 = value[ 1 ];
							v3 = value[ 2 ];
							v4 = value[ 3 ];

							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];

							customAttribute.array[ offset_custom + 3  ] = v2[ pp[ 0 ] ];
2840 2841
							customAttribute.array[ offset_custom + 4  ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5  ] = v2[ pp[ 2 ] ];
2842

2843 2844 2845
							customAttribute.array[ offset_custom + 6  ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7  ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8  ] = v3[ pp[ 2 ] ];
2846

2847 2848 2849
							customAttribute.array[ offset_custom + 9  ] = v4[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];
2850

2851
							offset_custom += 12;
2852

2853
						}
2854

A
alteredq 已提交
2855
					}
M
Mr.doob 已提交
2856

2857
				} else if ( customAttribute.size === 4 ) {
2858

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

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

2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924
							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 ++ ) {

2925
							value = customAttribute.value[ chunk_faces3[ f ] ];
2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942

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

2946
							offset_custom += 12;
A
alteredq 已提交
2947

2948 2949
						}

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

2952
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2953

2954 2955 2956 2957
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2958

2959 2960 2961 2962
							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;
2963

2964 2965 2966 2967
							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;
2968

2969 2970 2971 2972
							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;
2973

2974 2975 2976 2977
							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;
2978 2979 2980 2981 2982 2983 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

							offset_custom += 16;

						}

					} else if ( customAttribute.boundTo === "faceVertices" ) {

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

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

							v1 = value[ 0 ];
							v2 = value[ 1 ];
							v3 = value[ 2 ];

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

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

							v1 = value[ 0 ];
							v2 = value[ 1 ];
							v3 = value[ 2 ];
							v4 = value[ 3 ];

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

3041
							offset_custom += 16;
A
alteredq 已提交
3042

3043
						}
A
alteredq 已提交
3044 3045 3046 3047 3048

					}

				}

3049 3050 3051
				_gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );

A
alteredq 已提交
3052 3053 3054 3055
			}

		}

3056
		if ( dispose ) {
3057

3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068
			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.__skinIndexArray;
			delete geometryGroup.__skinWeightArray;
A
alteredq 已提交
3069

3070
		}
A
alteredq 已提交
3071

3072
	};
A
alteredq 已提交
3073

3074 3075
	function setDirectBuffers ( geometry, hint, dispose ) {

3076
		var attributes = geometry.attributes;
3077

3078 3079 3080 3081 3082
		var index = attributes[ "index" ];
		var position = attributes[ "position" ];
		var normal = attributes[ "normal" ];
		var uv = attributes[ "uv" ];
		var color = attributes[ "color" ];
3083
		var tangent = attributes[ "tangent" ];
3084 3085 3086 3087 3088

		if ( geometry.elementsNeedUpdate && index !== undefined ) {

			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, index.array, hint );
3089 3090 3091

		}

3092
		if ( geometry.verticesNeedUpdate && position !== undefined ) {
3093

3094 3095
			_gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, position.array, hint );
3096 3097 3098

		}

3099
		if ( geometry.normalsNeedUpdate && normal !== undefined ) {
3100

3101 3102
			_gl.bindBuffer( _gl.ARRAY_BUFFER, normal.buffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, normal.array, hint );
3103 3104 3105

		}

3106
		if ( geometry.uvsNeedUpdate && uv !== undefined ) {
3107

3108 3109
			_gl.bindBuffer( _gl.ARRAY_BUFFER, uv.buffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, uv.array, hint );
3110 3111 3112

		}

3113
		if ( geometry.colorsNeedUpdate && color !== undefined ) {
3114

3115 3116
			_gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, color.array, hint );
3117 3118 3119

		}

3120 3121 3122 3123 3124 3125
		if ( geometry.tangentsNeedUpdate && tangent !== undefined ) {

			_gl.bindBuffer( _gl.ARRAY_BUFFER, tangent.buffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, tangent.array, hint );

		}
3126 3127 3128

		if ( dispose ) {

3129 3130 3131 3132 3133
			for ( var i in geometry.attributes ) {

				delete geometry.attributes[ i ].array;

			}
3134 3135 3136 3137 3138

		}

	};

3139
	// Buffer rendering
A
alteredq 已提交
3140

3141
	this.renderBufferImmediate = function ( object, program, material ) {
A
alteredq 已提交
3142

3143 3144 3145
		if ( object.hasPositions && ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( object.hasNormals && ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
		if ( object.hasUvs && ! object.__webglUvBuffer ) object.__webglUvBuffer = _gl.createBuffer();
3146
		if ( object.hasColors && ! object.__webglColorBuffer ) object.__webglColorBuffer = _gl.createBuffer();
A
alteredq 已提交
3147

3148
		if ( object.hasPositions ) {
A
alteredq 已提交
3149

3150 3151 3152 3153
			_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 已提交
3154 3155 3156

		}

3157
		if ( object.hasNormals ) {
A
alteredq 已提交
3158

3159
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
A
alteredq 已提交
3160

3161
			if ( material.shading === THREE.FlatShading ) {
3162

3163 3164 3165 3166
				var nx, ny, nz,
					nax, nbx, ncx, nay, nby, ncy, naz, nbz, ncz,
					normalArray,
					i, il = object.count * 3;
3167

3168
				for( i = 0; i < il; i += 9 ) {
3169

3170
					normalArray = object.normalArray;
3171

3172 3173 3174
					nax  = normalArray[ i ];
					nay  = normalArray[ i + 1 ];
					naz  = normalArray[ i + 2 ];
3175

3176 3177 3178
					nbx  = normalArray[ i + 3 ];
					nby  = normalArray[ i + 4 ];
					nbz  = normalArray[ i + 5 ];
3179

3180 3181 3182
					ncx  = normalArray[ i + 6 ];
					ncy  = normalArray[ i + 7 ];
					ncz  = normalArray[ i + 8 ];
3183

3184 3185 3186
					nx = ( nax + nbx + ncx ) / 3;
					ny = ( nay + nby + ncy ) / 3;
					nz = ( naz + nbz + ncz ) / 3;
3187

3188 3189 3190
					normalArray[ i ] 	 = nx;
					normalArray[ i + 1 ] = ny;
					normalArray[ i + 2 ] = nz;
3191

3192 3193 3194
					normalArray[ i + 3 ] = nx;
					normalArray[ i + 4 ] = ny;
					normalArray[ i + 5 ] = nz;
3195

3196 3197 3198
					normalArray[ i + 6 ] = nx;
					normalArray[ i + 7 ] = ny;
					normalArray[ i + 8 ] = nz;
3199

3200
				}
3201

3202
			}
3203

3204 3205 3206
			_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 );
3207

3208
		}
3209

3210
		if ( object.hasUvs && material.map ) {
3211 3212 3213 3214 3215 3216 3217 3218

			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglUvBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
			_gl.enableVertexAttribArray( program.attributes.uv );
			_gl.vertexAttribPointer( program.attributes.uv, 2, _gl.FLOAT, false, 0, 0 );

		}

3219 3220 3221 3222 3223 3224 3225 3226 3227
		if ( object.hasColors && material.vertexColors !== THREE.NoColors ) {

			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglColorBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
			_gl.enableVertexAttribArray( program.attributes.color );
			_gl.vertexAttribPointer( program.attributes.color, 3, _gl.FLOAT, false, 0, 0 );

		}

3228
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );
3229

3230
		object.count = 0;
3231

3232
	};
3233

3234
	this.renderBufferDirect = function ( camera, lights, fog, material, geometry, object ) {
3235

3236 3237
		if ( material.visible === false ) return;

3238
		var program, attributes, linewidth, primitives, a, attribute;
3239 3240 3241 3242 3243 3244 3245

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

		attributes = program.attributes;

		var updateBuffers = false,
			wireframeBit = material.wireframe ? 1 : 0,
3246
			geometryHash = ( geometry.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit;
3247

3248
		if ( geometryHash !== _currentGeometryGroupHash ) {
3249

3250
			_currentGeometryGroupHash = geometryHash;
3251 3252 3253 3254
			updateBuffers = true;

		}

3255 3256 3257 3258 3259 3260
		if ( updateBuffers ) {

			disableAttributes();

		}

3261 3262 3263 3264
		// render mesh

		if ( object instanceof THREE.Mesh ) {

3265
			var index = geometry.attributes[ "index" ];
3266

3267
			// indexed triangles
3268

3269
			if ( index ) {
3270

3271
				var offsets = geometry.offsets;
3272

3273 3274 3275
				// if there is more than 1 chunk
				// must set attribute pointers to use new offsets for each chunk
				// even if geometry and materials didn't change
3276

3277
				if ( offsets.length > 1 ) updateBuffers = true;
3278

3279
				for ( var i = 0, il = offsets.length; i < il; i ++ ) {
3280

3281
					var startIndex = offsets[ i ].index;
3282

3283
					if ( updateBuffers ) {
3284

3285
						// vertices
3286

3287 3288
						var position = geometry.attributes[ "position" ];
						var positionSize = position.itemSize;
3289

3290 3291 3292
						_gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
						enableAttribute( attributes.position );
						_gl.vertexAttribPointer( attributes.position, positionSize, _gl.FLOAT, false, 0, startIndex * positionSize * 4 ); // 4 bytes per Float32
3293

3294
						// normals
3295

3296
						var normal = geometry.attributes[ "normal" ];
3297

3298
						if ( attributes.normal >= 0 && normal ) {
3299

3300
							var normalSize = normal.itemSize;
3301

3302 3303 3304
							_gl.bindBuffer( _gl.ARRAY_BUFFER, normal.buffer );
							enableAttribute( attributes.normal );
							_gl.vertexAttribPointer( attributes.normal, normalSize, _gl.FLOAT, false, 0, startIndex * normalSize * 4 );
3305

3306
						}
3307

3308
						// uvs
3309

3310
						var uv = geometry.attributes[ "uv" ];
3311

3312
						if ( attributes.uv >= 0 && uv ) {
3313

3314
							var uvSize = uv.itemSize;
3315

3316 3317 3318
							_gl.bindBuffer( _gl.ARRAY_BUFFER, uv.buffer );
							enableAttribute( attributes.uv );
							_gl.vertexAttribPointer( attributes.uv, uvSize, _gl.FLOAT, false, 0, startIndex * uvSize * 4 );
3319

3320
						}
3321

3322
						// colors
3323

3324
						var color = geometry.attributes[ "color" ];
3325

3326
						if ( attributes.color >= 0 && color ) {
3327

3328
							var colorSize = color.itemSize;
3329

3330 3331 3332
							_gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
							enableAttribute( attributes.color );
							_gl.vertexAttribPointer( attributes.color, colorSize, _gl.FLOAT, false, 0, startIndex * colorSize * 4 );
3333

3334
						}
3335

3336
						// tangents
3337

3338
						var tangent = geometry.attributes[ "tangent" ];
3339

3340
						if ( attributes.tangent >= 0 && tangent ) {
3341

3342
							var tangentSize = tangent.itemSize;
3343

3344 3345 3346
							_gl.bindBuffer( _gl.ARRAY_BUFFER, tangent.buffer );
							enableAttribute( attributes.tangent );
							_gl.vertexAttribPointer( attributes.tangent, tangentSize, _gl.FLOAT, false, 0, startIndex * tangentSize * 4 );
3347

3348
						}
3349

3350
						// indices
3351

3352
						_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
3353

3354
					}
3355

3356
					// render indexed triangles
3357

3358
					_gl.drawElements( _gl.TRIANGLES, offsets[ i ].count, _gl.UNSIGNED_SHORT, offsets[ i ].start * 2 ); // 2 bytes per Uint16
B
Ben Adams 已提交
3359

3360 3361 3362
					_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;
B
Ben Adams 已提交
3363

3364
				}
B
Ben Adams 已提交
3365

3366
			// non-indexed triangles
B
Ben Adams 已提交
3367

3368
			} else {
B
Ben Adams 已提交
3369

3370
				if ( updateBuffers ) {
B
Ben Adams 已提交
3371

3372
					// vertices
B
Ben Adams 已提交
3373

3374 3375
					var position = geometry.attributes[ "position" ];
					var positionSize = position.itemSize;
B
Ben Adams 已提交
3376

3377 3378 3379
					_gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
					enableAttribute( attributes.position );
					_gl.vertexAttribPointer( attributes.position, positionSize, _gl.FLOAT, false, 0, 0 );
B
Ben Adams 已提交
3380

3381
					// normals
B
Ben Adams 已提交
3382

3383
					var normal = geometry.attributes[ "normal" ];
B
Ben Adams 已提交
3384

3385
					if ( attributes.normal >= 0 && normal ) {
B
Ben Adams 已提交
3386

3387
						var normalSize = normal.itemSize;
B
Ben Adams 已提交
3388

3389 3390 3391
						_gl.bindBuffer( _gl.ARRAY_BUFFER, normal.buffer );
						enableAttribute( attributes.normal );
						_gl.vertexAttribPointer( attributes.normal, normalSize, _gl.FLOAT, false, 0, 0 );
B
Ben Adams 已提交
3392

3393
					}
B
Ben Adams 已提交
3394

3395
					// uvs
B
Ben Adams 已提交
3396

3397
					var uv = geometry.attributes[ "uv" ];
B
Ben Adams 已提交
3398

3399
					if ( attributes.uv >= 0 && uv ) {
B
Ben Adams 已提交
3400

3401
						var uvSize = uv.itemSize;
B
Ben Adams 已提交
3402

3403 3404 3405
						_gl.bindBuffer( _gl.ARRAY_BUFFER, uv.buffer );
						enableAttribute( attributes.uv );
						_gl.vertexAttribPointer( attributes.uv, uvSize, _gl.FLOAT, false, 0, 0 );
B
Ben Adams 已提交
3406

3407
					}
B
Ben Adams 已提交
3408

3409
					// colors
B
Ben Adams 已提交
3410

3411
					var color = geometry.attributes[ "color" ];
B
Ben Adams 已提交
3412

3413
					if ( attributes.color >= 0 && color ) {
B
Ben Adams 已提交
3414

3415
						var colorSize = color.itemSize;
B
Ben Adams 已提交
3416

3417 3418 3419 3420 3421
						_gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
						enableAttribute( attributes.color );
						_gl.vertexAttribPointer( attributes.color, colorSize, _gl.FLOAT, false, 0, 0 );

					}
B
Ben Adams 已提交
3422

3423
					// tangents
B
Ben Adams 已提交
3424

3425
					var tangent = geometry.attributes[ "tangent" ];
B
Ben Adams 已提交
3426

3427
					if ( attributes.tangent >= 0 && tangent ) {
B
Ben Adams 已提交
3428

3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447
						var tangentSize = tangent.itemSize;

						_gl.bindBuffer( _gl.ARRAY_BUFFER, tangent.buffer );
						enableAttribute( attributes.tangent );
						_gl.vertexAttribPointer( attributes.tangent, tangentSize, _gl.FLOAT, false, 0, 0 );

					}

				}

				// render non-indexed triangles

				_gl.drawArrays( _gl.TRIANGLES, 0, position.numItems / 3 );

				_this.info.render.calls ++;
				_this.info.render.vertices += position.numItems / 3;
				_this.info.render.faces += position.numItems / 3 / 3;

			}
3448

3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460
		// render particles

		} else if ( object instanceof THREE.ParticleSystem ) {

			if ( updateBuffers ) {

				// vertices

				var position = geometry.attributes[ "position" ];
				var positionSize = position.itemSize;

				_gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
3461
				enableAttribute( attributes.position );
3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472
				_gl.vertexAttribPointer( attributes.position, positionSize, _gl.FLOAT, false, 0, 0 );

				// colors

				var color = geometry.attributes[ "color" ];

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

					var colorSize = color.itemSize;

					_gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
3473
					enableAttribute( attributes.color );
3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486
					_gl.vertexAttribPointer( attributes.color, colorSize, _gl.FLOAT, false, 0, 0 );

				}

				// render particles

				_gl.drawArrays( _gl.POINTS, 0, position.numItems / 3 );

				_this.info.render.calls ++;
				_this.info.render.points += position.numItems / 3;

			}

3487 3488 3489 3490
		}

	};

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

3493 3494
		if ( material.visible === false ) return;

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

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

3499
		attributes = program.attributes;
3500

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

3505
		if ( geometryGroupHash !== _currentGeometryGroupHash ) {
A
alteredq 已提交
3506

3507 3508
			_currentGeometryGroupHash = geometryGroupHash;
			updateBuffers = true;
3509

3510
		}
3511

3512 3513 3514 3515 3516 3517
		if ( updateBuffers ) {

			disableAttributes();

		}

3518
		// vertices
3519

3520
		if ( !material.morphTargets && attributes.position >= 0 ) {
3521

3522
			if ( updateBuffers ) {
3523

3524
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
3525
				enableAttribute( attributes.position );
3526
				_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3527

3528
			}
3529

3530
		} else {
3531

3532
			if ( object.morphTargetBase ) {
3533

3534
				setupMorphTargets( material, geometryGroup, object );
3535

3536
			}
3537

3538
		}
3539

3540

3541
		if ( updateBuffers ) {
3542

3543
			// custom attributes
3544

3545
			// Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
3546

3547
			if ( geometryGroup.__webglCustomAttributesList ) {
3548

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

3551
					attribute = geometryGroup.__webglCustomAttributesList[ i ];
3552

3553
					if ( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
3554

3555
						_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
3556
						enableAttribute( attributes[ attribute.buffer.belongsToAttribute ] );
3557
						_gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 );
3558

3559
					}
3560

3561
				}
3562

3563
			}
3564 3565


3566
			// colors
3567

3568
			if ( attributes.color >= 0 ) {
3569

3570
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
3571
				enableAttribute( attributes.color );
3572
				_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
3573

3574
			}
3575

3576
			// normals
3577

3578
			if ( attributes.normal >= 0 ) {
3579

3580
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
3581
				enableAttribute( attributes.normal );
3582
				_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
3583

3584
			}
3585

3586
			// tangents
3587

3588
			if ( attributes.tangent >= 0 ) {
3589

3590
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
3591
				enableAttribute( attributes.tangent );
3592
				_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
3593

3594
			}
3595

3596
			// uvs
3597

3598
			if ( attributes.uv >= 0 ) {
3599

3600 3601 3602
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
				enableAttribute( attributes.uv );
				_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
3603 3604 3605

			}

3606
			if ( attributes.uv2 >= 0 ) {
3607

3608 3609 3610
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
				enableAttribute( attributes.uv2 );
				_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
3611 3612

			}
3613

3614 3615
			if ( material.skinning &&
				 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
A
alteredq 已提交
3616

3617
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
3618
				enableAttribute( attributes.skinIndex );
3619
				_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3620

3621
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
3622
				enableAttribute( attributes.skinWeight );
3623
				_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
3624

A
alteredq 已提交
3625
			}
3626

3627 3628 3629 3630 3631
			// line distances

			if ( attributes.lineDistance >= 0 ) {

				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglLineDistanceBuffer );
3632
				enableAttribute( attributes.lineDistance );
3633 3634 3635 3636
				_gl.vertexAttribPointer( attributes.lineDistance, 1, _gl.FLOAT, false, 0, 0 );

			}

3637
		}
3638

3639
		// render mesh
3640

3641
		if ( object instanceof THREE.Mesh ) {
3642

3643
			// wireframe
3644

3645
			if ( material.wireframe ) {
3646

3647
				setLineWidth( material.wireframeLinewidth );
3648

3649 3650
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
3651

3652
			// triangles
3653

3654
			} else {
3655

3656 3657
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3658

3659
			}
3660

3661 3662 3663
			_this.info.render.calls ++;
			_this.info.render.vertices += geometryGroup.__webglFaceCount;
			_this.info.render.faces += geometryGroup.__webglFaceCount / 3;
3664

3665
		// render lines
3666

3667
		} else if ( object instanceof THREE.Line ) {
3668

3669
			primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
3670

3671
			setLineWidth( material.linewidth );
3672

3673
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
3674

3675
			_this.info.render.calls ++;
3676

3677
		// render particles
3678

3679
		} else if ( object instanceof THREE.ParticleSystem ) {
3680

3681
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
3682

3683
			_this.info.render.calls ++;
3684
			_this.info.render.points += geometryGroup.__webglParticleCount;
3685

3686
		// render ribbon
3687

3688
		} else if ( object instanceof THREE.Ribbon ) {
3689

3690
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
3691

3692
			_this.info.render.calls ++;
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 3719 3720 3721 3722 3723
	function enableAttribute( attribute ) {

		if ( ! _enabledAttributes[ attribute ] ) {

			_gl.enableVertexAttribArray( attribute );
			_enabledAttributes[ attribute ] = true;

		}

	};

	function disableAttributes() {

		for ( var attribute in _enabledAttributes ) {

			if ( _enabledAttributes[ attribute ] ) {

				_gl.disableVertexAttribArray( attribute );
				_enabledAttributes[ attribute ] = false;

			}

		}

	};

3724
	function setupMorphTargets ( material, geometryGroup, object ) {
3725

3726
		// set base
3727

3728
		var attributes = material.program.attributes;
3729

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

3732
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] );
3733
			enableAttribute( attributes.position );
3734
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3735

3736
		} else if ( attributes.position >= 0 ) {
3737

3738
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
3739
			enableAttribute( attributes.position );
3740
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3741

3742
		}
3743

3744
		if ( object.morphTargetForcedOrder.length ) {
3745

3746
			// set forced order
3747

3748 3749 3750 3751 3752
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;

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

3754
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ order[ m ] ] );
3755
				enableAttribute( attributes[ "morphTarget" + m ] );
3756 3757
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );

A
alteredq 已提交
3758 3759 3760
				if ( material.morphNormals ) {

					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ order[ m ] ] );
3761
					enableAttribute( attributes[ "morphNormal" + m ] );
A
alteredq 已提交
3762 3763 3764 3765
					_gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 );

				}

3766 3767 3768
				object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ] ];

				m ++;
3769 3770
			}

3771 3772
		} else {

A
alteredq 已提交
3773
			// find the most influencing
3774

A
alteredq 已提交
3775
			var influence, activeInfluenceIndices = [];
3776 3777
			var influences = object.morphTargetInfluences;
			var i, il = influences.length;
3778

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

A
alteredq 已提交
3781 3782 3783 3784
				influence = influences[ i ];

				if ( influence > 0 ) {

3785
					activeInfluenceIndices.push( [ i, influence ] );
3786

I
ide user ide_gero3 已提交
3787
				}
A
alteredq 已提交
3788

I
ide user ide_gero3 已提交
3789
			}
A
alteredq 已提交
3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801

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

3802
				activeInfluenceIndices.push( [ 0, 0 ] );
A
alteredq 已提交
3803 3804 3805 3806

			};

			var influenceIndex, m = 0;
3807

3808
			while ( m < material.numSupportedMorphTargets ) {
3809

3810
				if ( activeInfluenceIndices[ m ] ) {
3811 3812 3813

					influenceIndex = activeInfluenceIndices[ m ][ 0 ];

A
alteredq 已提交
3814
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ influenceIndex ] );
3815
					enableAttribute( attributes[ "morphTarget" + m ] );
A
alteredq 已提交
3816
					_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
3817

A
alteredq 已提交
3818 3819 3820
					if ( material.morphNormals ) {

						_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ influenceIndex ] );
3821
						enableAttribute( attributes[ "morphNormal" + m ] );
A
alteredq 已提交
3822 3823 3824 3825 3826 3827 3828 3829 3830
						_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 );
3831

A
alteredq 已提交
3832
					if ( material.morphNormals ) {
3833

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

3836
					}
3837

A
alteredq 已提交
3838 3839
					object.__webglMorphTargetInfluences[ m ] = 0;

3840
				}
A
alteredq 已提交
3841

3842
				m ++;
3843 3844 3845 3846 3847

			}

		}

3848
		// load updated influences uniform
3849

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

3852
			_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
3853

3854
		}
3855

3856
	};
3857

A
alteredq 已提交
3858
	// Sorting
3859

3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873
	function painterSortStable ( a, b ) {

		if ( a.z !== b.z ) {

			return b.z - a.z;

		} else {

			return b.id - a.id;

		}

	};

3874
	function numericalSort ( a, b ) {
A
alteredq 已提交
3875

3876
		return b[ 1 ] - a[ 1 ];
A
alteredq 已提交
3877 3878 3879 3880

	};


3881
	// Rendering
3882

3883
	this.render = function ( scene, camera, renderTarget, forceClear ) {
3884

M
Mr.doob 已提交
3885 3886 3887 3888 3889 3890 3891
		if ( camera instanceof THREE.Camera === false ) {

			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
			return;

		}

3892 3893 3894 3895 3896
		var i, il,

		webglObject, object,
		renderList,

3897
		lights = scene.__lights,
3898
		fog = scene.fog;
M
Mr.doob 已提交
3899

3900 3901
		// reset caching for this frame

3902
		_currentMaterialId = -1;
3903
		_lightsNeedUpdate = true;
3904

A
alteredq 已提交
3905
		// update scene graph
3906

3907
		if ( this.autoUpdateScene ) scene.updateMatrixWorld();
3908

A
alteredq 已提交
3909
		// update camera matrices and frustum
A
alteredq 已提交
3910

3911 3912
		if ( camera.parent === undefined ) camera.updateMatrixWorld();

3913
		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
A
alteredq 已提交
3914

3915
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
A
alteredq 已提交
3916
		_frustum.setFromMatrix( _projScreenMatrix );
3917

A
alteredq 已提交
3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932
		// 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 已提交
3933
		this.setRenderTarget( renderTarget );
3934

3935
		if ( this.autoClear || forceClear ) {
3936

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

3939
		}
M
Mr.doob 已提交
3940

3941
		// set matrices for regular objects (frustum culled)
3942

3943
		renderList = scene.__webglObjects;
3944

3945
		for ( i = 0, il = renderList.length; i < il; i ++ ) {
3946

3947
			webglObject = renderList[ i ];
3948
			object = webglObject.object;
3949

A
alteredq 已提交
3950 3951
			webglObject.render = false;

3952
			if ( object.visible ) {
3953

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

A
alteredq 已提交
3956
					setupMatrices( object, camera );
3957

3958
					unrollBufferMaterial( webglObject );
3959

3960
					webglObject.render = true;
3961

3962
					if ( this.sortObjects === true ) {
3963

3964
						if ( object.renderDepth !== null ) {
3965

3966
							webglObject.z = object.renderDepth;
M
Mr.doob 已提交
3967

3968
						} else {
M
Mr.doob 已提交
3969

3970
							_vector3.copy( object.matrixWorld.getPosition() );
3971
							_projScreenMatrix.multiplyVector3( _vector3 );
3972

3973
							webglObject.z = _vector3.z;
3974

3975
						}
M
Mr.doob 已提交
3976

3977 3978
						webglObject.id = object.id;

3979
					}
M
Mr.doob 已提交
3980

3981
				}
3982 3983

			}
3984 3985 3986

		}

3987
		if ( this.sortObjects ) {
M
Mr.doob 已提交
3988

3989
			renderList.sort( painterSortStable );
3990

3991
		}
3992

3993
		// set matrices for immediate objects
3994

3995
		renderList = scene.__webglObjectsImmediate;
3996

3997 3998 3999
		for ( i = 0, il = renderList.length; i < il; i ++ ) {

			webglObject = renderList[ i ];
4000
			object = webglObject.object;
4001

4002
			if ( object.visible ) {
4003

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

4006
				unrollImmediateBufferMaterial( webglObject );
M
Mr.doob 已提交
4007

4008
			}
M
Mr.doob 已提交
4009

4010
		}
4011

4012
		if ( scene.overrideMaterial ) {
4013

4014 4015 4016 4017 4018 4019
			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 );
4020

4021 4022
			renderObjects( scene.__webglObjects, false, "", camera, lights, fog, true, material );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "", camera, lights, fog, false, material );
M
Mr.doob 已提交
4023

4024
		} else {
4025

4026 4027
			var material = null;

4028
			// opaque pass (front-to-back order)
4029

4030
			this.setBlending( THREE.NormalBlending );
4031

4032 4033
			renderObjects( scene.__webglObjects, true, "opaque", camera, lights, fog, false, material );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "opaque", camera, lights, fog, false, material );
4034

4035
			// transparent pass (back-to-front order)
4036

4037 4038
			renderObjects( scene.__webglObjects, false, "transparent", camera, lights, fog, true, material );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "transparent", camera, lights, fog, true, material );
4039

4040
		}
4041

A
alteredq 已提交
4042
		// custom render plugins (post pass)
4043

A
alteredq 已提交
4044
		renderPlugins( this.renderPluginsPost, scene, camera );
4045 4046


4047
		// Generate mipmap if we're using any kind of mipmap filtering
4048

4049
		if ( renderTarget && renderTarget.generateMipmaps && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {
4050

4051
			updateRenderTargetMipmap( renderTarget );
4052

4053
		}
4054

4055 4056 4057
		// Ensure depth buffer writing is enabled so it can be cleared on next render

		this.setDepthTest( true );
4058
		this.setDepthWrite( true );
4059

4060
		// _gl.finish();
4061

4062
	};
4063

A
alteredq 已提交
4064 4065 4066 4067 4068 4069
	function renderPlugins( plugins, scene, camera ) {

		if ( ! plugins.length ) return;

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

4070 4071
			// reset state for plugin (to start from clean slate)

A
alteredq 已提交
4072
			_currentProgram = null;
4073
			_currentCamera = null;
4074

A
alteredq 已提交
4075 4076 4077
			_oldBlending = -1;
			_oldDepthTest = -1;
			_oldDepthWrite = -1;
4078 4079
			_oldDoubleSided = -1;
			_oldFlipSided = -1;
A
alteredq 已提交
4080 4081
			_currentGeometryGroupHash = -1;
			_currentMaterialId = -1;
4082

4083
			_lightsNeedUpdate = true;
A
alteredq 已提交
4084

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

4087 4088
			// reset state after plugin (anything could have changed)

A
alteredq 已提交
4089
			_currentProgram = null;
4090
			_currentCamera = null;
4091

A
alteredq 已提交
4092 4093 4094
			_oldBlending = -1;
			_oldDepthTest = -1;
			_oldDepthWrite = -1;
4095 4096
			_oldDoubleSided = -1;
			_oldFlipSided = -1;
A
alteredq 已提交
4097 4098
			_currentGeometryGroupHash = -1;
			_currentMaterialId = -1;
4099

4100
			_lightsNeedUpdate = true;
A
alteredq 已提交
4101 4102 4103 4104 4105

		}

	};

4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141
	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;

4142
					if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
4143

A
alteredq 已提交
4144
					_this.setDepthTest( material.depthTest );
4145
					_this.setDepthWrite( material.depthWrite );
4146 4147 4148 4149
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

4150
				_this.setMaterialFaces( material );
4151 4152 4153 4154 4155 4156 4157 4158 4159 4160

				if ( buffer instanceof THREE.BufferGeometry ) {

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

				} else {

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

				}
4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188

			}

		}

	};

	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;

4189
					if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
4190

A
alteredq 已提交
4191
					_this.setDepthTest( material.depthTest );
4192
					_this.setDepthWrite( material.depthWrite );
4193 4194 4195 4196
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

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

A
alteredq 已提交
4199
			}
4200

A
alteredq 已提交
4201
		}
4202

A
alteredq 已提交
4203
	};
4204

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

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

A
alteredq 已提交
4209
		_currentGeometryGroupHash = -1;
4210

4211
		_this.setMaterialFaces( material );
A
alteredq 已提交
4212 4213 4214 4215 4216 4217 4218

		if ( object.immediateRenderCallback ) {

			object.immediateRenderCallback( program, _gl, _frustum );

		} else {

4219
			object.render( function( object ) { _this.renderBufferImmediate( object, program, material ); } );
4220 4221 4222 4223 4224

		}

	};

4225
	function unrollImmediateBufferMaterial ( globject ) {
4226

4227 4228
		var object = globject.object,
			material = object.material;
4229

4230
		if ( material.transparent ) {
4231

4232 4233
			globject.transparent = material;
			globject.opaque = null;
4234

4235
		} else {
4236

4237 4238
			globject.opaque = material;
			globject.transparent = null;
4239

4240
		}
A
alteredq 已提交
4241

4242
	};
A
alteredq 已提交
4243

4244
	function unrollBufferMaterial ( globject ) {
A
alteredq 已提交
4245

4246 4247 4248
		var object = globject.object,
			buffer = globject.buffer,
			material, materialIndex, meshMaterial;
4249

4250
		meshMaterial = object.material;
4251

4252
		if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
M
Mr.doob 已提交
4253

4254
			materialIndex = buffer.materialIndex;
4255

4256
			if ( materialIndex >= 0 ) {
4257

4258
				material = meshMaterial.materials[ materialIndex ];
4259

4260
				if ( material.transparent ) {
M
Mr.doob 已提交
4261

4262 4263
					globject.transparent = material;
					globject.opaque = null;
4264

4265
				} else {
4266

4267 4268
					globject.opaque = material;
					globject.transparent = null;
4269

4270
				}
4271

4272
			}
4273

4274
		} else {
4275

4276
			material = meshMaterial;
4277

4278
			if ( material ) {
4279

4280
				if ( material.transparent ) {
M
Mr.doob 已提交
4281

4282 4283
					globject.transparent = material;
					globject.opaque = null;
A
alteredq 已提交
4284

4285
				} else {
4286

4287 4288
					globject.opaque = material;
					globject.transparent = null;
4289

4290
				}
4291

4292
			}
4293

4294
		}
4295

4296
	};
4297

4298
	// Geometry splitting
4299

4300
	function sortFacesByMaterial ( geometry, material ) {
4301

4302 4303 4304
		var f, fl, face, materialIndex, vertices,
			materialHash, groupHash,
			hash_map = {};
4305

4306
		var numMorphTargets = geometry.morphTargets.length;
4307
		var numMorphNormals = geometry.morphNormals.length;
4308

4309 4310
		var usesFaceMaterial = material instanceof THREE.MeshFaceMaterial;

4311
		geometry.geometryGroups = {};
4312

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

4315
			face = geometry.faces[ f ];
4316
			materialIndex = usesFaceMaterial ? face.materialIndex : undefined;
4317

4318
			materialHash = ( materialIndex !== undefined ) ? materialIndex : -1;
4319

4320
			if ( hash_map[ materialHash ] === undefined ) {
4321

4322
				hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 };
4323 4324 4325

			}

4326
			groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
4327

4328
			if ( geometry.geometryGroups[ groupHash ] === undefined ) {
4329

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

4332
			}
A
alteredq 已提交
4333

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

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

4338 4339
				hash_map[ materialHash ].counter += 1;
				groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
A
alteredq 已提交
4340

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

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

4345
				}
4346

4347
			}
4348

4349
			if ( face instanceof THREE.Face3 ) {
4350

4351
				geometry.geometryGroups[ groupHash ].faces3.push( f );
4352

4353
			} else {
4354

4355
				geometry.geometryGroups[ groupHash ].faces4.push( f );
4356

A
alteredq 已提交
4357
			}
4358

4359
			geometry.geometryGroups[ groupHash ].vertices += vertices;
4360

4361
		}
4362

4363
		geometry.geometryGroupsList = [];
4364

4365
		for ( var g in geometry.geometryGroups ) {
4366

4367
			geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;
4368

4369
			geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );
4370

4371
		}
4372

4373
	};
4374

4375 4376 4377 4378 4379 4380 4381 4382 4383
	// Objects refresh

	this.initWebGLObjects = function ( scene ) {

		if ( !scene.__webglObjects ) {

			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
			scene.__webglSprites = [];
4384
			scene.__webglFlares = [];
4385 4386

		}
4387

4388
		while ( scene.__objectsAdded.length ) {
4389

4390 4391
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
4392

4393
		}
A
alteredq 已提交
4394

4395
		while ( scene.__objectsRemoved.length ) {
4396

4397 4398
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
4399

4400
		}
4401

4402
		// update must be called after objects adding / removal
4403

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

4406
			updateObject( scene.__webglObjects[ o ].object );
M
Mr.doob 已提交
4407 4408 4409 4410 4411

		}

	};

4412
	// Objects adding
M
Mr.doob 已提交
4413

4414
	function addObject ( object, scene ) {
A
alteredq 已提交
4415

4416
		var g, geometry, material, geometryGroup;
4417

4418
		if ( ! object.__webglInit ) {
M
Mr.doob 已提交
4419

4420
			object.__webglInit = true;
M
Mr.doob 已提交
4421

4422
			object._modelViewMatrix = new THREE.Matrix4();
4423
			object._normalMatrix = new THREE.Matrix3();
M
Mr.doob 已提交
4424

4425
			if ( object instanceof THREE.Mesh ) {
M
Mr.doob 已提交
4426

4427
				geometry = object.geometry;
4428
				material = object.material;
M
Mr.doob 已提交
4429

4430
				if ( geometry instanceof THREE.Geometry ) {
M
Mr.doob 已提交
4431

4432
					if ( geometry.geometryGroups === undefined ) {
M
Mr.doob 已提交
4433

4434
						sortFacesByMaterial( geometry, material );
M
Mr.doob 已提交
4435

4436 4437 4438
					}

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

4440
					for ( g in geometry.geometryGroups ) {
M
Mr.doob 已提交
4441

4442
						geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
4443

4444
						// initialise VBO on the first access
M
Mr.doob 已提交
4445

4446
						if ( ! geometryGroup.__webglVertexBuffer ) {
4447

4448 4449
							createMeshBuffers( geometryGroup );
							initMeshBuffers( geometryGroup, object );
M
Mr.doob 已提交
4450

4451
							geometry.verticesNeedUpdate = true;
4452
							geometry.morphTargetsNeedUpdate = true;
M
Mr.doob 已提交
4453
							geometry.elementsNeedUpdate = true;
M
Mr.doob 已提交
4454
							geometry.uvsNeedUpdate = true;
M
Mr.doob 已提交
4455
							geometry.normalsNeedUpdate = true;
4456
							geometry.tangentsNeedUpdate = true;
M
Mr.doob 已提交
4457
							geometry.colorsNeedUpdate = true;
4458 4459

						}
M
Mr.doob 已提交
4460

4461
					}
M
Mr.doob 已提交
4462

4463 4464 4465 4466
				} else if ( geometry instanceof THREE.BufferGeometry ) {

					initDirectBuffers( geometry );

4467
				}
M
Mr.doob 已提交
4468

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

4471
				geometry = object.geometry;
M
Mr.doob 已提交
4472

4473
				if ( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
4474

4475
					createRibbonBuffers( geometry );
4476
					initRibbonBuffers( geometry, object );
M
Mr.doob 已提交
4477

4478
					geometry.verticesNeedUpdate = true;
M
Mr.doob 已提交
4479
					geometry.colorsNeedUpdate = true;
4480
					geometry.normalsNeedUpdate = true;
M
Mr.doob 已提交
4481

4482
				}
M
Mr.doob 已提交
4483

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

4486
				geometry = object.geometry;
M
Mr.doob 已提交
4487

4488
				if ( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
4489

4490 4491
					createLineBuffers( geometry );
					initLineBuffers( geometry, object );
M
Mr.doob 已提交
4492

4493
					geometry.verticesNeedUpdate = true;
M
Mr.doob 已提交
4494
					geometry.colorsNeedUpdate = true;
4495
					geometry.lineDistancesNeedUpdate = true;
4496

4497
				}
4498

4499
			} else if ( object instanceof THREE.ParticleSystem ) {
4500

4501
				geometry = object.geometry;
4502

4503
				if ( ! geometry.__webglVertexBuffer ) {
4504

4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517
					if ( geometry instanceof THREE.Geometry ) {

						createParticleBuffers( geometry );
						initParticleBuffers( geometry, object );

						geometry.verticesNeedUpdate = true;
						geometry.colorsNeedUpdate = true;

					} else if ( geometry instanceof THREE.BufferGeometry ) {

						initDirectBuffers( geometry );

					}
4518

4519

4520
				}
4521

4522
			}
4523

4524
		}
4525

4526
		if ( ! object.__webglActive ) {
4527

4528
			if ( object instanceof THREE.Mesh ) {
4529

4530
				geometry = object.geometry;
4531

4532 4533 4534 4535 4536 4537 4538 4539 4540
				if ( geometry instanceof THREE.BufferGeometry ) {

					addBuffer( scene.__webglObjects, geometry, object );

				} else {

					for ( g in geometry.geometryGroups ) {

						geometryGroup = geometry.geometryGroups[ g ];
4541

4542
						addBuffer( scene.__webglObjects, geometryGroup, object );
4543

4544
					}
4545

4546
				}
4547

4548 4549 4550
			} else if ( object instanceof THREE.Ribbon ||
						object instanceof THREE.Line ||
						object instanceof THREE.ParticleSystem ) {
4551

4552 4553
				geometry = object.geometry;
				addBuffer( scene.__webglObjects, geometry, object );
4554

4555
			} else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
4556

4557
				addBufferImmediate( scene.__webglObjectsImmediate, object );
4558

4559
			} else if ( object instanceof THREE.Sprite ) {
4560

4561
				scene.__webglSprites.push( object );
4562

4563 4564 4565 4566
			} else if ( object instanceof THREE.LensFlare ) {

				scene.__webglFlares.push( object );

4567 4568
			}

4569
			object.__webglActive = true;
4570

4571
		}
4572

4573
	};
4574

4575
	function addBuffer ( objlist, buffer, object ) {
4576

4577 4578 4579 4580 4581 4582 4583 4584
		objlist.push(
			{
				buffer: buffer,
				object: object,
				opaque: null,
				transparent: null
			}
		);
4585

4586
	};
4587

4588
	function addBufferImmediate ( objlist, object ) {
4589

4590 4591 4592 4593 4594
		objlist.push(
			{
				object: object,
				opaque: null,
				transparent: null
4595
			}
4596
		);
4597

4598
	};
4599

4600
	// Objects updates
4601

4602
	function updateObject ( object ) {
4603

4604 4605
		var geometry = object.geometry,
			geometryGroup, customAttributesDirty, material;
4606

4607
		if ( object instanceof THREE.Mesh ) {
4608

4609 4610
			if ( geometry instanceof THREE.BufferGeometry ) {

M
Mr.doob 已提交
4611
				if ( geometry.verticesNeedUpdate || geometry.elementsNeedUpdate ||
M
Mr.doob 已提交
4612
					 geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
4613
					 geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate ) {
4614

4615
					setDirectBuffers( geometry, _gl.DYNAMIC_DRAW, !geometry.dynamic );
4616

4617
				}
4618

4619
				geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4620
				geometry.elementsNeedUpdate = false;
M
Mr.doob 已提交
4621
				geometry.uvsNeedUpdate = false;
M
Mr.doob 已提交
4622
				geometry.normalsNeedUpdate = false;
M
Mr.doob 已提交
4623
				geometry.colorsNeedUpdate = false;
4624
				geometry.tangentsNeedUpdate = false;
4625

4626
			} else {
4627

4628
				// check all geometry groups
4629

4630 4631 4632 4633 4634 4635
				for( var i = 0, il = geometry.geometryGroupsList.length; i < il; i ++ ) {

					geometryGroup = geometry.geometryGroupsList[ i ];

					material = getBufferMaterial( object, geometryGroup );

A
alteredq 已提交
4636 4637 4638 4639 4640 4641
					if ( geometry.buffersNeedUpdate ) {

						initMeshBuffers( geometryGroup, object );

					}

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

4644
					if ( geometry.verticesNeedUpdate || geometry.morphTargetsNeedUpdate || geometry.elementsNeedUpdate ||
M
Mr.doob 已提交
4645
						 geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
4646
						 geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate || customAttributesDirty ) {
4647 4648 4649 4650

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

					}
4651

4652
				}
M
Mr.doob 已提交
4653

4654
				geometry.verticesNeedUpdate = false;
4655
				geometry.morphTargetsNeedUpdate = false;
M
Mr.doob 已提交
4656
				geometry.elementsNeedUpdate = false;
M
Mr.doob 已提交
4657
				geometry.uvsNeedUpdate = false;
M
Mr.doob 已提交
4658
				geometry.normalsNeedUpdate = false;
M
Mr.doob 已提交
4659
				geometry.colorsNeedUpdate = false;
4660
				geometry.tangentsNeedUpdate = false;
4661

A
alteredq 已提交
4662 4663
				geometry.buffersNeedUpdate = false;

4664
				material.attributes && clearCustomAttributes( material );
4665

4666
			}
4667

4668
		} else if ( object instanceof THREE.Ribbon ) {
4669

4670 4671 4672 4673 4674
			material = getBufferMaterial( object, geometry );

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

			if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || geometry.normalsNeedUpdate || customAttributesDirty ) {
4675

4676
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
4677

4678
			}
4679

4680
			geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4681
			geometry.colorsNeedUpdate = false;
4682
			geometry.normalsNeedUpdate = false;
4683

4684 4685
			material.attributes && clearCustomAttributes( material );

4686
		} else if ( object instanceof THREE.Line ) {
4687

4688
			material = getBufferMaterial( object, geometry );
A
alteredq 已提交
4689

4690
			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
A
alteredq 已提交
4691

4692
			if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || geometry.lineDistancesNeedUpdate || customAttributesDirty ) {
A
alteredq 已提交
4693

4694
				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
4695

4696
			}
4697

4698
			geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4699
			geometry.colorsNeedUpdate = false;
4700
			geometry.lineDistancesNeedUpdate = false;
4701

4702
			material.attributes && clearCustomAttributes( material );
4703

4704
		} else if ( object instanceof THREE.ParticleSystem ) {
4705

4706
			if ( geometry instanceof THREE.BufferGeometry ) {
4707

4708
				if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate ) {
4709

4710
					setDirectBuffers( geometry, _gl.DYNAMIC_DRAW, !geometry.dynamic );
4711

4712
				}
4713

4714 4715
				geometry.verticesNeedUpdate = false;
				geometry.colorsNeedUpdate = false;
4716

4717
			} else {
4718

4719
				material = getBufferMaterial( object, geometry );
4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734

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

				if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || object.sortParticles || customAttributesDirty ) {

					setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );

				}

				geometry.verticesNeedUpdate = false;
				geometry.colorsNeedUpdate = false;

				material.attributes && clearCustomAttributes( material );

			}
4735

4736
		}
4737

4738
	};
4739

4740
	// Objects updates - custom attributes check
4741

4742
	function areCustomAttributesDirty ( material ) {
4743

4744
		for ( var a in material.attributes ) {
4745

4746
			if ( material.attributes[ a ].needsUpdate ) return true;
4747

4748
		}
4749

4750
		return false;
4751

4752
	};
4753

4754 4755 4756
	function clearCustomAttributes ( material ) {

		for ( var a in material.attributes ) {
4757

4758
			material.attributes[ a ].needsUpdate = false;
4759

4760
		}
4761

4762
	};
4763

4764
	// Objects removal
4765

4766
	function removeObject ( object, scene ) {
4767

4768 4769 4770 4771
		if ( object instanceof THREE.Mesh  ||
			 object instanceof THREE.ParticleSystem ||
			 object instanceof THREE.Ribbon ||
			 object instanceof THREE.Line ) {
4772

4773
			removeInstances( scene.__webglObjects, object );
4774

4775
		} else if ( object instanceof THREE.Sprite ) {
4776

4777
			removeInstancesDirect( scene.__webglSprites, object );
4778

4779 4780 4781 4782
		} else if ( object instanceof THREE.LensFlare ) {

			removeInstancesDirect( scene.__webglFlares, object );

4783
		} else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
4784

4785
			removeInstances( scene.__webglObjectsImmediate, object );
4786

4787
		}
4788

4789
		object.__webglActive = false;
4790

4791
	};
4792

4793
	function removeInstances ( objlist, object ) {
4794

4795
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4796

4797
			if ( objlist[ o ].object === object ) {
4798

4799
				objlist.splice( o, 1 );
4800

4801
			}
4802

4803
		}
4804

4805
	};
4806

4807
	function removeInstancesDirect ( objlist, object ) {
4808

4809
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4810

4811
			if ( objlist[ o ] === object ) {
4812

4813
				objlist.splice( o, 1 );
4814

4815
			}
4816

4817
		}
4818

4819
	};
4820

4821
	// Materials
4822

4823
	this.initMaterial = function ( material, lights, fog, object ) {
4824

4825
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
4826

4827
		if ( material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
4828

4829
			shaderID = 'depth';
4830

4831
		} else if ( material instanceof THREE.MeshNormalMaterial ) {
4832

4833
			shaderID = 'normal';
M
Mr.doob 已提交
4834

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

4837
			shaderID = 'basic';
M
Mr.doob 已提交
4838

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

4841
			shaderID = 'lambert';
M
Mr.doob 已提交
4842

4843
		} else if ( material instanceof THREE.MeshPhongMaterial ) {
4844

4845
			shaderID = 'phong';
4846

4847
		} else if ( material instanceof THREE.LineBasicMaterial ) {
4848

4849
			shaderID = 'basic';
4850

4851 4852 4853 4854
		} else if ( material instanceof THREE.LineDashedMaterial ) {

			shaderID = 'dashed';

4855
		} else if ( material instanceof THREE.ParticleBasicMaterial ) {
4856

4857
			shaderID = 'particle_basic';
4858 4859 4860

		}

4861
		if ( shaderID ) {
4862

4863
			setMaterialShaders( material, THREE.ShaderLib[ shaderID ] );
4864

4865
		}
4866

4867 4868
		// heuristics to create shader parameters according to lights in the scene
		// (not to blow over maxLights budget)
4869

4870
		maxLightCount = allocateLights( lights );
4871

4872
		maxShadows = allocateShadows( lights );
4873

4874
		maxBones = allocateBones( object );
4875

4876
		parameters = {
4877

A
alteredq 已提交
4878 4879 4880
			map: !!material.map,
			envMap: !!material.envMap,
			lightMap: !!material.lightMap,
4881
			bumpMap: !!material.bumpMap,
4882
			normalMap: !!material.normalMap,
4883
			specularMap: !!material.specularMap,
A
alteredq 已提交
4884

4885
			vertexColors: material.vertexColors,
A
alteredq 已提交
4886 4887 4888

			fog: fog,
			useFog: material.fog,
4889
			fogExp: fog instanceof THREE.FogExp2,
A
alteredq 已提交
4890

4891
			sizeAttenuation: material.sizeAttenuation,
A
alteredq 已提交
4892

4893
			skinning: material.skinning,
A
alteredq 已提交
4894
			maxBones: maxBones,
4895 4896 4897
			useVertexTexture: _supportsBoneTextures && object && object.useVertexTexture,
			boneTextureWidth: object && object.boneTextureWidth,
			boneTextureHeight: object && object.boneTextureHeight,
A
alteredq 已提交
4898

4899
			morphTargets: material.morphTargets,
A
alteredq 已提交
4900
			morphNormals: material.morphNormals,
4901
			maxMorphTargets: this.maxMorphTargets,
A
alteredq 已提交
4902
			maxMorphNormals: this.maxMorphNormals,
A
alteredq 已提交
4903 4904 4905 4906

			maxDirLights: maxLightCount.directional,
			maxPointLights: maxLightCount.point,
			maxSpotLights: maxLightCount.spot,
A
alteredq 已提交
4907
			maxHemiLights: maxLightCount.hemi,
A
alteredq 已提交
4908 4909

			maxShadows: maxShadows,
4910 4911
			shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
			shadowMapSoft: this.shadowMapSoft,
A
alteredq 已提交
4912 4913
			shadowMapDebug: this.shadowMapDebug,
			shadowMapCascade: this.shadowMapCascade,
A
alteredq 已提交
4914

4915 4916
			alphaTest: material.alphaTest,
			metal: material.metal,
4917
			perPixel: material.perPixel,
4918
			wrapAround: material.wrapAround,
4919 4920
			doubleSided: material.side === THREE.DoubleSide,
			flipSided: material.side === THREE.BackSide
4921

4922
		};
M
Mr.doob 已提交
4923

4924
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, material.defines, parameters );
4925

4926
		var attributes = material.program.attributes;
4927

4928
		if ( material.morphTargets ) {
M
Mr.doob 已提交
4929

4930
			material.numSupportedMorphTargets = 0;
4931

4932
			var id, base = "morphTarget";
4933

4934
			for ( i = 0; i < this.maxMorphTargets; i ++ ) {
4935

4936
				id = base + i;
M
Mr.doob 已提交
4937

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

4940
					material.numSupportedMorphTargets ++;
4941

4942
				}
4943

4944
			}
4945

4946
		}
4947

A
alteredq 已提交
4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967
		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

			var id, base = "morphNormal";

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

				id = base + i;

				if ( attributes[ id ] >= 0 ) {

					material.numSupportedMorphNormals ++;

				}

			}

		}

4968
		material.uniformsList = [];
4969

4970
		for ( u in material.uniforms ) {
4971

4972
			material.uniformsList.push( [ material.uniforms[ u ], u ] );
4973

4974
		}
M
Mr.doob 已提交
4975

4976
	};
M
Mr.doob 已提交
4977

4978
	function setMaterialShaders( material, shaders ) {
M
Mr.doob 已提交
4979

4980 4981 4982
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
M
Mr.doob 已提交
4983

4984
	};
M
Mr.doob 已提交
4985

4986
	function setProgram( camera, lights, fog, material, object ) {
4987

4988 4989
		_usedTextureUnits = 0;

A
alteredq 已提交
4990
		if ( material.needsUpdate ) {
4991

4992 4993
			if ( material.program ) _this.deallocateMaterial( material );

4994
			_this.initMaterial( material, lights, fog, object );
A
alteredq 已提交
4995
			material.needsUpdate = false;
4996

4997
		}
4998

4999
		if ( material.morphTargets ) {
5000

5001
			if ( ! object.__webglMorphTargetInfluences ) {
5002

5003
				object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );
5004

5005
			}
5006

5007
		}
5008

5009
		var refreshMaterial = false;
5010

5011 5012 5013
		var program = material.program,
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
5014

5015
		if ( program !== _currentProgram ) {
5016

5017 5018
			_gl.useProgram( program );
			_currentProgram = program;
5019

5020
			refreshMaterial = true;
5021

5022
		}
5023

5024
		if ( material.id !== _currentMaterialId ) {
5025

5026 5027
			_currentMaterialId = material.id;
			refreshMaterial = true;
5028

5029
		}
5030

5031
		if ( refreshMaterial || camera !== _currentCamera ) {
5032

5033
			_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, camera.projectionMatrix.elements );
A
alteredq 已提交
5034

5035 5036 5037 5038
			if ( camera !== _currentCamera ) _currentCamera = camera;

		}

5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067
		// skinning uniforms must be set even if material didn't change
		// auto-setting of texture unit for bone texture must go before other textures
		// not sure why, but otherwise weird things happen

		if ( material.skinning ) {

			if ( _supportsBoneTextures && object.useVertexTexture ) {

				if ( p_uniforms.boneTexture !== null ) {

					var textureUnit = getTextureUnit();

					_gl.uniform1i( p_uniforms.boneTexture, textureUnit );
					_this.setTexture( object.boneTexture, textureUnit );

				}

			} else {

				if ( p_uniforms.boneGlobalMatrices !== null ) {

					_gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.boneMatrices );

				}

			}

		}

5068 5069
		if ( refreshMaterial ) {

5070
			// refresh uniforms common to several materials
5071

5072
			if ( fog && material.fog ) {
5073

5074
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
5075

5076
			}
M
Mr.doob 已提交
5077

5078 5079 5080
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material.lights ) {
5081

5082 5083 5084 5085 5086 5087 5088
				if ( _lightsNeedUpdate ) {

					setupLights( program, lights );
					_lightsNeedUpdate = false;

				}

5089
				refreshUniformsLights( m_uniforms, _lights );
5090

5091
			}
M
Mr.doob 已提交
5092

5093 5094 5095
			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
5096

5097
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
5098 5099 5100

			}

5101
			// refresh single material specific uniforms
M
Mr.doob 已提交
5102

5103
			if ( material instanceof THREE.LineBasicMaterial ) {
5104

5105
				refreshUniformsLine( m_uniforms, material );
M
Mr.doob 已提交
5106

5107 5108 5109 5110 5111
			} else if ( material instanceof THREE.LineDashedMaterial ) {

				refreshUniformsLine( m_uniforms, material );
				refreshUniformsDash( m_uniforms, material );

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

5114
				refreshUniformsParticle( m_uniforms, material );
M
Mr.doob 已提交
5115

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

5118
				refreshUniformsPhong( m_uniforms, material );
M
Mr.doob 已提交
5119

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

5122
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
5123

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

5126 5127 5128
				m_uniforms.mNear.value = camera.near;
				m_uniforms.mFar.value = camera.far;
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
5129

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

5132
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
5133

5134
			}
M
Mr.doob 已提交
5135

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

5138
				refreshUniformsShadow( m_uniforms, lights );
M
Mr.doob 已提交
5139

5140
			}
M
Mr.doob 已提交
5141

5142
			// load common uniforms
M
Mr.doob 已提交
5143

5144
			loadUniformsGeneric( program, material.uniformsList );
M
Mr.doob 已提交
5145

5146 5147
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)
5148

5149 5150 5151
			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
				 material.envMap ) {
5152

5153
				if ( p_uniforms.cameraPosition !== null ) {
5154

5155 5156
					var position = camera.matrixWorld.getPosition();
					_gl.uniform3f( p_uniforms.cameraPosition, position.x, position.y, position.z );
5157

5158
				}
5159 5160 5161

			}

5162 5163 5164 5165
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {
5166

5167
				if ( p_uniforms.viewMatrix !== null ) {
5168

5169
					_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, camera.matrixWorldInverse.elements );
5170

5171
				}
5172

5173
			}
M
Mr.doob 已提交
5174

5175 5176
		}

5177
		loadUniformsMatrices( p_uniforms, object );
M
Mr.doob 已提交
5178

5179
		if ( p_uniforms.modelMatrix !== null ) {
M
Mr.doob 已提交
5180

5181
			_gl.uniformMatrix4fv( p_uniforms.modelMatrix, false, object.matrixWorld.elements );
5182

5183
		}
5184

5185
		return program;
5186

5187
	};
5188

5189
	// Uniforms (refresh uniforms objects)
A
alteredq 已提交
5190

5191
	function refreshUniformsCommon ( uniforms, material ) {
5192

5193
		uniforms.opacity.value = material.opacity;
5194

5195
		if ( _this.gammaInput ) {
5196

5197
			uniforms.diffuse.value.copyGammaToLinear( material.color );
5198

5199
		} else {
5200

5201
			uniforms.diffuse.value = material.color;
5202

5203
		}
5204

5205 5206 5207
		uniforms.map.value = material.map;
		uniforms.lightMap.value = material.lightMap;
		uniforms.specularMap.value = material.specularMap;
5208

5209
		if ( material.bumpMap ) {
5210

5211
			uniforms.bumpMap.value = material.bumpMap;
5212
			uniforms.bumpScale.value = material.bumpScale;
M
Mr.doob 已提交
5213

5214
		}
M
Mr.doob 已提交
5215

5216 5217
		if ( material.normalMap ) {

5218
			uniforms.normalMap.value = material.normalMap;
5219
			uniforms.normalScale.value.copy( material.normalScale );
5220

5221
		}
M
Mr.doob 已提交
5222

5223 5224 5225
		// uv repeat and offset setting priorities
		//	1. color map
		//	2. specular map
5226 5227
		//	3. normal map
		//	4. bump map
5228

5229
		var uvScaleMap;
5230

5231
		if ( material.map ) {
5232

5233
			uvScaleMap = material.map;
5234

5235
		} else if ( material.specularMap ) {
5236

5237 5238
			uvScaleMap = material.specularMap;

5239 5240 5241 5242
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254
		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

		}

		if ( uvScaleMap !== undefined ) {

			var offset = uvScaleMap.offset;
			var repeat = uvScaleMap.repeat;

			uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
5255

5256
		}
5257

5258
		uniforms.envMap.value = material.envMap;
5259
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
5260

5261
		if ( _this.gammaInput ) {
5262

5263 5264
			//uniforms.reflectivity.value = material.reflectivity * material.reflectivity;
			uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
5265

5266
		} else {
5267

5268
			uniforms.reflectivity.value = material.reflectivity;
5269

5270
		}
5271

5272 5273 5274
		uniforms.refractionRatio.value = material.refractionRatio;
		uniforms.combine.value = material.combine;
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
M
Mr.doob 已提交
5275

5276
	};
M
Mr.doob 已提交
5277

5278
	function refreshUniformsLine ( uniforms, material ) {
M
Mr.doob 已提交
5279

5280 5281
		uniforms.diffuse.value = material.color;
		uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
5282

5283
	};
M
Mr.doob 已提交
5284

5285 5286 5287 5288 5289 5290 5291 5292
	function refreshUniformsDash ( uniforms, material ) {

		uniforms.dashSize.value = material.dashSize;
		uniforms.totalSize.value = material.dashSize + material.gapSize;
		uniforms.scale.value = material.scale;

	};

5293
	function refreshUniformsParticle ( uniforms, material ) {
5294

5295 5296 5297 5298
		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.
5299

5300
		uniforms.map.value = material.map;
5301

5302
	};
5303

5304
	function refreshUniformsFog ( uniforms, fog ) {
5305

5306
		uniforms.fogColor.value = fog.color;
5307

5308
		if ( fog instanceof THREE.Fog ) {
5309

5310 5311
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
5312

5313
		} else if ( fog instanceof THREE.FogExp2 ) {
M
Mikael Emtinger 已提交
5314

5315
			uniforms.fogDensity.value = fog.density;
M
Mikael Emtinger 已提交
5316

5317
		}
M
Mikael Emtinger 已提交
5318

5319
	};
M
Mikael Emtinger 已提交
5320

5321
	function refreshUniformsPhong ( uniforms, material ) {
M
Mikael Emtinger 已提交
5322

5323
		uniforms.shininess.value = material.shininess;
5324

5325
		if ( _this.gammaInput ) {
M
Mikael Emtinger 已提交
5326

5327
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
5328
			uniforms.emissive.value.copyGammaToLinear( material.emissive );
5329
			uniforms.specular.value.copyGammaToLinear( material.specular );
5330

5331
		} else {
5332

5333
			uniforms.ambient.value = material.ambient;
5334
			uniforms.emissive.value = material.emissive;
5335
			uniforms.specular.value = material.specular;
5336

5337
		}
5338

5339 5340 5341 5342 5343 5344
		if ( material.wrapAround ) {

			uniforms.wrapRGB.value.copy( material.wrapRGB );

		}

5345
	};
5346

5347
	function refreshUniformsLambert ( uniforms, material ) {
5348

5349
		if ( _this.gammaInput ) {
5350

5351
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
5352
			uniforms.emissive.value.copyGammaToLinear( material.emissive );
M
Mr.doob 已提交
5353

5354
		} else {
5355

5356
			uniforms.ambient.value = material.ambient;
5357
			uniforms.emissive.value = material.emissive;
5358

5359
		}
5360

5361 5362 5363 5364 5365 5366
		if ( material.wrapAround ) {

			uniforms.wrapRGB.value.copy( material.wrapRGB );

		}

5367
	};
5368

5369
	function refreshUniformsLights ( uniforms, lights ) {
5370

5371
		uniforms.ambientLightColor.value = lights.ambient;
5372

5373 5374
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
5375

5376 5377 5378
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
		uniforms.pointLightDistance.value = lights.point.distances;
5379

A
alteredq 已提交
5380 5381 5382 5383
		uniforms.spotLightColor.value = lights.spot.colors;
		uniforms.spotLightPosition.value = lights.spot.positions;
		uniforms.spotLightDistance.value = lights.spot.distances;
		uniforms.spotLightDirection.value = lights.spot.directions;
5384
		uniforms.spotLightAngleCos.value = lights.spot.anglesCos;
A
alteredq 已提交
5385 5386
		uniforms.spotLightExponent.value = lights.spot.exponents;

A
alteredq 已提交
5387 5388
		uniforms.hemisphereLightSkyColor.value = lights.hemi.skyColors;
		uniforms.hemisphereLightGroundColor.value = lights.hemi.groundColors;
5389
		uniforms.hemisphereLightDirection.value = lights.hemi.positions;
A
alteredq 已提交
5390

5391
	};
5392

5393
	function refreshUniformsShadow ( uniforms, lights ) {
M
Mr.doob 已提交
5394

5395
		if ( uniforms.shadowMatrix ) {
5396

5397
			var j = 0;
5398

5399
			for ( var i = 0, il = lights.length; i < il; i ++ ) {
5400

5401
				var light = lights[ i ];
5402

A
alteredq 已提交
5403 5404
				if ( ! light.castShadow ) continue;

5405
				if ( light instanceof THREE.SpotLight || ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) ) {
5406

5407
					uniforms.shadowMap.value[ j ] = light.shadowMap;
5408
					uniforms.shadowMapSize.value[ j ] = light.shadowMapSize;
5409

5410 5411 5412 5413 5414 5415 5416 5417 5418 5419
					uniforms.shadowMatrix.value[ j ] = light.shadowMatrix;

					uniforms.shadowDarkness.value[ j ] = light.shadowDarkness;
					uniforms.shadowBias.value[ j ] = light.shadowBias;

					j ++;

				}

			}
5420

5421 5422
		}

5423
	};
5424

5425
	// Uniforms (load to GPU)
5426

5427
	function loadUniformsMatrices ( uniforms, object ) {
5428

5429
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrix.elements );
5430

5431
		if ( uniforms.normalMatrix ) {
5432

5433
			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrix.elements );
5434

5435
		}
5436

5437
	};
5438

5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454
	function getTextureUnit() {

		var textureUnit = _usedTextureUnits;

		if ( textureUnit >= _maxTextures ) {

			console.warn( "Trying to use " + textureUnit + " texture units while this GPU supports only " + _maxTextures );

		}

		_usedTextureUnits += 1;

		return textureUnit;

	};

5455
	function loadUniformsGeneric ( program, uniforms ) {
5456

5457
		var uniform, value, type, location, texture, textureUnit, i, il, j, jl, offset;
5458

M
Mr.doob 已提交
5459
		for ( j = 0, jl = uniforms.length; j < jl; j ++ ) {
5460

5461 5462
			location = program.uniforms[ uniforms[ j ][ 1 ] ];
			if ( !location ) continue;
5463

5464
			uniform = uniforms[ j ][ 0 ];
5465

5466 5467
			type = uniform.type;
			value = uniform.value;
5468

5469
			if ( type === "i" ) { // single integer
5470

5471
				_gl.uniform1i( location, value );
5472

5473
			} else if ( type === "f" ) { // single float
5474

5475
				_gl.uniform1f( location, value );
5476

5477
			} else if ( type === "v2" ) { // single THREE.Vector2
5478

5479
				_gl.uniform2f( location, value.x, value.y );
5480

5481
			} else if ( type === "v3" ) { // single THREE.Vector3
5482

5483
				_gl.uniform3f( location, value.x, value.y, value.z );
5484

5485
			} else if ( type === "v4" ) { // single THREE.Vector4
5486

5487
				_gl.uniform4f( location, value.x, value.y, value.z, value.w );
5488

5489
			} else if ( type === "c" ) { // single THREE.Color
5490

5491
				_gl.uniform3f( location, value.r, value.g, value.b );
5492

5493 5494 5495
			} else if ( type === "iv1" ) { // flat array of integers (JS or typed array)

				_gl.uniform1iv( location, value );
5496 5497 5498 5499

			} else if ( type === "iv" ) { // flat array of integers with 3 x N size (JS or typed array)

				_gl.uniform3iv( location, value );
5500

5501
			} else if ( type === "fv1" ) { // flat array of floats (JS or typed array)
5502

5503
				_gl.uniform1fv( location, value );
5504

5505
			} else if ( type === "fv" ) { // flat array of floats with 3 x N size (JS or typed array)
5506

5507
				_gl.uniform3fv( location, value );
5508

5509
			} else if ( type === "v2v" ) { // array of THREE.Vector2
5510

5511
				if ( uniform._array === undefined ) {
5512

5513
					uniform._array = new Float32Array( 2 * value.length );
5514

5515
				}
5516

5517
				for ( i = 0, il = value.length; i < il; i ++ ) {
5518

5519
					offset = i * 2;
5520

5521 5522
					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;
5523

5524
				}
5525

5526
				_gl.uniform2fv( location, uniform._array );
5527

5528
			} else if ( type === "v3v" ) { // array of THREE.Vector3
5529

5530
				if ( uniform._array === undefined ) {
M
Mr.doob 已提交
5531

5532
					uniform._array = new Float32Array( 3 * value.length );
A
alteredq 已提交
5533

5534
				}
5535

5536
				for ( i = 0, il = value.length; i < il; i ++ ) {
5537

5538
					offset = i * 3;
5539

5540 5541 5542
					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;
					uniform._array[ offset + 2 ] = value[ i ].z;
A
alteredq 已提交
5543

5544
				}
5545

5546
				_gl.uniform3fv( location, uniform._array );
A
alteredq 已提交
5547

5548
			} else if ( type === "v4v" ) { // array of THREE.Vector4
M
Mr.doob 已提交
5549

5550
				if ( uniform._array === undefined ) {
M
Mr.doob 已提交
5551

5552
					uniform._array = new Float32Array( 4 * value.length );
M
Mr.doob 已提交
5553

5554
				}
A
alteredq 已提交
5555

5556
				for ( i = 0, il = value.length; i < il; i ++ ) {
M
Mr.doob 已提交
5557

5558
					offset = i * 4;
M
Mr.doob 已提交
5559

5560 5561 5562 5563
					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;
A
alteredq 已提交
5564

5565
				}
5566

5567
				_gl.uniform4fv( location, uniform._array );
A
alteredq 已提交
5568

5569
			} else if ( type === "m4") { // single THREE.Matrix4
A
alteredq 已提交
5570

5571
				if ( uniform._array === undefined ) {
A
alteredq 已提交
5572

5573
					uniform._array = new Float32Array( 16 );
A
alteredq 已提交
5574

5575
				}
M
Mr.doob 已提交
5576

5577 5578
				value.flattenToArray( uniform._array );
				_gl.uniformMatrix4fv( location, false, uniform._array );
5579

5580
			} else if ( type === "m4v" ) { // array of THREE.Matrix4
5581

5582
				if ( uniform._array === undefined ) {
5583

5584
					uniform._array = new Float32Array( 16 * value.length );
M
Mr.doob 已提交
5585

5586
				}
M
Mr.doob 已提交
5587

5588
				for ( i = 0, il = value.length; i < il; i ++ ) {
M
Mr.doob 已提交
5589

5590
					value[ i ].flattenToArrayOffset( uniform._array, i * 16 );
A
alteredq 已提交
5591

5592
				}
M
Mr.doob 已提交
5593

5594
				_gl.uniformMatrix4fv( location, false, uniform._array );
M
Mr.doob 已提交
5595

5596
			} else if ( type === "t" ) { // single THREE.Texture (2d or cube)
5597

5598 5599
				texture = value;
				textureUnit = getTextureUnit();
M
Mr.doob 已提交
5600

5601
				_gl.uniform1i( location, textureUnit );
M
Mr.doob 已提交
5602

5603
				if ( !texture ) continue;
M
Mr.doob 已提交
5604

5605
				if ( texture.image instanceof Array && texture.image.length === 6 ) {
M
Mr.doob 已提交
5606

5607
					setCubeTexture( texture, textureUnit );
M
Mr.doob 已提交
5608

5609
				} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
M
Mr.doob 已提交
5610

5611
					setCubeTextureDynamic( texture, textureUnit );
5612

5613
				} else {
A
alteredq 已提交
5614

5615
					_this.setTexture( texture, textureUnit );
A
alteredq 已提交
5616

5617
				}
A
alteredq 已提交
5618

5619
			} else if ( type === "tv" ) { // array of THREE.Texture (2d)
5620

5621
				if ( uniform._array === undefined ) {
5622

5623
					uniform._array = [];
M
Mr.doob 已提交
5624

5625
				}
M
Mr.doob 已提交
5626

5627
				for( i = 0, il = uniform.value.length; i < il; i ++ ) {
M
Mr.doob 已提交
5628

5629
					uniform._array[ i ] = getTextureUnit();
M
Mr.doob 已提交
5630

5631
				}
M
Mr.doob 已提交
5632

5633
				_gl.uniform1iv( location, uniform._array );
M
Mr.doob 已提交
5634

5635
				for( i = 0, il = uniform.value.length; i < il; i ++ ) {
M
Mr.doob 已提交
5636

5637 5638
					texture = uniform.value[ i ];
					textureUnit = uniform._array[ i ];
M
Mr.doob 已提交
5639

5640
					if ( !texture ) continue;
M
Mr.doob 已提交
5641

5642
					_this.setTexture( texture, textureUnit );
M
Mr.doob 已提交
5643

5644
				}
M
Mr.doob 已提交
5645

M
Mr.doob 已提交
5646
			}
M
Mr.doob 已提交
5647

M
Mr.doob 已提交
5648
		}
M
Mr.doob 已提交
5649

5650
	};
M
Mr.doob 已提交
5651

A
alteredq 已提交
5652
	function setupMatrices ( object, camera ) {
M
Mr.doob 已提交
5653

5654
		object._modelViewMatrix.multiply( camera.matrixWorldInverse, object.matrixWorld );
M
Mr.doob 已提交
5655

5656
		object._normalMatrix.getInverse( object._modelViewMatrix );
5657
		object._normalMatrix.transpose();
M
Mr.doob 已提交
5658

A
alteredq 已提交
5659
	};
M
Mr.doob 已提交
5660

A
alteredq 已提交
5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678
	//

	function setColorGamma( array, offset, color, intensitySq ) {

		array[ offset ]     = color.r * color.r * intensitySq;
		array[ offset + 1 ] = color.g * color.g * intensitySq;
		array[ offset + 2 ] = color.b * color.b * intensitySq;

	};

	function setColorLinear( array, offset, color, intensity ) {

		array[ offset ]     = color.r * intensity;
		array[ offset + 1 ] = color.g * intensity;
		array[ offset + 2 ] = color.b * intensity;

	};

5679
	function setupLights ( program, lights ) {
M
Mr.doob 已提交
5680

5681 5682
		var l, ll, light, n,
		r = 0, g = 0, b = 0,
A
alteredq 已提交
5683 5684 5685 5686
		color, skyColor, groundColor,
		intensity,  intensitySq,
		position,
		distance,
M
Mr.doob 已提交
5687

5688
		zlights = _lights,
A
alteredq 已提交
5689

A
alteredq 已提交
5690 5691 5692 5693 5694 5695
		dirColors = zlights.directional.colors,
		dirPositions = zlights.directional.positions,

		pointColors = zlights.point.colors,
		pointPositions = zlights.point.positions,
		pointDistances = zlights.point.distances,
A
alteredq 已提交
5696

A
alteredq 已提交
5697 5698 5699 5700
		spotColors = zlights.spot.colors,
		spotPositions = zlights.spot.positions,
		spotDistances = zlights.spot.distances,
		spotDirections = zlights.spot.directions,
5701
		spotAnglesCos = zlights.spot.anglesCos,
A
alteredq 已提交
5702
		spotExponents = zlights.spot.exponents,
5703

A
alteredq 已提交
5704 5705 5706
		hemiSkyColors = zlights.hemi.skyColors,
		hemiGroundColors = zlights.hemi.groundColors,
		hemiPositions = zlights.hemi.positions,
A
alteredq 已提交
5707

A
alteredq 已提交
5708 5709 5710 5711
		dirLength = 0,
		pointLength = 0,
		spotLength = 0,
		hemiLength = 0,
5712

5713 5714 5715 5716 5717
		dirCount = 0,
		pointCount = 0,
		spotCount = 0,
		hemiCount = 0,

A
alteredq 已提交
5718 5719 5720 5721
		dirOffset = 0,
		pointOffset = 0,
		spotOffset = 0,
		hemiOffset = 0;
5722

5723
		for ( l = 0, ll = lights.length; l < ll; l ++ ) {
5724

5725
			light = lights[ l ];
A
alteredq 已提交
5726

5727
			if ( light.onlyShadow ) continue;
A
alteredq 已提交
5728 5729

			color = light.color;
5730 5731
			intensity = light.intensity;
			distance = light.distance;
A
alteredq 已提交
5732

5733
			if ( light instanceof THREE.AmbientLight ) {
5734

5735 5736
				if ( ! light.visible ) continue;

5737
				if ( _this.gammaInput ) {
5738

5739 5740 5741
					r += color.r * color.r;
					g += color.g * color.g;
					b += color.b * color.b;
5742

5743
				} else {
5744

5745 5746 5747
					r += color.r;
					g += color.g;
					b += color.b;
5748

5749
				}
5750

5751
			} else if ( light instanceof THREE.DirectionalLight ) {
5752

5753 5754 5755 5756
				dirCount += 1;

				if ( ! light.visible ) continue;

A
alteredq 已提交
5757
				dirOffset = dirLength * 3;
5758

5759
				if ( _this.gammaInput ) {
5760

A
alteredq 已提交
5761
					setColorGamma( dirColors, dirOffset, color, intensity * intensity );
5762

5763
				} else {
5764

A
alteredq 已提交
5765
					setColorLinear( dirColors, dirOffset, color, intensity );
A
alteredq 已提交
5766

5767
				}
A
alteredq 已提交
5768

5769 5770 5771
				_direction.copy( light.matrixWorld.getPosition() );
				_direction.subSelf( light.target.matrixWorld.getPosition() );
				_direction.normalize();
A
alteredq 已提交
5772

A
alteredq 已提交
5773 5774 5775
				dirPositions[ dirOffset ]     = _direction.x;
				dirPositions[ dirOffset + 1 ] = _direction.y;
				dirPositions[ dirOffset + 2 ] = _direction.z;
A
alteredq 已提交
5776

A
alteredq 已提交
5777
				dirLength += 1;
A
alteredq 已提交
5778

5779 5780 5781 5782 5783
			} else if ( light instanceof THREE.PointLight ) {

				pointCount += 1;

				if ( ! light.visible ) continue;
M
Mr.doob 已提交
5784

A
alteredq 已提交
5785
				pointOffset = pointLength * 3;
M
Mr.doob 已提交
5786

5787
				if ( _this.gammaInput ) {
5788

A
alteredq 已提交
5789
					setColorGamma( pointColors, pointOffset, color, intensity * intensity );
A
alteredq 已提交
5790

5791
				} else {
A
alteredq 已提交
5792

A
alteredq 已提交
5793
					setColorLinear( pointColors, pointOffset, color, intensity );
A
alteredq 已提交
5794

5795
				}
A
alteredq 已提交
5796

A
alteredq 已提交
5797 5798
				position = light.matrixWorld.getPosition();

A
alteredq 已提交
5799 5800 5801
				pointPositions[ pointOffset ]     = position.x;
				pointPositions[ pointOffset + 1 ] = position.y;
				pointPositions[ pointOffset + 2 ] = position.z;
A
alteredq 已提交
5802

A
alteredq 已提交
5803
				pointDistances[ pointLength ] = distance;
A
alteredq 已提交
5804

A
alteredq 已提交
5805
				pointLength += 1;
5806

5807 5808 5809 5810 5811
			} else if ( light instanceof THREE.SpotLight ) {

				spotCount += 1;

				if ( ! light.visible ) continue;
A
alteredq 已提交
5812

A
alteredq 已提交
5813
				spotOffset = spotLength * 3;
A
alteredq 已提交
5814 5815 5816

				if ( _this.gammaInput ) {

A
alteredq 已提交
5817
					setColorGamma( spotColors, spotOffset, color, intensity * intensity );
A
alteredq 已提交
5818 5819 5820

				} else {

A
alteredq 已提交
5821
					setColorLinear( spotColors, spotOffset, color, intensity );
A
alteredq 已提交
5822 5823 5824 5825 5826

				}

				position = light.matrixWorld.getPosition();

A
alteredq 已提交
5827 5828 5829
				spotPositions[ spotOffset ]     = position.x;
				spotPositions[ spotOffset + 1 ] = position.y;
				spotPositions[ spotOffset + 2 ] = position.z;
A
alteredq 已提交
5830

A
alteredq 已提交
5831
				spotDistances[ spotLength ] = distance;
A
alteredq 已提交
5832 5833 5834 5835 5836

				_direction.copy( position );
				_direction.subSelf( light.target.matrixWorld.getPosition() );
				_direction.normalize();

A
alteredq 已提交
5837 5838 5839 5840
				spotDirections[ spotOffset ]     = _direction.x;
				spotDirections[ spotOffset + 1 ] = _direction.y;
				spotDirections[ spotOffset + 2 ] = _direction.z;

5841
				spotAnglesCos[ spotLength ] = Math.cos( light.angle );
A
alteredq 已提交
5842 5843 5844 5845 5846
				spotExponents[ spotLength ] = light.exponent;

				spotLength += 1;

			} else if ( light instanceof THREE.HemisphereLight ) {
A
alteredq 已提交
5847

5848 5849 5850 5851
				hemiCount += 1;

				if ( ! light.visible ) continue;

A
alteredq 已提交
5852 5853
				skyColor = light.color;
				groundColor = light.groundColor;
A
alteredq 已提交
5854

A
alteredq 已提交
5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870
				hemiOffset = hemiLength * 3;

				if ( _this.gammaInput ) {

					intensitySq = intensity * intensity;

					setColorGamma( hemiSkyColors, hemiOffset, skyColor, intensitySq );
					setColorGamma( hemiGroundColors, hemiOffset, groundColor, intensitySq );

				} else {

					setColorLinear( hemiSkyColors, hemiOffset, skyColor, intensity );
					setColorLinear( hemiGroundColors, hemiOffset, groundColor, intensity );

				}

A
alteredq 已提交
5871 5872
				_direction.copy( light.matrixWorld.getPosition() );
				_direction.normalize();
A
alteredq 已提交
5873

A
alteredq 已提交
5874 5875 5876
				hemiPositions[ hemiOffset ]     = _direction.x;
				hemiPositions[ hemiOffset + 1 ] = _direction.y;
				hemiPositions[ hemiOffset + 2 ] = _direction.z;
A
alteredq 已提交
5877 5878

				hemiLength += 1;
A
alteredq 已提交
5879

5880
			}
5881

5882
		}
A
alteredq 已提交
5883

5884 5885
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
A
alteredq 已提交
5886

5887 5888 5889 5890 5891 5892 5893 5894 5895 5896
		for ( l = dirLength * 3, ll = Math.max( dirColors.length, dirCount * 3 ); l < ll; l ++ ) dirColors[ l ] = 0.0;
		for ( l = dirLength * 3, ll = Math.max( dirPositions.length, dirCount * 3 ); l < ll; l ++ ) dirPositions[ l ] = 0.0;

		for ( l = pointLength * 3, ll = Math.max( pointColors.length, pointCount * 3 ); l < ll; l ++ ) pointColors[ l ] = 0.0;
		for ( l = pointLength * 3, ll = Math.max( pointPositions.length, pointCount * 3 ); l < ll; l ++ ) pointPositions[ l ] = 0.0;
		for ( l = pointLength, ll = Math.max( pointDistances.length, pointCount ); l < ll; l ++ ) pointDistances[ l ] = 0.0;

		for ( l = spotLength * 3, ll = Math.max( spotColors.length, spotCount * 3 ); l < ll; l ++ ) spotColors[ l ] = 0.0;
		for ( l = spotLength * 3, ll = Math.max( spotPositions.length, spotCount * 3 ); l < ll; l ++ ) spotPositions[ l ] = 0.0;
		for ( l = spotLength * 3, ll = Math.max( spotDirections.length, spotCount * 3 ); l < ll; l ++ ) spotDirections[ l ] = 0.0;
5897
		for ( l = spotLength, ll = Math.max( spotAnglesCos.length, spotCount ); l < ll; l ++ ) spotAnglesCos[ l ] = 0.0;
5898 5899 5900 5901 5902 5903
		for ( l = spotLength, ll = Math.max( spotExponents.length, spotCount ); l < ll; l ++ ) spotExponents[ l ] = 0.0;
		for ( l = spotLength, ll = Math.max( spotDistances.length, spotCount ); l < ll; l ++ ) spotDistances[ l ] = 0.0;

		for ( l = hemiLength * 3, ll = Math.max( hemiSkyColors.length, hemiCount * 3 ); l < ll; l ++ ) hemiSkyColors[ l ] = 0.0;
		for ( l = hemiLength * 3, ll = Math.max( hemiGroundColors.length, hemiCount * 3 ); l < ll; l ++ ) hemiGroundColors[ l ] = 0.0;
		for ( l = hemiLength * 3, ll = Math.max( hemiPositions.length, hemiCount * 3 ); l < ll; l ++ ) hemiPositions[ l ] = 0.0;
A
alteredq 已提交
5904

A
alteredq 已提交
5905 5906 5907 5908
		zlights.directional.length = dirLength;
		zlights.point.length = pointLength;
		zlights.spot.length = spotLength;
		zlights.hemi.length = hemiLength;
A
alteredq 已提交
5909

5910 5911 5912
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
5913

5914
	};
M
Mr.doob 已提交
5915

5916
	// GL state setting
M
Mr.doob 已提交
5917

5918
	this.setFaceCulling = function ( cullFace, frontFace ) {
M
Mr.doob 已提交
5919

5920
		if ( cullFace ) {
M
Mr.doob 已提交
5921

5922
			if ( !frontFace || frontFace === "ccw" ) {
5923

5924
				_gl.frontFace( _gl.CCW );
5925

5926
			} else {
5927

5928
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
5929

5930
			}
M
Mr.doob 已提交
5931

5932
			if( cullFace === "back" ) {
5933

5934
				_gl.cullFace( _gl.BACK );
5935

5936
			} else if( cullFace === "front" ) {
5937

5938
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
5939

5940
			} else {
5941

5942
				_gl.cullFace( _gl.FRONT_AND_BACK );
5943

5944
			}
5945

5946
			_gl.enable( _gl.CULL_FACE );
5947

5948
		} else {
5949

5950
			_gl.disable( _gl.CULL_FACE );
5951 5952 5953 5954 5955

		}

	};

5956
	this.setMaterialFaces = function ( material ) {
5957

5958 5959
		var doubleSided = material.side === THREE.DoubleSide;
		var flipSided = material.side === THREE.BackSide;
M
Mr.doob 已提交
5960

5961 5962 5963
		if ( _oldDoubleSided !== doubleSided ) {

			if ( doubleSided ) {
M
Mr.doob 已提交
5964

5965
				_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
5966

5967
			} else {
5968

5969
				_gl.enable( _gl.CULL_FACE );
5970

5971
			}
5972

5973
			_oldDoubleSided = doubleSided;
5974

5975
		}
5976

5977
		if ( _oldFlipSided !== flipSided ) {
5978

5979
			if ( flipSided ) {
5980

5981
				_gl.frontFace( _gl.CW );
5982

5983
			} else {
5984

5985
				_gl.frontFace( _gl.CCW );
5986

5987
			}
5988

5989
			_oldFlipSided = flipSided;
5990

5991
		}
5992

5993
	};
5994

A
alteredq 已提交
5995
	this.setDepthTest = function ( depthTest ) {
5996

5997
		if ( _oldDepthTest !== depthTest ) {
5998

5999
			if ( depthTest ) {
6000

6001
				_gl.enable( _gl.DEPTH_TEST );
6002

6003
			} else {
6004

6005
				_gl.disable( _gl.DEPTH_TEST );
6006 6007 6008

			}

6009
			_oldDepthTest = depthTest;
6010

6011
		}
6012

6013
	};
6014

6015
	this.setDepthWrite = function ( depthWrite ) {
A
alteredq 已提交
6016

6017
		if ( _oldDepthWrite !== depthWrite ) {
A
alteredq 已提交
6018

6019 6020
			_gl.depthMask( depthWrite );
			_oldDepthWrite = depthWrite;
A
alteredq 已提交
6021 6022 6023 6024 6025

		}

	};

6026
	function setLineWidth ( width ) {
6027

6028
		if ( width !== _oldLineWidth ) {
6029

6030 6031 6032
			_gl.lineWidth( width );

			_oldLineWidth = width;
6033 6034 6035

		}

6036
	};
6037

6038
	function setPolygonOffset ( polygonoffset, factor, units ) {
6039

6040
		if ( _oldPolygonOffset !== polygonoffset ) {
M
Mr.doob 已提交
6041

6042
			if ( polygonoffset ) {
6043

6044
				_gl.enable( _gl.POLYGON_OFFSET_FILL );
6045

6046
			} else {
6047

6048
				_gl.disable( _gl.POLYGON_OFFSET_FILL );
6049

6050
			}
6051

6052
			_oldPolygonOffset = polygonoffset;
6053

6054
		}
6055

6056
		if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
6057

6058
			_gl.polygonOffset( factor, units );
M
Mr.doob 已提交
6059

6060 6061
			_oldPolygonOffsetFactor = factor;
			_oldPolygonOffsetUnits = units;
M
Mr.doob 已提交
6062

6063
		}
M
Mr.doob 已提交
6064

6065
	};
M
Mr.doob 已提交
6066

6067
	this.setBlending = function ( blending, blendEquation, blendSrc, blendDst ) {
M
Mr.doob 已提交
6068

6069
		if ( blending !== _oldBlending ) {
M
Mr.doob 已提交
6070

6071
			if ( blending === THREE.NoBlending ) {
M
Mr.doob 已提交
6072

6073
				_gl.disable( _gl.BLEND );
M
Mr.doob 已提交
6074

6075
			} else if ( blending === THREE.AdditiveBlending ) {
M
Mr.doob 已提交
6076

6077 6078 6079
				_gl.enable( _gl.BLEND );
				_gl.blendEquation( _gl.FUNC_ADD );
				_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
M
Mr.doob 已提交
6080

6081
			} else if ( blending === THREE.SubtractiveBlending ) {
M
Mr.doob 已提交
6082

6083 6084 6085 6086
				// TODO: Find blendFuncSeparate() combination
				_gl.enable( _gl.BLEND );
				_gl.blendEquation( _gl.FUNC_ADD );
				_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
M
Mr.doob 已提交
6087

6088
			} else if ( blending === THREE.MultiplyBlending ) {
M
Mr.doob 已提交
6089

6090 6091 6092 6093
				// TODO: Find blendFuncSeparate() combination
				_gl.enable( _gl.BLEND );
				_gl.blendEquation( _gl.FUNC_ADD );
				_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
6094

6095
			} else if ( blending === THREE.CustomBlending ) {
6096

6097
				_gl.enable( _gl.BLEND );
6098

6099
			} else {
6100

6101 6102 6103
				_gl.enable( _gl.BLEND );
				_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 );
6104

6105
			}
6106

6107
			_oldBlending = blending;
6108

6109
		}
6110

6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137
		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;

		}

6138
	};
6139

6140 6141 6142 6143
	// Defines

	function generateDefines ( defines ) {

6144
		var value, chunk, chunks = [];
6145 6146 6147

		for ( var d in defines ) {

6148 6149 6150 6151
			value = defines[ d ];
			if ( value === false ) continue;

			chunk = "#define " + d + " " + value;
6152 6153 6154 6155 6156 6157 6158 6159
			chunks.push( chunk );

		}

		return chunks.join( "\n" );

	};

6160 6161
	// Shaders

6162
	function buildProgram ( shaderID, fragmentShader, vertexShader, uniforms, attributes, defines, parameters ) {
6163

6164
		var p, pl, d, program, code;
6165
		var chunks = [];
6166 6167 6168

		// Generate code

6169 6170 6171 6172 6173 6174 6175 6176 6177 6178
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

			chunks.push( fragmentShader );
			chunks.push( vertexShader );

		}
6179

6180 6181 6182 6183 6184 6185 6186
		for ( d in defines ) {

			chunks.push( d );
			chunks.push( defines[ d ] );

		}

6187 6188
		for ( p in parameters ) {

6189 6190
			chunks.push( p );
			chunks.push( parameters[ p ] );
6191 6192 6193

		}

6194 6195
		code = chunks.join();

6196 6197 6198 6199
		// Check if code has been already compiled

		for ( p = 0, pl = _programs.length; p < pl; p ++ ) {

A
alteredq 已提交
6200 6201 6202
			var programInfo = _programs[ p ];

			if ( programInfo.code === code ) {
6203

6204
				//console.log( "Code already compiled." /*: \n\n" + code*/ );
6205

A
alteredq 已提交
6206 6207 6208
				programInfo.usedTimes ++;

				return programInfo.program;
6209 6210 6211 6212

			}

		}
6213

6214
		//console.log( "building new program " );
6215 6216 6217

		//

6218 6219 6220 6221
		var customDefines = generateDefines( defines );

		//

6222
		program = _gl.createProgram();
M
Mr.doob 已提交
6223

6224
		var prefix_vertex = [
M
Mr.doob 已提交
6225

6226 6227
			"precision " + _precision + " float;",

6228 6229
			customDefines,

6230
			_supportsVertexTextures ? "#define VERTEX_TEXTURES" : "",
6231

6232 6233 6234 6235
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

6236 6237
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
6238
			"#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
A
alteredq 已提交
6239
			"#define MAX_HEMI_LIGHTS " + parameters.maxHemiLights,
6240

6241 6242
			"#define MAX_SHADOWS " + parameters.maxShadows,

6243 6244
			"#define MAX_BONES " + parameters.maxBones,

6245
			parameters.map ? "#define USE_MAP" : "",
6246 6247
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
6248
			parameters.bumpMap ? "#define USE_BUMPMAP" : "",
6249
			parameters.normalMap ? "#define USE_NORMALMAP" : "",
6250
			parameters.specularMap ? "#define USE_SPECULARMAP" : "",
6251
			parameters.vertexColors ? "#define USE_COLOR" : "",
6252

6253
			parameters.skinning ? "#define USE_SKINNING" : "",
6254
			parameters.useVertexTexture ? "#define BONE_TEXTURE" : "",
6255 6256
			parameters.boneTextureWidth ? "#define N_BONE_PIXEL_X " + parameters.boneTextureWidth.toFixed( 1 ) : "",
			parameters.boneTextureHeight ? "#define N_BONE_PIXEL_Y " + parameters.boneTextureHeight.toFixed( 1 ) : "",
6257

6258
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
A
alteredq 已提交
6259
			parameters.morphNormals ? "#define USE_MORPHNORMALS" : "",
A
alteredq 已提交
6260
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
6261
			parameters.wrapAround ? "#define WRAP_AROUND" : "",
6262
			parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
6263
			parameters.flipSided ? "#define FLIP_SIDED" : "",
6264

6265
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
6266
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
A
alteredq 已提交
6267 6268
			parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
			parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
6269

6270 6271
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

6272
			"uniform mat4 modelMatrix;",
M
Mr.doob 已提交
6273 6274
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
6275 6276
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
6277
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
6278

M
Mr.doob 已提交
6279 6280 6281
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
6282
			"attribute vec2 uv2;",
6283

6284
			"#ifdef USE_COLOR",
6285

6286
				"attribute vec3 color;",
6287

6288 6289
			"#endif",

6290
			"#ifdef USE_MORPHTARGETS",
6291

6292 6293 6294 6295
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
A
alteredq 已提交
6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311

				"#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",
6312

6313 6314 6315
			"#endif",

			"#ifdef USE_SKINNING",
6316

6317 6318
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
6319

6320
			"#endif",
6321

M
Mr.doob 已提交
6322
			""
A
alteredq 已提交
6323

M
Mr.doob 已提交
6324
		].join("\n");
6325

M
Mr.doob 已提交
6326 6327
		var prefix_fragment = [

6328
			"precision " + _precision + " float;",
M
Mr.doob 已提交
6329

6330
			( parameters.bumpMap || parameters.normalMap ) ? "#extension GL_OES_standard_derivatives : enable" : "",
6331

6332 6333
			customDefines,

M
Mr.doob 已提交
6334 6335
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
6336
			"#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
A
alteredq 已提交
6337
			"#define MAX_HEMI_LIGHTS " + parameters.maxHemiLights,
M
Mr.doob 已提交
6338

6339 6340
			"#define MAX_SHADOWS " + parameters.maxShadows,

6341 6342
			parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",

6343 6344 6345 6346
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

M
Mr.doob 已提交
6347
			( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
6348
			( parameters.useFog && parameters.fogExp ) ? "#define FOG_EXP2" : "",
M
Mr.doob 已提交
6349 6350 6351 6352

			parameters.map ? "#define USE_MAP" : "",
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
6353
			parameters.bumpMap ? "#define USE_BUMPMAP" : "",
6354
			parameters.normalMap ? "#define USE_NORMALMAP" : "",
6355
			parameters.specularMap ? "#define USE_SPECULARMAP" : "",
M
Mr.doob 已提交
6356
			parameters.vertexColors ? "#define USE_COLOR" : "",
6357

6358 6359
			parameters.metal ? "#define METAL" : "",
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
6360
			parameters.wrapAround ? "#define WRAP_AROUND" : "",
6361
			parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
6362
			parameters.flipSided ? "#define FLIP_SIDED" : "",
6363

6364
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
6365
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
A
alteredq 已提交
6366 6367
			parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
			parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
M
Mr.doob 已提交
6368 6369 6370 6371 6372 6373 6374

			"uniform mat4 viewMatrix;",
			"uniform vec3 cameraPosition;",
			""

		].join("\n");

6375 6376 6377 6378 6379
		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 已提交
6380

M
Mr.doob 已提交
6381
		_gl.linkProgram( program );
N
Nicolas Garcia Belmonte 已提交
6382

M
Mr.doob 已提交
6383
		if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
N
Nicolas Garcia Belmonte 已提交
6384

6385
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
6386

N
Nicolas Garcia Belmonte 已提交
6387
		}
6388

6389 6390 6391 6392 6393
		// clean up

		_gl.deleteShader( glFragmentShader );
		_gl.deleteShader( glVertexShader );

6394 6395
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
6396

M
Mr.doob 已提交
6397
		program.uniforms = {};
6398
		program.attributes = {};
M
Mr.doob 已提交
6399

6400 6401 6402 6403
		var identifiers, u, a, i;

		// cache uniform locations

6404
		identifiers = [
6405

6406
			'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'modelMatrix', 'cameraPosition',
6407
			'morphTargetInfluences'
M
Mr.doob 已提交
6408

6409
		];
M
Mr.doob 已提交
6410

6411
		if ( parameters.useVertexTexture ) {
6412 6413 6414 6415 6416 6417 6418 6419 6420

			identifiers.push( 'boneTexture' );

		} else {

			identifiers.push( 'boneGlobalMatrices' );

		}

6421
		for ( u in uniforms ) {
M
Mr.doob 已提交
6422

6423
			identifiers.push( u );
M
Mr.doob 已提交
6424

6425
		}
M
Mr.doob 已提交
6426

6427
		cacheUniformLocations( program, identifiers );
M
Mr.doob 已提交
6428

6429
		// cache attributes locations
M
Mr.doob 已提交
6430

6431
		identifiers = [
A
alteredq 已提交
6432

6433
			"position", "normal", "uv", "uv2", "tangent", "color",
6434
			"skinIndex", "skinWeight", "lineDistance"
A
alteredq 已提交
6435

6436
		];
M
Mr.doob 已提交
6437

6438
		for ( i = 0; i < parameters.maxMorphTargets; i ++ ) {
M
Mr.doob 已提交
6439

6440
			identifiers.push( "morphTarget" + i );
M
Mr.doob 已提交
6441

6442
		}
6443

A
alteredq 已提交
6444 6445 6446 6447 6448 6449
		for ( i = 0; i < parameters.maxMorphNormals; i ++ ) {

			identifiers.push( "morphNormal" + i );

		}

6450
		for ( a in attributes ) {
6451

6452
			identifiers.push( a );
6453

6454
		}
6455

6456
		cacheAttributeLocations( program, identifiers );
6457

A
alteredq 已提交
6458
		program.id = _programs_counter ++;
6459

A
alteredq 已提交
6460
		_programs.push( { program: program, code: code, usedTimes: 1 } );
6461

6462
		_this.info.memory.programs = _programs.length;
6463

6464
		return program;
6465

6466
	};
6467

6468
	// Shader parameters cache
6469

6470
	function cacheUniformLocations ( program, identifiers ) {
6471

6472
		var i, l, id;
6473

6474
		for( i = 0, l = identifiers.length; i < l; i ++ ) {
6475

6476 6477
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
6478

6479
		}
M
Mr.doob 已提交
6480

6481
	};
M
Mr.doob 已提交
6482

6483
	function cacheAttributeLocations ( program, identifiers ) {
A
alteredq 已提交
6484

6485
		var i, l, id;
A
alteredq 已提交
6486

6487
		for( i = 0, l = identifiers.length; i < l; i ++ ) {
A
alteredq 已提交
6488

6489 6490
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
A
alteredq 已提交
6491

6492
		}
6493

6494
	};
A
alteredq 已提交
6495

6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512
	function addLineNumbers ( string ) {

		var chunks = string.split( "\n" );

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

			// Chrome reports shader errors on lines
			// starting counting from 1

			chunks[ i ] = ( i + 1 ) + ": " + chunks[ i ];

		}

		return chunks.join( "\n" );

	};

6513
	function getShader ( type, string ) {
A
alteredq 已提交
6514

6515
		var shader;
6516

6517
		if ( type === "fragment" ) {
A
alteredq 已提交
6518

6519
			shader = _gl.createShader( _gl.FRAGMENT_SHADER );
A
alteredq 已提交
6520

6521
		} else if ( type === "vertex" ) {
A
alteredq 已提交
6522

6523
			shader = _gl.createShader( _gl.VERTEX_SHADER );
A
alteredq 已提交
6524

6525
		}
A
alteredq 已提交
6526

6527 6528
		_gl.shaderSource( shader, string );
		_gl.compileShader( shader );
6529

6530
		if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {
6531

6532
			console.error( _gl.getShaderInfoLog( shader ) );
6533
			console.error( addLineNumbers( string ) );
6534
			return null;
6535

A
alteredq 已提交
6536 6537
		}

6538 6539
		return shader;

A
alteredq 已提交
6540
	};
6541

6542 6543
	// Textures

6544 6545 6546 6547 6548 6549 6550

	function isPowerOfTwo ( value ) {

		return ( value & ( value - 1 ) ) === 0;

	};

6551
	function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {
6552

6553
		if ( isImagePowerOfTwo ) {
M
Mr.doob 已提交
6554

6555 6556
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
6557

6558 6559
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
6560

6561
		} else {
M
Mr.doob 已提交
6562

6563 6564
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
6565

6566 6567
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
6568

6569
		}
M
Mr.doob 已提交
6570

6571
		if ( _glExtensionTextureFilterAnisotropic && texture.type !== THREE.FloatType ) {
6572

6573 6574 6575 6576 6577 6578
			if ( texture.anisotropy > 1 || texture.__oldAnisotropy ) {

				_gl.texParameterf( textureType, _glExtensionTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _maxAnisotropy ) );
				texture.__oldAnisotropy = texture.anisotropy;

			}
6579 6580 6581

		}

6582
	};
6583

6584
	this.setTexture = function ( texture, slot ) {
6585

6586
		if ( texture.needsUpdate ) {
A
alteredq 已提交
6587

6588
			if ( ! texture.__webglInit ) {
M
Mr.doob 已提交
6589

6590
				texture.__webglInit = true;
6591
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
6592

M
Mr.doob 已提交
6593 6594
				_this.info.memory.textures ++;

6595
			}
M
Mr.doob 已提交
6596

6597
			_gl.activeTexture( _gl.TEXTURE0 + slot );
6598 6599
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );

6600
			_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
6601 6602
			_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );

6603 6604
			var image = texture.image,
			isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
6605 6606
			glFormat = paramThreeToGL( texture.format ),
			glType = paramThreeToGL( texture.type );
6607

6608 6609
			setTextureParameters( _gl.TEXTURE_2D, texture, isImagePowerOfTwo );

6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621
			if ( texture instanceof THREE.CompressedTexture ) {

				var mipmap, mipmaps = texture.mipmaps;

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

					mipmap = mipmaps[ i ];
					_gl.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );

				}

			} else if ( texture instanceof THREE.DataTexture ) {
6622

6623
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );
M
Mr.doob 已提交
6624

A
alteredq 已提交
6625
			} else {
M
Mr.doob 已提交
6626

6627
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, texture.image );
M
Mr.doob 已提交
6628 6629 6630

			}

6631
			if ( texture.generateMipmaps && isImagePowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
M
Mr.doob 已提交
6632

A
alteredq 已提交
6633
			texture.needsUpdate = false;
6634

6635
			if ( texture.onUpdate ) texture.onUpdate();
6636

6637
		} else {
6638

6639 6640
			_gl.activeTexture( _gl.TEXTURE0 + slot );
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
6641 6642

		}
M
Mr.doob 已提交
6643

6644
	};
M
Mr.doob 已提交
6645

6646 6647 6648 6649 6650 6651 6652 6653 6654 6655
	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.
6656

6657 6658 6659 6660 6661 6662 6663
		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;
6664

6665
		var ctx = canvas.getContext( "2d" );
6666 6667
		ctx.drawImage( image, 0, 0, image.width, image.height, 0, 0, newWidth, newHeight );

6668 6669 6670 6671
		return canvas;

	}

6672
	function setCubeTexture ( texture, slot ) {
6673

6674
		if ( texture.image.length === 6 ) {
6675 6676 6677

			if ( texture.needsUpdate ) {

A
alteredq 已提交
6678
				if ( ! texture.image.__webglTextureCube ) {
6679 6680

					texture.image.__webglTextureCube = _gl.createTexture();
6681

A
alteredq 已提交
6682
				}
6683

A
alteredq 已提交
6684 6685
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
6686

6687
				_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
M
Mr.doob 已提交
6688

6689 6690
				var isCompressed = texture instanceof THREE.CompressedTexture;

6691
				var cubeImage = [];
6692

A
alteredq 已提交
6693
				for ( var i = 0; i < 6; i ++ ) {
6694

6695
					if ( _this.autoScaleCubemaps && ! isCompressed ) {
6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706

						cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize );

					} else {

						cubeImage[ i ] = texture.image[ i ];

					}

				}

6707 6708
				var image = cubeImage[ 0 ],
				isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
6709 6710
				glFormat = paramThreeToGL( texture.format ),
				glType = paramThreeToGL( texture.type );
6711

6712 6713
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo );

A
alteredq 已提交
6714
				for ( var i = 0; i < 6; i ++ ) {
6715

6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731
					if ( isCompressed ) {

						var mipmap, mipmaps = cubeImage[ i ].mipmaps;

						for( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {

							mipmap = mipmaps[ j ];
							_gl.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );

						}

					} else {

						_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );

					}
6732

A
alteredq 已提交
6733
				}
6734

M
Mr.doob 已提交
6735 6736 6737 6738 6739
				if ( texture.generateMipmaps && isImagePowerOfTwo ) {

					_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

				}
6740

A
alteredq 已提交
6741
				texture.needsUpdate = false;
6742

6743
				if ( texture.onUpdate ) texture.onUpdate();
6744

A
alteredq 已提交
6745
			} else {
6746

A
alteredq 已提交
6747 6748
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
6749

A
alteredq 已提交
6750
			}
6751

A
alteredq 已提交
6752
		}
6753

A
alteredq 已提交
6754
	};
6755

6756
	function setCubeTextureDynamic ( texture, slot ) {
6757

A
alteredq 已提交
6758 6759
		_gl.activeTexture( _gl.TEXTURE0 + slot );
		_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
6760 6761 6762

	};

6763 6764 6765
	// Render targets

	function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
6766

6767 6768
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
A
alteredq 已提交
6769

6770
	};
M
Mr.doob 已提交
6771

6772
	function setupRenderBuffer ( renderbuffer, renderTarget  ) {
M
Mikael Emtinger 已提交
6773

6774
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
6775

6776
		if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
M
Mr.doob 已提交
6777

6778 6779
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
6780

6781 6782
		/* For some reason this is not working. Defaulting to RGBA4.
		} else if( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
A
alteredq 已提交
6783

6784 6785 6786 6787
			_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 已提交
6788

6789 6790
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
6791

6792
		} else {
A
alteredq 已提交
6793

6794
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
A
alteredq 已提交
6795

6796
		}
A
alteredq 已提交
6797

6798
	};
A
alteredq 已提交
6799

A
alteredq 已提交
6800
	this.setRenderTarget = function ( renderTarget ) {
A
alteredq 已提交
6801

6802
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
A
alteredq 已提交
6803

6804
		if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
A
alteredq 已提交
6805

M
Mr.doob 已提交
6806 6807
			if ( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
			if ( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
A
alteredq 已提交
6808

6809
			renderTarget.__webglTexture = _gl.createTexture();
A
alteredq 已提交
6810

6811
			// Setup texture, create render and frame buffers
6812

6813 6814
			var isTargetPowerOfTwo = isPowerOfTwo( renderTarget.width ) && isPowerOfTwo( renderTarget.height ),
				glFormat = paramThreeToGL( renderTarget.format ),
6815 6816
				glType = paramThreeToGL( renderTarget.type );

6817
			if ( isCube ) {
M
Mr.doob 已提交
6818

6819 6820
				renderTarget.__webglFramebuffer = [];
				renderTarget.__webglRenderbuffer = [];
M
Mikael Emtinger 已提交
6821

6822
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
6823
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, isTargetPowerOfTwo );
A
alteredq 已提交
6824

6825
				for ( var i = 0; i < 6; i ++ ) {
A
alteredq 已提交
6826

6827 6828
					renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
					renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
A
alteredq 已提交
6829

6830
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
A
alteredq 已提交
6831

6832 6833
					setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
					setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
A
alteredq 已提交
6834

6835
				}
6836

6837 6838
				if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

6839
			} else {
6840

6841 6842
				renderTarget.__webglFramebuffer = _gl.createFramebuffer();
				renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
6843

6844
				_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
6845
				setTextureParameters( _gl.TEXTURE_2D, renderTarget, isTargetPowerOfTwo );
6846

6847
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
6848

6849 6850
				setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
				setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
6851

6852 6853
				if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );

M
Mikael Emtinger 已提交
6854
			}
6855

6856
			// Release everything
M
Mr.doob 已提交
6857

A
alteredq 已提交
6858 6859 6860 6861 6862 6863 6864 6865 6866 6867
			if ( isCube ) {

				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

			} else {

				_gl.bindTexture( _gl.TEXTURE_2D, null );

			}

6868 6869
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
6870

6871 6872
		}

6873
		var framebuffer, width, height, vx, vy;
M
Mr.doob 已提交
6874

6875
		if ( renderTarget ) {
M
Mr.doob 已提交
6876

A
alteredq 已提交
6877 6878
			if ( isCube ) {

6879
				framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
A
alteredq 已提交
6880 6881 6882

			} else {

6883
				framebuffer = renderTarget.__webglFramebuffer;
A
alteredq 已提交
6884 6885 6886

			}

6887 6888
			width = renderTarget.width;
			height = renderTarget.height;
M
Mr.doob 已提交
6889

6890 6891 6892
			vx = 0;
			vy = 0;

6893
		} else {
M
Mr.doob 已提交
6894

6895
			framebuffer = null;
6896

6897 6898
			width = _viewportWidth;
			height = _viewportHeight;
6899

6900 6901
			vx = _viewportX;
			vy = _viewportY;
M
Mr.doob 已提交
6902

6903
		}
M
Mr.doob 已提交
6904

6905
		if ( framebuffer !== _currentFramebuffer ) {
M
Mr.doob 已提交
6906

6907
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
6908
			_gl.viewport( vx, vy, width, height );
M
Mr.doob 已提交
6909

6910
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
6911

6912
		}
6913

A
alteredq 已提交
6914 6915 6916
		_currentWidth = width;
		_currentHeight = height;

6917
	};
M
Mr.doob 已提交
6918

6919
	function updateRenderTargetMipmap ( renderTarget ) {
M
Mr.doob 已提交
6920

A
alteredq 已提交
6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931 6932 6933
		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 已提交
6934 6935

	};
6936

6937
	// Fallback filters for non-power-of-2 textures
6938

6939
	function filterFallback ( f ) {
6940

6941
		if ( f === THREE.NearestFilter || f === THREE.NearestMipMapNearestFilter || f === THREE.NearestMipMapLinearFilter ) {
6942

6943
			return _gl.NEAREST;
6944 6945

		}
6946

6947 6948
		return _gl.LINEAR;

6949
	};
6950

6951 6952
	// Map three.js constants to WebGL constants

6953
	function paramThreeToGL ( p ) {
M
Mr.doob 已提交
6954

6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966 6967 6968 6969 6970 6971 6972 6973 6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999 7000
		if ( p === THREE.RepeatWrapping ) return _gl.REPEAT;
		if ( p === THREE.ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;
		if ( p === THREE.MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;

		if ( p === THREE.NearestFilter ) return _gl.NEAREST;
		if ( p === THREE.NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;
		if ( p === THREE.NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;

		if ( p === THREE.LinearFilter ) return _gl.LINEAR;
		if ( p === THREE.LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;
		if ( p === THREE.LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;

		if ( p === THREE.UnsignedByteType ) return _gl.UNSIGNED_BYTE;
		if ( p === THREE.UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;
		if ( p === THREE.UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;
		if ( p === THREE.UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;

		if ( p === THREE.ByteType ) return _gl.BYTE;
		if ( p === THREE.ShortType ) return _gl.SHORT;
		if ( p === THREE.UnsignedShortType ) return _gl.UNSIGNED_SHORT;
		if ( p === THREE.IntType ) return _gl.INT;
		if ( p === THREE.UnsignedIntType ) return _gl.UNSIGNED_INT;
		if ( p === THREE.FloatType ) return _gl.FLOAT;

		if ( p === THREE.AlphaFormat ) return _gl.ALPHA;
		if ( p === THREE.RGBFormat ) return _gl.RGB;
		if ( p === THREE.RGBAFormat ) return _gl.RGBA;
		if ( p === THREE.LuminanceFormat ) return _gl.LUMINANCE;
		if ( p === THREE.LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;

		if ( p === THREE.AddEquation ) return _gl.FUNC_ADD;
		if ( p === THREE.SubtractEquation ) return _gl.FUNC_SUBTRACT;
		if ( p === THREE.ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;

		if ( p === THREE.ZeroFactor ) return _gl.ZERO;
		if ( p === THREE.OneFactor ) return _gl.ONE;
		if ( p === THREE.SrcColorFactor ) return _gl.SRC_COLOR;
		if ( p === THREE.OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;
		if ( p === THREE.SrcAlphaFactor ) return _gl.SRC_ALPHA;
		if ( p === THREE.OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;
		if ( p === THREE.DstAlphaFactor ) return _gl.DST_ALPHA;
		if ( p === THREE.OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;

		if ( p === THREE.DstColorFactor ) return _gl.DST_COLOR;
		if ( p === THREE.OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;
		if ( p === THREE.SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;
M
Mr.doob 已提交
7001

7002 7003 7004 7005 7006 7007 7008 7009 7010
		if ( _glExtensionCompressedTextureS3TC !== undefined ) {

			if ( p === THREE.RGB_S3TC_DXT1_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGB_S3TC_DXT1_EXT;
			if ( p === THREE.RGBA_S3TC_DXT1_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT1_EXT;
			if ( p === THREE.RGBA_S3TC_DXT3_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT3_EXT;
			if ( p === THREE.RGBA_S3TC_DXT5_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT5_EXT;

		}

7011
		return 0;
M
Mr.doob 已提交
7012

7013 7014
	};

7015
	// Allocations
7016

7017
	function allocateBones ( object ) {
7018

7019
		if ( _supportsBoneTextures && object && object.useVertexTexture ) {
7020 7021

			return 1024;
7022

7023
		} else {
7024

7025 7026 7027 7028 7029 7030 7031
			// 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)
7032

7033 7034
			var nVertexUniforms = _gl.getParameter( _gl.MAX_VERTEX_UNIFORM_VECTORS );
			var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );
7035

7036
			var maxBones = nVertexMatrices;
7037

7038
			if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
7039

7040
				maxBones = Math.min( object.bones.length, maxBones );
7041

7042
				if ( maxBones < object.bones.length ) {
7043

7044
					console.warn( "WebGLRenderer: too many bones - " + object.bones.length + ", this GPU supports just " + maxBones + " (try OpenGL instead of ANGLE)" );
7045

7046
				}
7047

7048
			}
7049

7050
			return maxBones;
7051

7052 7053 7054
		}

	};
7055

7056
	function allocateLights ( lights ) {
7057

7058
		var l, ll, light, dirLights, pointLights, spotLights, hemiLights;
7059

7060
		dirLights = pointLights = spotLights = hemiLights = 0;
A
alteredq 已提交
7061 7062

		for ( l = 0, ll = lights.length; l < ll; l ++ ) {
7063

7064
			light = lights[ l ];
7065

A
alteredq 已提交
7066 7067
			if ( light.onlyShadow ) continue;

7068 7069
			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
			if ( light instanceof THREE.PointLight ) pointLights ++;
A
alteredq 已提交
7070
			if ( light instanceof THREE.SpotLight ) spotLights ++;
A
alteredq 已提交
7071
			if ( light instanceof THREE.HemisphereLight ) hemiLights ++;
7072

7073
		}
7074

7075
		return { 'directional' : dirLights, 'point' : pointLights, 'spot': spotLights, 'hemi': hemiLights };
7076 7077

	};
M
Mr.doob 已提交
7078

7079
	function allocateShadows ( lights ) {
7080

M
Mr.doob 已提交
7081
		var l, ll, light, maxShadows = 0;
7082 7083 7084 7085 7086

		for ( l = 0, ll = lights.length; l < ll; l++ ) {

			light = lights[ l ];

A
alteredq 已提交
7087 7088
			if ( ! light.castShadow ) continue;

7089 7090
			if ( light instanceof THREE.SpotLight ) maxShadows ++;
			if ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) maxShadows ++;
7091 7092 7093 7094 7095 7096 7097

		}

		return maxShadows;

	};

7098
	// Initialization
M
Mr.doob 已提交
7099

7100 7101 7102 7103
	function initGL () {

		try {

7104
			if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { alpha: _alpha, premultipliedAlpha: _premultipliedAlpha, antialias: _antialias, stencil: _stencil, preserveDrawingBuffer: _preserveDrawingBuffer } ) ) ) {
7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115

				throw 'Error creating WebGL context.';

			}

		} catch ( error ) {

			console.error( error );

		}

7116
		_glExtensionTextureFloat = _gl.getExtension( 'OES_texture_float' );
A
alteredq 已提交
7117 7118 7119 7120 7121 7122
		_glExtensionStandardDerivatives = _gl.getExtension( 'OES_standard_derivatives' );

		_glExtensionTextureFilterAnisotropic = _gl.getExtension( 'EXT_texture_filter_anisotropic' ) ||
											   _gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) ||
											   _gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );

7123

7124 7125 7126 7127
		_glExtensionCompressedTextureS3TC = _gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) ||
											_gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) ||
											_gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );

7128
		if ( ! _glExtensionTextureFloat ) {
7129 7130 7131 7132 7133

			console.log( 'THREE.WebGLRenderer: Float textures not supported.' );

		}

A
alteredq 已提交
7134
		if ( ! _glExtensionStandardDerivatives ) {
7135

A
alteredq 已提交
7136
			console.log( 'THREE.WebGLRenderer: Standard derivatives not supported.' );
7137

A
alteredq 已提交
7138
		}
7139

A
alteredq 已提交
7140
		if ( ! _glExtensionTextureFilterAnisotropic ) {
7141

A
alteredq 已提交
7142
			console.log( 'THREE.WebGLRenderer: Anisotropic texture filtering not supported.' );
7143 7144 7145

		}

7146 7147 7148 7149 7150 7151
		if ( ! _glExtensionCompressedTextureS3TC ) {

			console.log( 'THREE.WebGLRenderer: S3TC compressed textures not supported.' );

		}

7152 7153 7154 7155 7156 7157 7158 7159 7160 7161 7162 7163 7164 7165 7166 7167 7168 7169 7170 7171 7172 7173 7174
	};

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

	};

7175 7176
	// default plugins (order is important)

A
alteredq 已提交
7177 7178 7179 7180 7181
	this.shadowMapPlugin = new THREE.ShadowMapPlugin();
	this.addPrePlugin( this.shadowMapPlugin );

	this.addPostPlugin( new THREE.SpritePlugin() );
	this.addPostPlugin( new THREE.LensFlarePlugin() );
7182

7183
};