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

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

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

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

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

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

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

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

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

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

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

	// clearing
M
Mr.doob 已提交
35

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

41 42
	// scene graph

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

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

	// physically based shading

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

54 55 56
	// shadow map

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

63
	// morphs
64

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

68 69 70 71
	// flags

	this.autoScaleCubemaps = true;

72 73
	// custom render plugins

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

77
	// info
78

79
	this.info = {
80

81
		memory: {
82

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

87
		},
88

89
		render: {
90

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

		}

98
	};
M
Mr.doob 已提交
99

100
	// internal properties
101

102
	var _this = this,
103

104
	_programs = [],
A
alteredq 已提交
105
	_programs_counter = 0,
106

107
	// internal state cache
108

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

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

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

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

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

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

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

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

156 157
	_direction = new THREE.Vector3(),

158 159
	_lightsNeedUpdate = true,

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

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

167
	};
M
Mr.doob 已提交
168

169
	// initialize
M
Mikael Emtinger 已提交
170

171 172
	var _gl;
	var _glExtensionTextureFloat;
173
	var _glExtensionTextureFilterAnisotropic;
174 175

	initGL();
M
Mikael Emtinger 已提交
176

177
	setDefaultGLState();
M
Mikael Emtinger 已提交
178

179
	this.context = _gl;
M
Mikael Emtinger 已提交
180

181 182 183
	// GPU capabilities

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

187 188
	var _maxAnisotropy = _glExtensionTextureFilterAnisotropic ? _gl.getParameter( _glExtensionTextureFilterAnisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT ) : 0;

189 190 191
	var _supportsVertexTextures = ( _maxVertexTextures > 0 );
	var _supportsBoneTextures = _supportsVertexTextures && _glExtensionTextureFloat;

192
	// API
M
Mr.doob 已提交
193

194
	this.getContext = function () {
M
Mr.doob 已提交
195

196
		return _gl;
M
Mr.doob 已提交
197

198
	};
M
Mr.doob 已提交
199

200
	this.supportsVertexTextures = function () {
M
Mikael Emtinger 已提交
201

202
		return _supportsVertexTextures;
M
Mikael Emtinger 已提交
203

204
	};
M
Mikael Emtinger 已提交
205

206 207 208 209 210 211
	this.getMaxAnisotropy  = function () {

		return _maxAnisotropy;

	};

N
Nicolas Garcia Belmonte 已提交
212 213 214 215
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
216

217 218 219
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
220

221
	this.setViewport = function ( x, y, width, height ) {
222

223 224
		_viewportX = x;
		_viewportY = y;
225

226 227
		_viewportWidth = width;
		_viewportHeight = height;
228

229
		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
230

N
Nicolas Garcia Belmonte 已提交
231
	};
232

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

235
		_gl.scissor( x, y, width, height );
236

237
	};
238

239
	this.enableScissorTest = function ( enable ) {
240

M
Mr.doob 已提交
241
		enable ? _gl.enable( _gl.SCISSOR_TEST ) : _gl.disable( _gl.SCISSOR_TEST );
242 243

	};
244

245 246
	// Clearing

247
	this.setClearColorHex = function ( hex, alpha ) {
248

249 250 251 252
		_clearColor.setHex( hex );
		_clearAlpha = alpha;

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

254
	};
A
alteredq 已提交
255

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

258 259 260 261
		_clearColor.copy( color );
		_clearAlpha = alpha;

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

	};
264

M
Mr.doob 已提交
265 266 267 268 269 270 271
	this.getClearColor = function () {

		return _clearColor;

	};

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

M
Mr.doob 已提交
273 274 275 276 277 278 279 280
		return _clearAlpha;

	};

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

		var bits = 0;

281 282 283
		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 已提交
284 285

		_gl.clear( bits );
N
Nicolas Garcia Belmonte 已提交
286 287 288

	};

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

A
alteredq 已提交
291
		this.setRenderTarget( renderTarget );
292
		this.clear( color, depth, stencil );
M
Mr.doob 已提交
293 294 295

	};

296 297
	// Plugins

A
alteredq 已提交
298
	this.addPostPlugin = function ( plugin ) {
299 300

		plugin.init( this );
A
alteredq 已提交
301
		this.renderPluginsPost.push( plugin );
302 303 304

	};

A
alteredq 已提交
305 306 307 308 309 310
	this.addPrePlugin = function ( plugin ) {

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

	};
311

312 313
	// Deallocation

314 315 316 317 318 319 320
	this.deallocateObject = function ( object ) {

		if ( ! object.__webglInit ) return;

		object.__webglInit = false;

		delete object._modelViewMatrix;
321
		delete object._normalMatrix;
322 323 324 325 326 327 328

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

		if ( object instanceof THREE.Mesh ) {

329
			for ( var g in object.geometry.geometryGroups ) {
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357

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

360 361
	};

362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
	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 已提交
386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
	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 --;

		}

	};

449
	// Rendering
450

451
	this.updateShadowMap = function ( scene, camera ) {
452

A
alteredq 已提交
453 454 455 456 457 458
		_currentProgram = null;
		_oldBlending = -1;
		_oldDepthTest = -1;
		_oldDepthWrite = -1;
		_currentGeometryGroupHash = -1;
		_currentMaterialId = -1;
459 460 461
		_lightsNeedUpdate = true;
		_oldDoubleSided = -1;
		_oldFlipSided = -1;
A
alteredq 已提交
462 463

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

465
	};
M
Mr.doob 已提交
466

467
	// Internal functions
468

469
	// Buffer allocation
470

471
	function createParticleBuffers ( geometry ) {
472

473 474
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
475

476
		_this.info.geometries ++;
477

478
	};
479

480
	function createLineBuffers ( geometry ) {
481

482 483
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
484

485
		_this.info.memory.geometries ++;
486

487
	};
488

489
	function createRibbonBuffers ( geometry ) {
490

491 492
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
493

494
		_this.info.memory.geometries ++;
M
Mr.doob 已提交
495

496
	};
497

498
	function createMeshBuffers ( geometryGroup ) {
499

500 501 502 503 504 505
		geometryGroup.__webglVertexBuffer = _gl.createBuffer();
		geometryGroup.__webglNormalBuffer = _gl.createBuffer();
		geometryGroup.__webglTangentBuffer = _gl.createBuffer();
		geometryGroup.__webglColorBuffer = _gl.createBuffer();
		geometryGroup.__webglUVBuffer = _gl.createBuffer();
		geometryGroup.__webglUV2Buffer = _gl.createBuffer();
506

507 508 509 510
		geometryGroup.__webglSkinVertexABuffer = _gl.createBuffer();
		geometryGroup.__webglSkinVertexBBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinIndicesBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinWeightsBuffer = _gl.createBuffer();
511

512 513
		geometryGroup.__webglFaceBuffer = _gl.createBuffer();
		geometryGroup.__webglLineBuffer = _gl.createBuffer();
514

515
		var m, ml;
516

517
		if ( geometryGroup.numMorphTargets ) {
518

519
			geometryGroup.__webglMorphTargetsBuffers = [];
520

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

523
				geometryGroup.__webglMorphTargetsBuffers.push( _gl.createBuffer() );
524 525 526 527 528 529 530 531 532 533 534

			}

		}

		if ( geometryGroup.numMorphNormals ) {

			geometryGroup.__webglMorphNormalsBuffers = [];

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

A
alteredq 已提交
535
				geometryGroup.__webglMorphNormalsBuffers.push( _gl.createBuffer() );
536

537
			}
538

539
		}
540

541
		_this.info.memory.geometries ++;
542

543
	};
544

545
	// Buffer deallocation
546

547
	function deleteParticleBuffers ( geometry ) {
548

549 550
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
551

552
		_this.info.memory.geometries --;
553

554
	};
555

556
	function deleteLineBuffers ( geometry ) {
557

558 559
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
560

M
Mr.doob 已提交
561 562
		_this.info.memory.geometries --;

563 564
	};

565
	function deleteRibbonBuffers ( geometry ) {
566 567 568 569

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

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

572 573
	};

574
	function deleteMeshBuffers ( geometryGroup ) {
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590

		_gl.deleteBuffer( geometryGroup.__webglVertexBuffer );
		_gl.deleteBuffer( geometryGroup.__webglNormalBuffer );
		_gl.deleteBuffer( geometryGroup.__webglTangentBuffer );
		_gl.deleteBuffer( geometryGroup.__webglColorBuffer );
		_gl.deleteBuffer( geometryGroup.__webglUVBuffer );
		_gl.deleteBuffer( geometryGroup.__webglUV2Buffer );

		_gl.deleteBuffer( geometryGroup.__webglSkinVertexABuffer );
		_gl.deleteBuffer( geometryGroup.__webglSkinVertexBBuffer );
		_gl.deleteBuffer( geometryGroup.__webglSkinIndicesBuffer );
		_gl.deleteBuffer( geometryGroup.__webglSkinWeightsBuffer );

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

591 592
		var m, ml;

593 594
		if ( geometryGroup.numMorphTargets ) {

595
			for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
596 597

				_gl.deleteBuffer( geometryGroup.__webglMorphTargetsBuffers[ m ] );
598 599 600 601 602 603 604 605 606

			}

		}

		if ( geometryGroup.numMorphNormals ) {

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

A
alteredq 已提交
607
				_gl.deleteBuffer( geometryGroup.__webglMorphNormalsBuffers[ m ] );
608 609 610 611 612

			}

		}

613 614 615 616 617 618 619 620 621 622 623

		if ( geometryGroup.__webglCustomAttributesList ) {

			for ( var id in geometryGroup.__webglCustomAttributesList ) {

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

			}

		}

M
Mr.doob 已提交
624 625
		_this.info.memory.geometries --;

626 627
	};

628
	// Buffer initialization
629

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

632 633
		var nvertices = geometry.vertices.length;

634
		var material = object.material;
635

636
		if ( material.attributes ) {
637

638
			if ( geometry.__webglCustomAttributesList === undefined ) {
639

640
				geometry.__webglCustomAttributesList = [];
641

642
			}
643

644
			for ( var a in material.attributes ) {
645

646
				var attribute = material.attributes[ a ];
647

648
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
649

650
					attribute.__webglInitialized = true;
651

A
alteredq 已提交
652
					var size = 1;		// "f" and "i"
653

654 655 656 657
					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;
658

659
					attribute.size = size;
A
alteredq 已提交
660

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

663 664
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
665

666
					attribute.needsUpdate = true;
667

668
				}
669

670
				geometry.__webglCustomAttributesList.push( attribute );
671

672
			}
673

674
		}
675

676
	};
677

678
	function initParticleBuffers ( geometry, object ) {
A
alteredq 已提交
679 680 681 682 683 684

		var nvertices = geometry.vertices.length;

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

685 686 687
		geometry.__sortArray = [];

		geometry.__webglParticleCount = nvertices;
A
alteredq 已提交
688 689 690 691 692

		initCustomAttributes ( geometry, object );

	};

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

		var nvertices = geometry.vertices.length;

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

700
		geometry.__webglLineCount = nvertices;
A
alteredq 已提交
701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716

		initCustomAttributes ( geometry, object );

	};

	function initRibbonBuffers ( geometry ) {

		var nvertices = geometry.vertices.length;

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

		geometry.__webglVertexCount = nvertices;

	};

M
Mr.doob 已提交
717
	function initMeshBuffers ( geometryGroup, object ) {
M
Mr.doob 已提交
718

719 720 721
		var geometry = object.geometry,
			faces3 = geometryGroup.faces3,
			faces4 = geometryGroup.faces4,
M
Mr.doob 已提交
722

723 724 725
			nvertices = faces3.length * 3 + faces4.length * 4,
			ntris     = faces3.length * 1 + faces4.length * 2,
			nlines    = faces3.length * 3 + faces4.length * 4,
726

727
			material = getBufferMaterial( object, geometryGroup ),
728

729 730 731
			uvType = bufferGuessUVType( material ),
			normalType = bufferGuessNormalType( material ),
			vertexColorType = bufferGuessVertexColorType( material );
A
alteredq 已提交
732

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

735
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
736

737
		if ( normalType ) {
M
Mr.doob 已提交
738

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

741
		}
742

743
		if ( geometry.hasTangents ) {
744

745
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
746

747
		}
748

749
		if ( vertexColorType ) {
750

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

753
		}
M
Mr.doob 已提交
754

755
		if ( uvType ) {
756

757
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
758

759 760 761 762 763
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

765 766 767 768 769 770 771 772 773 774 775 776 777 778 779
				geometryGroup.__uv2Array = new Float32Array( nvertices * 2 );

			}

		}

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

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

		}

780
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
781
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
782

783 784
		var m, ml;

785 786
		if ( geometryGroup.numMorphTargets ) {

M
Mr.doob 已提交
787
			geometryGroup.__morphTargetsArrays = [];
788

789
			for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
790

791
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );
792 793 794 795 796 797 798 799 800 801 802

			}

		}

		if ( geometryGroup.numMorphNormals ) {

			geometryGroup.__morphNormalsArrays = [];

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

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

805 806 807
			}

		}
808

809
		geometryGroup.__webglFaceCount = ntris * 3;
810
		geometryGroup.__webglLineCount = nlines * 2;
811

M
Mr.doob 已提交
812

813
		// custom attributes
M
Mr.doob 已提交
814

815
		if ( material.attributes ) {
816

817
			if ( geometryGroup.__webglCustomAttributesList === undefined ) {
818

819
				geometryGroup.__webglCustomAttributesList = [];
820

821
			}
822

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

825 826
				// Do a shallow copy of the attribute object so different geometryGroup chunks use different
				// attribute buffers which are correctly indexed in the setMeshBuffers function
827

828
				var originalAttribute = material.attributes[ a ];
829

830
				var attribute = {};
831

832
				for ( var property in originalAttribute ) {
M
Mr.doob 已提交
833

834
					attribute[ property ] = originalAttribute[ property ];
835

836
				}
837

838
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
839

840
					attribute.__webglInitialized = true;
841

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

844 845 846 847
					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;
848

849
					attribute.size = size;
A
alteredq 已提交
850

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

853 854
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
855

856 857
					originalAttribute.needsUpdate = true;
					attribute.__original = originalAttribute;
858 859 860

				}

861 862
				geometryGroup.__webglCustomAttributesList.push( attribute );

863
			}
M
Mr.doob 已提交
864

865
		}
866

867 868
		geometryGroup.__inittedArrays = true;

869
	};
M
Mr.doob 已提交
870

871
	function getBufferMaterial( object, geometryGroup ) {
872

873
		if ( object.material && ! ( object.material instanceof THREE.MeshFaceMaterial ) ) {
874

875
			return object.material;
876

877
		} else if ( geometryGroup.materialIndex >= 0 ) {
878

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

881
		}
882

883
	};
M
Mr.doob 已提交
884

885
	function materialNeedsSmoothNormals ( material ) {
886

887
		return material && material.shading !== undefined && material.shading === THREE.SmoothShading;
888

889
	};
M
Mr.doob 已提交
890

891
	function bufferGuessNormalType ( material ) {
892

893
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
894

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

897
			return false;
898

899
		}
900

901
		if ( materialNeedsSmoothNormals( material ) ) {
902

903
			return THREE.SmoothShading;
M
Mr.doob 已提交
904

905
		} else {
906

907
			return THREE.FlatShading;
908

909
		}
910

911
	};
912

913
	function bufferGuessVertexColorType ( material ) {
914

915
		if ( material.vertexColors ) {
916

917
			return material.vertexColors;
918

919
		}
M
Mr.doob 已提交
920

921
		return false;
M
Mr.doob 已提交
922

923
	};
M
Mr.doob 已提交
924

925
	function bufferGuessUVType ( material ) {
926

927 928 929 930 931 932 933 934 935 936 937 938
		// material must use some texture to require uvs

		if ( material.map || material.lightMap || material instanceof THREE.ShaderMaterial ) {

			return true;

		}

		return false;

	};

939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967
	//

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

		}

	};

968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984
	// 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,

985
		dirtyVertices = geometry.verticesNeedUpdate,
M
Mr.doob 已提交
986
		dirtyElements = geometry.elementsNeedUpdate,
M
Mr.doob 已提交
987
		dirtyColors = geometry.colorsNeedUpdate,
988 989 990 991 992 993 994 995

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

		if ( object.sortParticles ) {

A
alteredq 已提交
996 997
			_projScreenMatrixPS.copy( _projScreenMatrix );
			_projScreenMatrixPS.multiplySelf( object.matrixWorld );
998 999 1000

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

1001
				vertex = vertices[ v ];
1002 1003

				_vector3.copy( vertex );
A
alteredq 已提交
1004
				_projScreenMatrixPS.multiplyVector3( _vector3 );
1005 1006 1007 1008 1009 1010 1011 1012 1013

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

			}

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

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

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

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

1138
					vertex = vertices[ v ];
1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172

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

						cal = customAttribute.value.length;

						offset = 0;

						if ( customAttribute.size === 1 ) {

							for ( ca = 0; ca < cal; ca ++ ) {

								customAttribute.array[ ca ] = customAttribute.value[ ca ];

							}

						} else if ( customAttribute.size === 2 ) {

							for ( ca = 0; ca < cal; ca ++ ) {

								value = customAttribute.value[ ca ];

								customAttribute.array[ offset ] 	= value.x;
								customAttribute.array[ offset + 1 ] = value.y;

								offset += 2;

							}

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

							if ( customAttribute.type === "c" ) {

								for ( ca = 0; ca < cal; ca ++ ) {

									value = customAttribute.value[ ca ];

									customAttribute.array[ offset ] 	= value.r;
									customAttribute.array[ offset + 1 ] = value.g;
									customAttribute.array[ offset + 2 ] = value.b;

									offset += 3;

								}

							} else {

								for ( ca = 0; ca < cal; ca ++ ) {

									value = customAttribute.value[ ca ];

									customAttribute.array[ offset ] 	= value.x;
									customAttribute.array[ offset + 1 ] = value.y;
									customAttribute.array[ offset + 2 ] = value.z;

									offset += 3;

								}

							}

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

							for ( ca = 0; ca < cal; ca ++ ) {

								value = customAttribute.value[ ca ];

								customAttribute.array[ offset ]      = value.x;
								customAttribute.array[ offset + 1  ] = value.y;
								customAttribute.array[ offset + 2  ] = value.z;
								customAttribute.array[ offset + 3  ] = value.w;

								offset += 4;

							}

						}

					}

				}

			}

		}

		if ( dirtyVertices || object.sortParticles ) {

			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

		}

		if ( dirtyColors || object.sortParticles ) {

			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

		if ( customAttributes ) {

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

				customAttribute = customAttributes[ i ];

				if ( customAttribute.needsUpdate || object.sortParticles ) {

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

				}

			}

		}


	};

	function setLineBuffers ( geometry, hint ) {

		var v, c, vertex, offset, color,

		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,

		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,

1304
		dirtyVertices = geometry.verticesNeedUpdate,
M
Mr.doob 已提交
1305
		dirtyColors = geometry.colorsNeedUpdate,
1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316

		customAttributes = geometry.__webglCustomAttributesList,

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

		if ( dirtyVertices ) {

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

1317
				vertex = vertices[ v ];
1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 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

				offset = v * 3;

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

			}

			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

		}

		if ( dirtyColors ) {

			for ( c = 0; c < cl; c ++ ) {

				color = colors[ c ];

				offset = c * 3;

				colorArray[ offset ]     = color.r;
				colorArray[ offset + 1 ] = color.g;
				colorArray[ offset + 2 ] = color.b;

			}

			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

		if ( customAttributes ) {

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

				customAttribute = customAttributes[ i ];

				if ( customAttribute.needsUpdate &&
					 ( customAttribute.boundTo === undefined ||
					   customAttribute.boundTo === "vertices" ) ) {

					offset = 0;

					cal = customAttribute.value.length;

					if ( customAttribute.size === 1 ) {

						for ( ca = 0; ca < cal; ca ++ ) {

							customAttribute.array[ ca ] = customAttribute.value[ ca ];

						}

					} else if ( customAttribute.size === 2 ) {

						for ( ca = 0; ca < cal; ca ++ ) {

							value = customAttribute.value[ ca ];

							customAttribute.array[ offset ] 	= value.x;
							customAttribute.array[ offset + 1 ] = value.y;

							offset += 2;

						}

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

						if ( customAttribute.type === "c" ) {

							for ( ca = 0; ca < cal; ca ++ ) {

								value = customAttribute.value[ ca ];

								customAttribute.array[ offset ] 	= value.r;
								customAttribute.array[ offset + 1 ] = value.g;
								customAttribute.array[ offset + 2 ] = value.b;

								offset += 3;

							}

						} else {

							for ( ca = 0; ca < cal; ca ++ ) {

								value = customAttribute.value[ ca ];

								customAttribute.array[ offset ] 	= value.x;
								customAttribute.array[ offset + 1 ] = value.y;
								customAttribute.array[ offset + 2 ] = value.z;

								offset += 3;

							}

						}

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

						for ( ca = 0; ca < cal; ca ++ ) {

							value = customAttribute.value[ ca ];

							customAttribute.array[ offset ] 	 = value.x;
							customAttribute.array[ offset + 1  ] = value.y;
							customAttribute.array[ offset + 2  ] = value.z;
							customAttribute.array[ offset + 3  ] = value.w;

							offset += 4;

						}

					}

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

				}

			}

		}

	};

	function setRibbonBuffers ( geometry, hint ) {

		var v, c, vertex, offset, color,

		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,

		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,

1458
		dirtyVertices = geometry.verticesNeedUpdate,
M
Mr.doob 已提交
1459
		dirtyColors = geometry.colorsNeedUpdate;
1460 1461 1462 1463 1464

		if ( dirtyVertices ) {

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

1465
				vertex = vertices[ v ];
1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500

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

		}

	};

1501
	function setMeshBuffers( geometryGroup, object, hint, dispose, material ) {
1502 1503 1504 1505 1506 1507 1508 1509

		if ( ! geometryGroup.__inittedArrays ) {

			// console.log( object );
			return;

		}

1510 1511 1512 1513 1514 1515
		var normalType = bufferGuessNormalType( material ),
		vertexColorType = bufferGuessVertexColorType( material ),
		uvType = bufferGuessUVType( material ),

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

1516 1517 1518 1519
		var f, fl, fi, face,
		vertexNormals, faceNormal, normal,
		vertexColors, faceColor,
		vertexTangents,
A
alteredq 已提交
1520
		uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4, n1, n2, n3, n4,
1521 1522 1523 1524 1525 1526 1527 1528
		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 已提交
1529
		nka, chf, faceVertexNormals,
1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561
		a,

		vertexIndex = 0,

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

		value,

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

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

		morphTargetsArrays = geometryGroup.__morphTargetsArrays,
A
alteredq 已提交
1562
		morphNormalsArrays = geometryGroup.__morphNormalsArrays,
1563 1564 1565 1566 1567 1568 1569 1570 1571

		customAttributes = geometryGroup.__webglCustomAttributesList,
		customAttribute,

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

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

1572
		dirtyVertices = geometry.verticesNeedUpdate,
M
Mr.doob 已提交
1573
		dirtyElements = geometry.elementsNeedUpdate,
M
Mr.doob 已提交
1574
		dirtyUvs = geometry.uvsNeedUpdate,
M
Mr.doob 已提交
1575
		dirtyNormals = geometry.normalsNeedUpdate,
1576
		dirtyTangents = geometry.tangentsNeedUpdate,
M
Mr.doob 已提交
1577
		dirtyColors = geometry.colorsNeedUpdate,
1578
		dirtyMorphTargets = geometry.morphTargetsNeedUpdate,
1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594

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

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

		obj_colors = geometry.colors,

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

A
alteredq 已提交
1595 1596
		morphTargets = geometry.morphTargets,
		morphNormals = geometry.morphNormals;
1597 1598 1599 1600 1601 1602 1603

		if ( dirtyVertices ) {

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

				face = obj_faces[ chunk_faces3[ f ] ];

1604 1605 1606
				v1 = vertices[ face.a ];
				v2 = vertices[ face.b ];
				v3 = vertices[ face.c ];
1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618

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

1620
				offset += 9;
M
Mr.doob 已提交
1621

1622
			}
1623

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

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

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

A
alteredq 已提交
1633 1634 1635
				vertexArray[ offset ]     = v1.x;
				vertexArray[ offset + 1 ] = v1.y;
				vertexArray[ offset + 2 ] = v1.z;
1636

A
alteredq 已提交
1637 1638 1639
				vertexArray[ offset + 3 ] = v2.x;
				vertexArray[ offset + 4 ] = v2.y;
				vertexArray[ offset + 5 ] = v2.z;
1640

A
alteredq 已提交
1641 1642 1643
				vertexArray[ offset + 6 ] = v3.x;
				vertexArray[ offset + 7 ] = v3.y;
				vertexArray[ offset + 8 ] = v3.z;
1644

A
alteredq 已提交
1645 1646 1647
				vertexArray[ offset + 9 ]  = v4.x;
				vertexArray[ offset + 10 ] = v4.y;
				vertexArray[ offset + 11 ] = v4.z;
1648

A
alteredq 已提交
1649
				offset += 12;
1650

A
alteredq 已提交
1651
			}
1652

A
alteredq 已提交
1653 1654
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1655

A
alteredq 已提交
1656
		}
M
Mr.doob 已提交
1657

A
alteredq 已提交
1658
		if ( dirtyMorphTargets ) {
M
Mr.doob 已提交
1659

1660
			for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {
1661

1662
				offset_morphTarget = 0;
1663

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

A
alteredq 已提交
1666 1667 1668 1669
					chf = chunk_faces3[ f ];
					face = obj_faces[ chf ];

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

1671 1672 1673
					v1 = morphTargets[ vk ].vertices[ face.a ];
					v2 = morphTargets[ vk ].vertices[ face.b ];
					v3 = morphTargets[ vk ].vertices[ face.c ];
M
Mr.doob 已提交
1674

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

A
alteredq 已提交
1677 1678 1679
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
M
Mr.doob 已提交
1680

A
alteredq 已提交
1681 1682 1683
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
M
Mr.doob 已提交
1684

A
alteredq 已提交
1685 1686 1687
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
M
Mr.doob 已提交
1688

A
alteredq 已提交
1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726
					// 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;

					}

					//

1727
					offset_morphTarget += 9;
1728

1729
				}
1730

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

A
alteredq 已提交
1733 1734 1735 1736
					chf = chunk_faces4[ f ];
					face = obj_faces[ chf ];

					// morph positions
1737

1738 1739 1740 1741
					v1 = morphTargets[ vk ].vertices[ face.a ];
					v2 = morphTargets[ vk ].vertices[ face.b ];
					v3 = morphTargets[ vk ].vertices[ face.c ];
					v4 = morphTargets[ vk ].vertices[ face.d ];
1742

1743
					vka = morphTargetsArrays[ vk ];
1744

1745 1746 1747
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
1748

1749 1750 1751
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
1752

1753 1754 1755
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
1756

A
alteredq 已提交
1757 1758 1759 1760
					vka[ offset_morphTarget + 9 ]  = v4.x;
					vka[ offset_morphTarget + 10 ] = v4.y;
					vka[ offset_morphTarget + 11 ] = v4.z;

A
alteredq 已提交
1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804
					// 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;

					}

					//

1805
					offset_morphTarget += 12;
A
alteredq 已提交
1806

1807
				}
A
alteredq 已提交
1808 1809 1810

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

A
alteredq 已提交
1812 1813 1814 1815 1816 1817 1818
				if ( material.morphNormals ) {

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

				}

1819
			}
1820

A
alteredq 已提交
1821 1822 1823 1824 1825 1826 1827
		}

		if ( obj_skinWeights.length ) {

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

				face = obj_faces[ chunk_faces3[ f ]	];
1828

1829
				// weights
A
alteredq 已提交
1830

1831 1832 1833
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
A
alteredq 已提交
1834

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

1840 1841 1842 1843
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1844

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

1850
				// indices
A
alteredq 已提交
1851

1852 1853 1854
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
A
alteredq 已提交
1855

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

1861 1862 1863 1864
				skinIndexArray[ offset_skin + 4 ] = si2.x;
				skinIndexArray[ offset_skin + 5 ] = si2.y;
				skinIndexArray[ offset_skin + 6 ] = si2.z;
				skinIndexArray[ offset_skin + 7 ] = si2.w;
1865

1866 1867 1868 1869
				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 已提交
1870

1871
				// vertices A
A
alteredq 已提交
1872

1873 1874 1875
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
A
alteredq 已提交
1876

1877 1878 1879 1880
				skinVertexAArray[ offset_skin ]     = sa1.x;
				skinVertexAArray[ offset_skin + 1 ] = sa1.y;
				skinVertexAArray[ offset_skin + 2 ] = sa1.z;
				skinVertexAArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
A
alteredq 已提交
1881

1882 1883 1884 1885
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1886

1887 1888 1889 1890
				skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
				skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
				skinVertexAArray[ offset_skin + 10 ] = sa3.z;
				skinVertexAArray[ offset_skin + 11 ] = 1;
A
alteredq 已提交
1891

1892
				// vertices B
A
alteredq 已提交
1893

1894 1895 1896
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
A
alteredq 已提交
1897

1898 1899 1900 1901
				skinVertexBArray[ offset_skin ]     = sb1.x;
				skinVertexBArray[ offset_skin + 1 ] = sb1.y;
				skinVertexBArray[ offset_skin + 2 ] = sb1.z;
				skinVertexBArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
A
alteredq 已提交
1902

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

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

1913
				offset_skin += 12;
1914

1915
			}
1916

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

A
alteredq 已提交
1919
				face = obj_faces[ chunk_faces4[ f ] ];
1920

A
alteredq 已提交
1921
				// weights
1922

A
alteredq 已提交
1923 1924 1925 1926
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
				sw4 = obj_skinWeights[ face.d ];
1927

A
alteredq 已提交
1928 1929 1930 1931
				skinWeightArray[ offset_skin ]     = sw1.x;
				skinWeightArray[ offset_skin + 1 ] = sw1.y;
				skinWeightArray[ offset_skin + 2 ] = sw1.z;
				skinWeightArray[ offset_skin + 3 ] = sw1.w;
1932

A
alteredq 已提交
1933 1934 1935 1936
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1937

A
alteredq 已提交
1938 1939 1940 1941
				skinWeightArray[ offset_skin + 8 ]  = sw3.x;
				skinWeightArray[ offset_skin + 9 ]  = sw3.y;
				skinWeightArray[ offset_skin + 10 ] = sw3.z;
				skinWeightArray[ offset_skin + 11 ] = sw3.w;
1942

A
alteredq 已提交
1943 1944 1945 1946
				skinWeightArray[ offset_skin + 12 ] = sw4.x;
				skinWeightArray[ offset_skin + 13 ] = sw4.y;
				skinWeightArray[ offset_skin + 14 ] = sw4.z;
				skinWeightArray[ offset_skin + 15 ] = sw4.w;
1947

A
alteredq 已提交
1948
				// indices
1949

A
alteredq 已提交
1950 1951 1952 1953
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
				si4 = obj_skinIndices[ face.d ];
1954

A
alteredq 已提交
1955 1956 1957 1958
				skinIndexArray[ offset_skin ]     = si1.x;
				skinIndexArray[ offset_skin + 1 ] = si1.y;
				skinIndexArray[ offset_skin + 2 ] = si1.z;
				skinIndexArray[ offset_skin + 3 ] = si1.w;
1959

A
alteredq 已提交
1960 1961 1962 1963
				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 已提交
1964

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

A
alteredq 已提交
1970 1971 1972 1973
				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 已提交
1974

A
alteredq 已提交
1975
				// vertices A
M
Mr.doob 已提交
1976

A
alteredq 已提交
1977 1978 1979 1980
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
				sa4 = obj_skinVerticesA[ face.d ];
1981

A
alteredq 已提交
1982 1983 1984 1985
				skinVertexAArray[ offset_skin ]     = sa1.x;
				skinVertexAArray[ offset_skin + 1 ] = sa1.y;
				skinVertexAArray[ offset_skin + 2 ] = sa1.z;
				skinVertexAArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
M
Mr.doob 已提交
1986

A
alteredq 已提交
1987 1988 1989 1990
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1991

A
alteredq 已提交
1992 1993 1994 1995
				skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
				skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
				skinVertexAArray[ offset_skin + 10 ] = sa3.z;
				skinVertexAArray[ offset_skin + 11 ] = 1;
1996

A
alteredq 已提交
1997 1998 1999 2000
				skinVertexAArray[ offset_skin + 12 ] = sa4.x;
				skinVertexAArray[ offset_skin + 13 ] = sa4.y;
				skinVertexAArray[ offset_skin + 14 ] = sa4.z;
				skinVertexAArray[ offset_skin + 15 ] = 1;
M
Mr.doob 已提交
2001

A
alteredq 已提交
2002
				// vertices B
M
Mr.doob 已提交
2003

A
alteredq 已提交
2004 2005 2006 2007
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
				sb4 = obj_skinVerticesB[ face.d ];
M
Mr.doob 已提交
2008

A
alteredq 已提交
2009 2010 2011 2012
				skinVertexBArray[ offset_skin ]     = sb1.x;
				skinVertexBArray[ offset_skin + 1 ] = sb1.y;
				skinVertexBArray[ offset_skin + 2 ] = sb1.z;
				skinVertexBArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
M
Mr.doob 已提交
2013

A
alteredq 已提交
2014 2015 2016 2017
				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
				skinVertexBArray[ offset_skin + 7 ] = 1;
2018

A
alteredq 已提交
2019 2020 2021 2022
				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
				skinVertexBArray[ offset_skin + 11 ] = 1;
2023

A
alteredq 已提交
2024 2025 2026 2027
				skinVertexBArray[ offset_skin + 12 ] = sb4.x;
				skinVertexBArray[ offset_skin + 13 ] = sb4.y;
				skinVertexBArray[ offset_skin + 14 ] = sb4.z;
				skinVertexBArray[ offset_skin + 15 ] = 1;
2028

A
alteredq 已提交
2029
				offset_skin += 16;
M
Mr.doob 已提交
2030

A
alteredq 已提交
2031
			}
M
Mr.doob 已提交
2032

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

A
alteredq 已提交
2035 2036
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );
M
Mr.doob 已提交
2037

A
alteredq 已提交
2038 2039 2040 2041 2042 2043 2044 2045
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );

				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );

				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
2046

2047
			}
2048

A
alteredq 已提交
2049
		}
M
Mr.doob 已提交
2050

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

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

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

A
alteredq 已提交
2057 2058
				vertexColors = face.vertexColors;
				faceColor = face.color;
2059

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

A
alteredq 已提交
2062 2063 2064
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
2065

A
alteredq 已提交
2066
				} else {
2067

A
alteredq 已提交
2068 2069 2070
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
2071

A
alteredq 已提交
2072
				}
2073

A
alteredq 已提交
2074 2075 2076
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
2077

A
alteredq 已提交
2078 2079 2080
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
2081

A
alteredq 已提交
2082 2083 2084
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
2085

A
alteredq 已提交
2086
				offset_color += 9;
M
Mr.doob 已提交
2087

A
alteredq 已提交
2088
			}
M
Mr.doob 已提交
2089

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

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

A
alteredq 已提交
2094 2095
				vertexColors = face.vertexColors;
				faceColor = face.color;
M
Mr.doob 已提交
2096

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

A
alteredq 已提交
2099 2100 2101 2102
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
					c4 = vertexColors[ 3 ];
2103

A
alteredq 已提交
2104
				} else {
M
Mr.doob 已提交
2105

A
alteredq 已提交
2106 2107 2108 2109
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
					c4 = faceColor;
M
Mr.doob 已提交
2110

A
alteredq 已提交
2111
				}
2112

A
alteredq 已提交
2113 2114 2115
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
2116

A
alteredq 已提交
2117 2118 2119
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
M
Mr.doob 已提交
2120

A
alteredq 已提交
2121 2122 2123
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
M
Mr.doob 已提交
2124

A
alteredq 已提交
2125 2126 2127
				colorArray[ offset_color + 9 ]  = c4.r;
				colorArray[ offset_color + 10 ] = c4.g;
				colorArray[ offset_color + 11 ] = c4.b;
M
Mr.doob 已提交
2128

A
alteredq 已提交
2129
				offset_color += 12;
2130

2131
			}
2132

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

A
alteredq 已提交
2135 2136
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
M
Mr.doob 已提交
2137

2138
			}
2139

A
alteredq 已提交
2140
		}
M
Mr.doob 已提交
2141

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

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

A
alteredq 已提交
2146
				face = obj_faces[ chunk_faces3[ f ]	];
2147

A
alteredq 已提交
2148
				vertexTangents = face.vertexTangents;
M
Mr.doob 已提交
2149

A
alteredq 已提交
2150 2151 2152
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
2153

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

A
alteredq 已提交
2159 2160 2161 2162
				tangentArray[ offset_tangent + 4 ] = t2.x;
				tangentArray[ offset_tangent + 5 ] = t2.y;
				tangentArray[ offset_tangent + 6 ] = t2.z;
				tangentArray[ offset_tangent + 7 ] = t2.w;
2163

A
alteredq 已提交
2164 2165 2166 2167
				tangentArray[ offset_tangent + 8 ]  = t3.x;
				tangentArray[ offset_tangent + 9 ]  = t3.y;
				tangentArray[ offset_tangent + 10 ] = t3.z;
				tangentArray[ offset_tangent + 11 ] = t3.w;
2168

A
alteredq 已提交
2169
				offset_tangent += 12;
2170

2171
			}
2172

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

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

A
alteredq 已提交
2177
				vertexTangents = face.vertexTangents;
2178

A
alteredq 已提交
2179 2180 2181 2182
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
				t4 = vertexTangents[ 3 ];
2183

A
alteredq 已提交
2184 2185 2186 2187
				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 已提交
2188

A
alteredq 已提交
2189 2190 2191 2192
				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 已提交
2193

A
alteredq 已提交
2194 2195 2196 2197
				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 已提交
2198

A
alteredq 已提交
2199 2200 2201 2202
				tangentArray[ offset_tangent + 12 ] = t4.x;
				tangentArray[ offset_tangent + 13 ] = t4.y;
				tangentArray[ offset_tangent + 14 ] = t4.z;
				tangentArray[ offset_tangent + 15 ] = t4.w;
2203

A
alteredq 已提交
2204
				offset_tangent += 16;
2205

A
alteredq 已提交
2206
			}
2207

A
alteredq 已提交
2208 2209
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
2210

A
alteredq 已提交
2211
		}
2212

A
alteredq 已提交
2213
		if ( dirtyNormals && normalType ) {
2214

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

A
alteredq 已提交
2217
				face = obj_faces[ chunk_faces3[ f ]	];
2218

A
alteredq 已提交
2219 2220
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
2221

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

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

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

A
alteredq 已提交
2228 2229 2230
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
2231

A
alteredq 已提交
2232
						offset_normal += 3;
2233

A
alteredq 已提交
2234
					}
2235

A
alteredq 已提交
2236
				} else {
M
Mr.doob 已提交
2237

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

A
alteredq 已提交
2240 2241 2242
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
2243

A
alteredq 已提交
2244
						offset_normal += 3;
M
Mr.doob 已提交
2245

A
alteredq 已提交
2246
					}
2247

A
alteredq 已提交
2248
				}
2249

A
alteredq 已提交
2250
			}
2251

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

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

A
alteredq 已提交
2256 2257
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
2258

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

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

A
alteredq 已提交
2263
						vn = vertexNormals[ i ];
2264

A
alteredq 已提交
2265 2266 2267
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
2268

A
alteredq 已提交
2269
						offset_normal += 3;
2270

A
alteredq 已提交
2271
					}
M
Mr.doob 已提交
2272

A
alteredq 已提交
2273
				} else {
2274

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

A
alteredq 已提交
2277 2278 2279
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
2280

A
alteredq 已提交
2281
						offset_normal += 3;
M
Mr.doob 已提交
2282

A
alteredq 已提交
2283
					}
2284

A
alteredq 已提交
2285
				}
2286

A
alteredq 已提交
2287
			}
M
Mr.doob 已提交
2288

A
alteredq 已提交
2289 2290
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
2291

A
alteredq 已提交
2292
		}
M
Mr.doob 已提交
2293

A
alteredq 已提交
2294
		if ( dirtyUvs && obj_uvs && uvType ) {
2295

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

A
alteredq 已提交
2298
				fi = chunk_faces3[ f ];
2299

A
alteredq 已提交
2300 2301
				face = obj_faces[ fi ];
				uv = obj_uvs[ fi ];
2302

A
alteredq 已提交
2303
				if ( uv === undefined ) continue;
2304

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

A
alteredq 已提交
2307
					uvi = uv[ i ];
2308

A
alteredq 已提交
2309 2310
					uvArray[ offset_uv ]     = uvi.u;
					uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
2311

A
alteredq 已提交
2312
					offset_uv += 2;
M
Mr.doob 已提交
2313

A
alteredq 已提交
2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334
				}

			}

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

				fi = chunk_faces4[ f ];

				face = obj_faces[ fi ];
				uv = obj_uvs[ fi ];

				if ( uv === undefined ) continue;

				for ( i = 0; i < 4; i ++ ) {

					uvi = uv[ i ];

					uvArray[ offset_uv ]     = uvi.u;
					uvArray[ offset_uv + 1 ] = uvi.v;

					offset_uv += 2;
M
Mr.doob 已提交
2335

2336 2337
				}

2338
			}
2339

A
alteredq 已提交
2340
			if ( offset_uv > 0 ) {
2341

A
alteredq 已提交
2342 2343
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
2344

A
alteredq 已提交
2345
			}
2346

A
alteredq 已提交
2347
		}
2348

A
alteredq 已提交
2349
		if ( dirtyUvs && obj_uvs2 && uvType ) {
2350

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

A
alteredq 已提交
2353
				fi = chunk_faces3[ f ];
2354

A
alteredq 已提交
2355 2356
				face = obj_faces[ fi ];
				uv2 = obj_uvs2[ fi ];
2357

A
alteredq 已提交
2358 2359 2360 2361 2362 2363 2364 2365 2366 2367
				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;
2368

2369 2370
				}

A
alteredq 已提交
2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391
			}

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

				fi = chunk_faces4[ f ];

				face = obj_faces[ fi ];
				uv2 = obj_uvs2[ fi ];

				if ( uv2 === undefined ) continue;

				for ( i = 0; i < 4; i ++ ) {

					uv2i = uv2[ i ];

					uv2Array[ offset_uv2 ]     = uv2i.u;
					uv2Array[ offset_uv2 + 1 ] = uv2i.v;

					offset_uv2 += 2;

				}
2392

2393
			}
2394

A
alteredq 已提交
2395
			if ( offset_uv2 > 0 ) {
2396

A
alteredq 已提交
2397 2398
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );
2399

A
alteredq 已提交
2400
			}
2401

A
alteredq 已提交
2402
		}
2403

A
alteredq 已提交
2404
		if ( dirtyElements ) {
2405

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

A
alteredq 已提交
2408
				face = obj_faces[ chunk_faces3[ f ]	];
2409

A
alteredq 已提交
2410 2411 2412
				faceArray[ offset_face ] 	 = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 2;
2413

A
alteredq 已提交
2414
				offset_face += 3;
2415

A
alteredq 已提交
2416 2417
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2418

A
alteredq 已提交
2419 2420
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 2;
2421

A
alteredq 已提交
2422 2423
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
2424

A
alteredq 已提交
2425
				offset_line += 6;
2426

A
alteredq 已提交
2427
				vertexIndex += 3;
2428

A
alteredq 已提交
2429
			}
2430

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

A
alteredq 已提交
2433
				face = obj_faces[ chunk_faces4[ f ] ];
2434

A
alteredq 已提交
2435 2436 2437
				faceArray[ offset_face ]     = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 3;
2438

A
alteredq 已提交
2439 2440 2441
				faceArray[ offset_face + 3 ] = vertexIndex + 1;
				faceArray[ offset_face + 4 ] = vertexIndex + 2;
				faceArray[ offset_face + 5 ] = vertexIndex + 3;
2442

A
alteredq 已提交
2443
				offset_face += 6;
2444

A
alteredq 已提交
2445 2446
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2447

A
alteredq 已提交
2448 2449
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 3;
2450

A
alteredq 已提交
2451 2452
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
2453

A
alteredq 已提交
2454 2455
				lineArray[ offset_line + 6 ] = vertexIndex + 2;
				lineArray[ offset_line + 7 ] = vertexIndex + 3;
2456

A
alteredq 已提交
2457
				offset_line += 8;
2458

A
alteredq 已提交
2459
				vertexIndex += 4;
2460

2461
			}
2462

A
alteredq 已提交
2463 2464
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
2465

A
alteredq 已提交
2466 2467
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
2468

A
alteredq 已提交
2469
		}
2470

A
alteredq 已提交
2471
		if ( customAttributes ) {
2472

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

2475
				customAttribute = customAttributes[ i ];
2476

2477
				if ( ! customAttribute.__original.needsUpdate ) continue;
2478

2479 2480
				offset_custom = 0;
				offset_customSrc = 0;
2481

2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514
				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 ++ ) {

2515
							value = customAttribute.value[ chunk_faces3[ f ] ];
2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526

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

2527
							value = customAttribute.value[ chunk_faces4[ f ] ];
2528 2529 2530 2531 2532 2533 2534 2535 2536

							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;

						}
2537

2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556
					}

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

2558 2559
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2560

2561
							offset_custom += 6;
A
alteredq 已提交
2562

2563
						}
A
alteredq 已提交
2564

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

2567
							face = obj_faces[ chunk_faces4[ f ] ];
A
alteredq 已提交
2568

2569 2570 2571 2572
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
A
alteredq 已提交
2573

2574 2575
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2576

2577 2578
							customAttribute.array[ offset_custom + 2 ] = v2.x;
							customAttribute.array[ offset_custom + 3 ] = v2.y;
A
alteredq 已提交
2579

2580 2581
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2582

2583 2584
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
A
alteredq 已提交
2585

2586
							offset_custom += 8;
A
alteredq 已提交
2587

2588
						}
A
alteredq 已提交
2589

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

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

2594
							value = customAttribute.value[ chunk_faces3[ f ] ];
A
alteredq 已提交
2595

2596 2597 2598
							v1 = value;
							v2 = value;
							v3 = value;
A
alteredq 已提交
2599

2600 2601
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2602

2603 2604
							customAttribute.array[ offset_custom + 2 ] = v2.x;
							customAttribute.array[ offset_custom + 3 ] = v2.y;
A
alteredq 已提交
2605

2606 2607
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2608

2609
							offset_custom += 6;
A
alteredq 已提交
2610

2611
						}
A
alteredq 已提交
2612

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

2615
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2616

2617 2618 2619 2620
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2621

2622 2623
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2624

2625 2626
							customAttribute.array[ offset_custom + 2 ] = v2.x;
							customAttribute.array[ offset_custom + 3 ] = v2.y;
A
alteredq 已提交
2627

2628 2629
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2630

2631 2632
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
2633

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

2636
						}
M
Mr.doob 已提交
2637

M
Mr.doob 已提交
2638
					}
M
Mr.doob 已提交
2639

2640
				} else if ( customAttribute.size === 3 ) {
2641

2642
					var pp;
2643

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

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

2648
					} else {
M
Mr.doob 已提交
2649

2650
						pp = [ "x", "y", "z" ];
2651

2652
					}
2653

2654
					if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
2655

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

2658
							face = obj_faces[ chunk_faces3[ f ]	];
2659

2660 2661 2662
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
2663

2664 2665 2666
							customAttribute.array[ offset_custom ] 	   = v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
2667

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

2672 2673 2674
							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 已提交
2675

2676
							offset_custom += 9;
M
Mr.doob 已提交
2677

2678
						}
M
Mr.doob 已提交
2679

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

2682
							face = obj_faces[ chunk_faces4[ f ] ];
M
Mr.doob 已提交
2683

2684 2685 2686 2687
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
M
Mr.doob 已提交
2688

2689 2690 2691
							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 已提交
2692

2693 2694 2695
							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 已提交
2696

2697 2698 2699
							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 已提交
2700

2701 2702 2703
							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 已提交
2704

2705
							offset_custom += 12;
M
Mr.doob 已提交
2706

2707
						}
M
Mr.doob 已提交
2708

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

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

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

2715 2716 2717
							v1 = value;
							v2 = value;
							v3 = value;
M
Mr.doob 已提交
2718

2719 2720 2721
							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 已提交
2722

2723 2724 2725
							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 已提交
2726

2727 2728 2729
							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 已提交
2730

2731
							offset_custom += 9;
M
Mr.doob 已提交
2732

2733
						}
2734

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

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

2739 2740 2741 2742
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
2743

2744 2745 2746
							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
2747

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

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

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

2760
							offset_custom += 12;
2761

2762
						}
2763

A
alteredq 已提交
2764
					}
M
Mr.doob 已提交
2765

2766
				} else if ( customAttribute.size === 4 ) {
2767

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

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

2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 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
							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 ++ ) {

2834
							value = customAttribute.value[ chunk_faces3[ f ] ];
2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851

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

2855
							offset_custom += 12;
A
alteredq 已提交
2856

2857 2858
						}

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

2861
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2862

2863 2864 2865 2866
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2867

2868 2869 2870 2871
							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;
2872

2873 2874 2875 2876
							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;
2877

2878 2879 2880 2881
							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;
2882

2883 2884 2885 2886
							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;
2887

2888
							offset_custom += 16;
A
alteredq 已提交
2889

2890
						}
A
alteredq 已提交
2891 2892 2893 2894 2895

					}

				}

2896 2897 2898
				_gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );

A
alteredq 已提交
2899 2900 2901 2902
			}

		}

2903
		if ( dispose ) {
2904

2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917
			delete geometryGroup.__inittedArrays;
			delete geometryGroup.__colorArray;
			delete geometryGroup.__normalArray;
			delete geometryGroup.__tangentArray;
			delete geometryGroup.__uvArray;
			delete geometryGroup.__uv2Array;
			delete geometryGroup.__faceArray;
			delete geometryGroup.__vertexArray;
			delete geometryGroup.__lineArray;
			delete geometryGroup.__skinVertexAArray;
			delete geometryGroup.__skinVertexBArray;
			delete geometryGroup.__skinIndexArray;
			delete geometryGroup.__skinWeightArray;
A
alteredq 已提交
2918

2919
		}
A
alteredq 已提交
2920

2921
	};
A
alteredq 已提交
2922

2923 2924
	function setDirectBuffers ( geometry, hint, dispose ) {

2925
		var attributes = geometry.attributes;
2926

2927 2928 2929 2930 2931
		var index = attributes[ "index" ];
		var position = attributes[ "position" ];
		var normal = attributes[ "normal" ];
		var uv = attributes[ "uv" ];
		var color = attributes[ "color" ];
2932
		var tangent = attributes[ "tangent" ];
2933 2934 2935 2936 2937

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

			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, index.array, hint );
2938 2939 2940

		}

2941
		if ( geometry.verticesNeedUpdate && position !== undefined ) {
2942

2943 2944
			_gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, position.array, hint );
2945 2946 2947

		}

2948
		if ( geometry.normalsNeedUpdate && normal !== undefined ) {
2949

2950 2951
			_gl.bindBuffer( _gl.ARRAY_BUFFER, normal.buffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, normal.array, hint );
2952 2953 2954

		}

2955
		if ( geometry.uvsNeedUpdate && uv !== undefined ) {
2956

2957 2958
			_gl.bindBuffer( _gl.ARRAY_BUFFER, uv.buffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, uv.array, hint );
2959 2960 2961

		}

2962
		if ( geometry.colorsNeedUpdate && color !== undefined ) {
2963

2964 2965
			_gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, color.array, hint );
2966 2967 2968

		}

2969 2970 2971 2972 2973 2974
		if ( geometry.tangentsNeedUpdate && tangent !== undefined ) {

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

		}
2975 2976 2977

		if ( dispose ) {

2978 2979 2980 2981 2982
			for ( var i in geometry.attributes ) {

				delete geometry.attributes[ i ].array;

			}
2983 2984 2985 2986 2987

		}

	};

2988
	// Buffer rendering
A
alteredq 已提交
2989

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

2992 2993 2994
		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();
2995
		if ( object.hasColors && ! object.__webglColorBuffer ) object.__webglColorBuffer = _gl.createBuffer();
A
alteredq 已提交
2996

2997
		if ( object.hasPositions ) {
A
alteredq 已提交
2998

2999 3000 3001 3002
			_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 已提交
3003 3004 3005

		}

3006
		if ( object.hasNormals ) {
A
alteredq 已提交
3007

3008
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
A
alteredq 已提交
3009

3010
			if ( material.shading === THREE.FlatShading ) {
3011

3012 3013 3014 3015
				var nx, ny, nz,
					nax, nbx, ncx, nay, nby, ncy, naz, nbz, ncz,
					normalArray,
					i, il = object.count * 3;
3016

3017
				for( i = 0; i < il; i += 9 ) {
3018

3019
					normalArray = object.normalArray;
3020

3021 3022 3023
					nax  = normalArray[ i ];
					nay  = normalArray[ i + 1 ];
					naz  = normalArray[ i + 2 ];
3024

3025 3026 3027
					nbx  = normalArray[ i + 3 ];
					nby  = normalArray[ i + 4 ];
					nbz  = normalArray[ i + 5 ];
3028

3029 3030 3031
					ncx  = normalArray[ i + 6 ];
					ncy  = normalArray[ i + 7 ];
					ncz  = normalArray[ i + 8 ];
3032

3033 3034 3035
					nx = ( nax + nbx + ncx ) / 3;
					ny = ( nay + nby + ncy ) / 3;
					nz = ( naz + nbz + ncz ) / 3;
3036

3037 3038 3039
					normalArray[ i ] 	 = nx;
					normalArray[ i + 1 ] = ny;
					normalArray[ i + 2 ] = nz;
3040

3041 3042 3043
					normalArray[ i + 3 ] = nx;
					normalArray[ i + 4 ] = ny;
					normalArray[ i + 5 ] = nz;
3044

3045 3046 3047
					normalArray[ i + 6 ] = nx;
					normalArray[ i + 7 ] = ny;
					normalArray[ i + 8 ] = nz;
3048

3049
				}
3050

3051
			}
3052

3053 3054 3055
			_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 );
3056

3057
		}
3058

3059
		if ( object.hasUvs && material.map ) {
3060 3061 3062 3063 3064 3065 3066 3067

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

		}

3068 3069 3070 3071 3072 3073 3074 3075 3076
		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 );

		}

3077
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );
3078

3079
		object.count = 0;
3080

3081
	};
3082

3083
	this.renderBufferDirect = function ( camera, lights, fog, material, geometry, object ) {
3084

3085 3086
		if ( material.visible === false ) return;

3087
		var program, attributes, linewidth, primitives, a, attribute;
3088 3089 3090 3091 3092 3093 3094

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

		attributes = program.attributes;

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

3097
		if ( geometryHash !== _currentGeometryGroupHash ) {
3098

3099
			_currentGeometryGroupHash = geometryHash;
3100 3101 3102 3103 3104 3105 3106 3107
			updateBuffers = true;

		}

		// render mesh

		if ( object instanceof THREE.Mesh ) {

3108
			var offsets = geometry.offsets;
3109

3110
			// if there is more than 1 chunk
3111
			// must set attribute pointers to use new offsets for each chunk
3112 3113 3114 3115
			// even if geometry and materials didn't change

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

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

3118 3119
				var startIndex = offsets[ i ].index;

3120 3121 3122 3123
				if ( updateBuffers ) {

					// vertices

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

3127 3128
					_gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
					_gl.vertexAttribPointer( attributes.position, positionSize, _gl.FLOAT, false, 0, startIndex * positionSize * 4 ); // 4 bytes per Float32
3129 3130 3131

					// normals

3132
					var normal = geometry.attributes[ "normal" ];
3133

3134
					if ( attributes.normal >= 0 && normal ) {
3135

3136 3137 3138 3139
						var normalSize = normal.itemSize;

						_gl.bindBuffer( _gl.ARRAY_BUFFER, normal.buffer );
						_gl.vertexAttribPointer( attributes.normal, normalSize, _gl.FLOAT, false, 0, startIndex * normalSize * 4 );
3140 3141 3142 3143 3144

					}

					// uvs

3145 3146 3147
					var uv = geometry.attributes[ "uv" ];

					if ( attributes.uv >= 0 && uv ) {
3148

3149
						if ( uv.buffer ) {
3150

3151
							var uvSize = uv.itemSize;
3152

3153 3154
							_gl.bindBuffer( _gl.ARRAY_BUFFER, uv.buffer );
							_gl.vertexAttribPointer( attributes.uv, uvSize, _gl.FLOAT, false, 0, startIndex * uvSize * 4 );
3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167

							_gl.enableVertexAttribArray( attributes.uv );

						} else {

							_gl.disableVertexAttribArray( attributes.uv );

						}

					}

					// colors

3168 3169 3170
					var color = geometry.attributes[ "color" ];

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

3172
						var colorSize = color.itemSize;
3173

3174 3175
						_gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
						_gl.vertexAttribPointer( attributes.color, colorSize, _gl.FLOAT, false, 0, startIndex * colorSize * 4 );
3176

3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188
					}

					// tangents

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

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

						var tangentSize = tangent.itemSize;

						_gl.bindBuffer( _gl.ARRAY_BUFFER, tangent.buffer );
						_gl.vertexAttribPointer( attributes.tangent, tangentSize, _gl.FLOAT, false, 0, startIndex * tangentSize * 4 );
3189 3190 3191

					}

3192 3193 3194 3195 3196
					// indices

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

					_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
3197 3198 3199 3200 3201

				}

				// render indexed triangles

3202
				_gl.drawElements( _gl.TRIANGLES, offsets[ i ].count, _gl.UNSIGNED_SHORT, offsets[ i ].start * 2 ); // 2 bytes per Uint16
3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213

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

			}

		}

	};

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

3216 3217
		if ( material.visible === false ) return;

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

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

3222
		attributes = program.attributes;
3223

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

3228
		if ( geometryGroupHash !== _currentGeometryGroupHash ) {
A
alteredq 已提交
3229

3230 3231
			_currentGeometryGroupHash = geometryGroupHash;
			updateBuffers = true;
3232

3233
		}
3234

3235
		// vertices
3236

3237
		if ( !material.morphTargets && attributes.position >= 0 ) {
3238

3239
			if ( updateBuffers ) {
3240

3241 3242
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
				_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3243

3244
			}
3245

3246
		} else {
3247

3248
			if ( object.morphTargetBase ) {
3249

3250
				setupMorphTargets( material, geometryGroup, object );
3251

3252
			}
3253

3254
		}
3255

3256

3257
		if ( updateBuffers ) {
3258

3259
			// custom attributes
3260

3261
			// Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
3262

3263
			if ( geometryGroup.__webglCustomAttributesList ) {
3264

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

3267
					attribute = geometryGroup.__webglCustomAttributesList[ i ];
3268

3269
					if( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
3270

3271 3272
						_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
						_gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 );
3273

3274
					}
3275

3276
				}
3277

3278
			}
3279 3280


3281
			// colors
3282

3283
			if ( attributes.color >= 0 ) {
3284

3285 3286
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
3287

3288
			}
3289

3290
			// normals
3291

3292
			if ( attributes.normal >= 0 ) {
3293

3294 3295
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
				_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
3296

3297
			}
3298

3299
			// tangents
3300

3301
			if ( attributes.tangent >= 0 ) {
3302

3303 3304
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
				_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
3305

3306
			}
3307

3308
			// uvs
3309

3310
			if ( attributes.uv >= 0 ) {
3311

3312
				if ( geometryGroup.__webglUVBuffer ) {
3313

3314 3315
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
					_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
3316

3317
					_gl.enableVertexAttribArray( attributes.uv );
3318

3319
				} else {
3320

3321
					_gl.disableVertexAttribArray( attributes.uv );
3322 3323 3324 3325 3326

				}

			}

3327
			if ( attributes.uv2 >= 0 ) {
3328

3329
				if ( geometryGroup.__webglUV2Buffer ) {
3330

3331 3332
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
					_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
3333

3334
					_gl.enableVertexAttribArray( attributes.uv2 );
3335

3336
				} else {
3337

3338
					_gl.disableVertexAttribArray( attributes.uv2 );
3339 3340

				}
3341 3342

			}
3343

3344 3345 3346
			if ( material.skinning &&
				 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
				 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
A
alteredq 已提交
3347

3348 3349
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3350

3351 3352
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
				_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3353

3354 3355
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
				_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3356

3357 3358
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
				_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
3359

A
alteredq 已提交
3360
			}
3361

3362
		}
3363

3364
		// render mesh
3365

3366
		if ( object instanceof THREE.Mesh ) {
3367

3368
			// wireframe
3369

3370
			if ( material.wireframe ) {
3371

3372
				setLineWidth( material.wireframeLinewidth );
3373

3374 3375
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
3376

3377
			// triangles
3378

3379
			} else {
3380

3381 3382
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3383

3384
			}
3385

3386 3387 3388
			_this.info.render.calls ++;
			_this.info.render.vertices += geometryGroup.__webglFaceCount;
			_this.info.render.faces += geometryGroup.__webglFaceCount / 3;
3389

3390
		// render lines
3391

3392
		} else if ( object instanceof THREE.Line ) {
3393

3394
			primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
3395

3396
			setLineWidth( material.linewidth );
3397

3398
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
3399

3400
			_this.info.render.calls ++;
3401

3402
		// render particles
3403

3404
		} else if ( object instanceof THREE.ParticleSystem ) {
3405

3406
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
3407

3408
			_this.info.render.calls ++;
3409
			_this.info.render.points += geometryGroup.__webglParticleCount;
3410

3411
		// render ribbon
3412

3413
		} else if ( object instanceof THREE.Ribbon ) {
3414

3415
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
3416

3417
			_this.info.render.calls ++;
3418

3419
		}
3420

3421
	};
3422

3423
	function setupMorphTargets ( material, geometryGroup, object ) {
3424

3425
		// set base
3426

3427
		var attributes = material.program.attributes;
3428

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

3431 3432
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3433

3434
		} else if ( attributes.position >= 0 ) {
3435

3436 3437
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3438

3439
		}
3440

3441
		if ( object.morphTargetForcedOrder.length ) {
3442

3443
			// set forced order
3444

3445 3446 3447 3448 3449
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;

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

3451 3452 3453
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ order[ m ] ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );

A
alteredq 已提交
3454 3455 3456 3457 3458 3459 3460
				if ( material.morphNormals ) {

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

				}

3461 3462 3463
				object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ] ];

				m ++;
3464 3465
			}

3466 3467
		} else {

A
alteredq 已提交
3468
			// find the most influencing
3469

A
alteredq 已提交
3470
			var influence, activeInfluenceIndices = [];
3471 3472
			var influences = object.morphTargetInfluences;
			var i, il = influences.length;
3473

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

A
alteredq 已提交
3476 3477 3478 3479
				influence = influences[ i ];

				if ( influence > 0 ) {

3480
					activeInfluenceIndices.push( [ i, influence ] );
3481

I
ide user ide_gero3 已提交
3482
				}
A
alteredq 已提交
3483

I
ide user ide_gero3 已提交
3484
			}
A
alteredq 已提交
3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496

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

3497
				activeInfluenceIndices.push( [ 0, 0 ] );
A
alteredq 已提交
3498 3499 3500 3501

			};

			var influenceIndex, m = 0;
3502

3503
			while ( m < material.numSupportedMorphTargets ) {
3504

3505
				if ( activeInfluenceIndices[ m ] ) {
3506 3507 3508

					influenceIndex = activeInfluenceIndices[ m ][ 0 ];

A
alteredq 已提交
3509 3510 3511
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ influenceIndex ] );

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

A
alteredq 已提交
3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524
					if ( material.morphNormals ) {

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

					}

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

				} else {

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

A
alteredq 已提交
3526
					if ( material.morphNormals ) {
3527

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

3530
					}
3531

A
alteredq 已提交
3532 3533
					object.__webglMorphTargetInfluences[ m ] = 0;

3534
				}
A
alteredq 已提交
3535

3536
				m ++;
3537 3538 3539 3540 3541

			}

		}

3542
		// load updated influences uniform
3543

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

3546
			_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
3547

3548
		}
3549

3550
	};
3551

A
alteredq 已提交
3552
	// Sorting
3553

3554
	function painterSort ( a, b ) {
3555

3556
		return b.z - a.z;
3557

3558
	};
3559

3560
	function numericalSort ( a, b ) {
A
alteredq 已提交
3561

3562
		return b[ 1 ] - a[ 1 ];
A
alteredq 已提交
3563 3564 3565 3566

	};


3567
	// Rendering
3568

3569
	this.render = function ( scene, camera, renderTarget, forceClear ) {
3570

3571 3572 3573 3574 3575
		var i, il,

		webglObject, object,
		renderList,

3576
		lights = scene.__lights,
3577
		fog = scene.fog;
M
Mr.doob 已提交
3578

3579 3580
		// reset caching for this frame

3581
		_currentMaterialId = -1;
3582
		_lightsNeedUpdate = true;
3583

A
alteredq 已提交
3584
		// update scene graph
3585

3586
		if ( camera.parent === undefined ) {
3587

3588 3589
			console.warn( 'DEPRECATED: Camera hasn\'t been added to a Scene. Adding it...' );
			scene.add( camera );
3590

3591
		}
3592

3593
		if ( this.autoUpdateScene ) scene.updateMatrixWorld();
3594

A
alteredq 已提交
3595
		// update camera matrices and frustum
A
alteredq 已提交
3596

A
alteredq 已提交
3597 3598
		if ( ! camera._viewMatrixArray ) camera._viewMatrixArray = new Float32Array( 16 );
		if ( ! camera._projectionMatrixArray ) camera._projectionMatrixArray = new Float32Array( 16 );
A
alteredq 已提交
3599

3600
		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
A
alteredq 已提交
3601 3602 3603

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

3605
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
A
alteredq 已提交
3606
		_frustum.setFromMatrix( _projScreenMatrix );
3607

A
alteredq 已提交
3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622
		// 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 已提交
3623
		this.setRenderTarget( renderTarget );
3624

3625
		if ( this.autoClear || forceClear ) {
3626

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

3629
		}
M
Mr.doob 已提交
3630

3631
		// set matrices for regular objects (frustum culled)
3632

3633
		renderList = scene.__webglObjects;
3634

3635
		for ( i = 0, il = renderList.length; i < il; i ++ ) {
3636

3637
			webglObject = renderList[ i ];
3638
			object = webglObject.object;
3639

A
alteredq 已提交
3640 3641
			webglObject.render = false;

3642
			if ( object.visible ) {
3643

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

3646
					//object.matrixWorld.flattenToArray( object._objectMatrixArray );
3647

A
alteredq 已提交
3648
					setupMatrices( object, camera );
3649

3650
					unrollBufferMaterial( webglObject );
3651

3652
					webglObject.render = true;
3653

3654
					if ( this.sortObjects ) {
3655

3656
						if ( object.renderDepth ) {
3657

3658
							webglObject.z = object.renderDepth;
M
Mr.doob 已提交
3659

3660
						} else {
M
Mr.doob 已提交
3661

3662
							_vector3.copy( object.matrixWorld.getPosition() );
3663
							_projScreenMatrix.multiplyVector3( _vector3 );
3664

3665
							webglObject.z = _vector3.z;
3666

3667
						}
M
Mr.doob 已提交
3668

3669
					}
M
Mr.doob 已提交
3670

3671
				}
3672 3673

			}
3674 3675 3676

		}

3677
		if ( this.sortObjects ) {
M
Mr.doob 已提交
3678

3679
			renderList.sort( painterSort );
3680

3681
		}
3682

3683
		// set matrices for immediate objects
3684

3685
		renderList = scene.__webglObjectsImmediate;
3686

3687 3688 3689
		for ( i = 0, il = renderList.length; i < il; i ++ ) {

			webglObject = renderList[ i ];
3690
			object = webglObject.object;
3691

3692
			if ( object.visible ) {
3693

M
Mr.doob 已提交
3694 3695
				/*
				if ( object.matrixAutoUpdate ) {
3696

3697
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3698

3699
				}
M
Mr.doob 已提交
3700
				*/
M
Mr.doob 已提交
3701

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

3704
				unrollImmediateBufferMaterial( webglObject );
M
Mr.doob 已提交
3705

3706
			}
M
Mr.doob 已提交
3707

3708
		}
3709

3710
		if ( scene.overrideMaterial ) {
3711

3712 3713 3714 3715 3716 3717
			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 );
3718

3719 3720
			renderObjects( scene.__webglObjects, false, "", camera, lights, fog, true, material );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "", camera, lights, fog, false, material );
M
Mr.doob 已提交
3721

3722
		} else {
3723

3724
			// opaque pass (front-to-back order)
3725

3726
			this.setBlending( THREE.NormalBlending );
3727

3728 3729
			renderObjects( scene.__webglObjects, true, "opaque", camera, lights, fog, false );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "opaque", camera, lights, fog, false );
3730

3731
			// transparent pass (back-to-front order)
3732

3733 3734
			renderObjects( scene.__webglObjects, false, "transparent", camera, lights, fog, true );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "transparent", camera, lights, fog, true );
3735

3736
		}
3737

A
alteredq 已提交
3738
		// custom render plugins (post pass)
3739

A
alteredq 已提交
3740
		renderPlugins( this.renderPluginsPost, scene, camera );
3741 3742


3743
		// Generate mipmap if we're using any kind of mipmap filtering
3744

3745
		if ( renderTarget && renderTarget.generateMipmaps && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {
3746

3747
			updateRenderTargetMipmap( renderTarget );
3748

3749
		}
3750

3751 3752 3753
		// Ensure depth buffer writing is enabled so it can be cleared on next render

		this.setDepthTest( true );
3754
		this.setDepthWrite( true );
3755

3756
		// _gl.finish();
3757

3758
	};
3759

A
alteredq 已提交
3760 3761 3762 3763 3764 3765
	function renderPlugins( plugins, scene, camera ) {

		if ( ! plugins.length ) return;

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

3766 3767
			// reset state for plugin (to start from clean slate)

A
alteredq 已提交
3768
			_currentProgram = null;
3769
			_currentCamera = null;
3770

A
alteredq 已提交
3771 3772 3773
			_oldBlending = -1;
			_oldDepthTest = -1;
			_oldDepthWrite = -1;
3774 3775
			_oldDoubleSided = -1;
			_oldFlipSided = -1;
A
alteredq 已提交
3776 3777
			_currentGeometryGroupHash = -1;
			_currentMaterialId = -1;
3778

3779
			_lightsNeedUpdate = true;
A
alteredq 已提交
3780

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

3783 3784
			// reset state after plugin (anything could have changed)

A
alteredq 已提交
3785
			_currentProgram = null;
3786
			_currentCamera = null;
3787

A
alteredq 已提交
3788 3789 3790
			_oldBlending = -1;
			_oldDepthTest = -1;
			_oldDepthWrite = -1;
3791 3792
			_oldDoubleSided = -1;
			_oldFlipSided = -1;
A
alteredq 已提交
3793 3794
			_currentGeometryGroupHash = -1;
			_currentMaterialId = -1;
3795

3796
			_lightsNeedUpdate = true;
A
alteredq 已提交
3797 3798 3799 3800 3801

		}

	};

3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837
	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;

3838
					if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
3839

A
alteredq 已提交
3840
					_this.setDepthTest( material.depthTest );
3841
					_this.setDepthWrite( material.depthWrite );
3842 3843 3844 3845
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

A
alteredq 已提交
3846
				_this.setObjectFaces( object );
3847 3848 3849 3850 3851 3852 3853 3854 3855 3856

				if ( buffer instanceof THREE.BufferGeometry ) {

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

				} else {

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

				}
3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884

			}

		}

	};

	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;

3885
					if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
3886

A
alteredq 已提交
3887
					_this.setDepthTest( material.depthTest );
3888
					_this.setDepthWrite( material.depthWrite );
3889 3890 3891 3892
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

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

A
alteredq 已提交
3895
			}
3896

A
alteredq 已提交
3897
		}
3898

A
alteredq 已提交
3899
	};
3900

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

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

A
alteredq 已提交
3905
		_currentGeometryGroupHash = -1;
3906

A
alteredq 已提交
3907 3908 3909 3910 3911 3912 3913 3914
		_this.setObjectFaces( object );

		if ( object.immediateRenderCallback ) {

			object.immediateRenderCallback( program, _gl, _frustum );

		} else {

3915
			object.render( function( object ) { _this.renderBufferImmediate( object, program, material ); } );
3916 3917 3918 3919 3920

		}

	};

3921
	function unrollImmediateBufferMaterial ( globject ) {
3922

3923 3924
		var object = globject.object,
			material = object.material;
3925

3926
		if ( material.transparent ) {
3927

3928 3929
			globject.transparent = material;
			globject.opaque = null;
3930

3931
		} else {
3932

3933 3934
			globject.opaque = material;
			globject.transparent = null;
3935

3936
		}
A
alteredq 已提交
3937

3938
	};
A
alteredq 已提交
3939

3940
	function unrollBufferMaterial ( globject ) {
A
alteredq 已提交
3941

3942 3943 3944
		var object = globject.object,
			buffer = globject.buffer,
			material, materialIndex, meshMaterial;
3945

3946
		meshMaterial = object.material;
3947

3948
		if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
M
Mr.doob 已提交
3949

3950
			materialIndex = buffer.materialIndex;
3951

3952
			if ( materialIndex >= 0 ) {
3953

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

3956
				if ( material.transparent ) {
M
Mr.doob 已提交
3957

3958 3959
					globject.transparent = material;
					globject.opaque = null;
3960

3961
				} else {
3962

3963 3964
					globject.opaque = material;
					globject.transparent = null;
3965

3966
				}
3967

3968
			}
3969

3970
		} else {
3971

3972
			material = meshMaterial;
3973

3974
			if ( material ) {
3975

3976
				if ( material.transparent ) {
M
Mr.doob 已提交
3977

3978 3979
					globject.transparent = material;
					globject.opaque = null;
A
alteredq 已提交
3980

3981
				} else {
3982

3983 3984
					globject.opaque = material;
					globject.transparent = null;
3985

3986
				}
3987

3988
			}
3989

3990
		}
3991

3992
	};
3993

3994
	// Geometry splitting
3995

3996
	function sortFacesByMaterial ( geometry ) {
3997

3998 3999 4000
		var f, fl, face, materialIndex, vertices,
			materialHash, groupHash,
			hash_map = {};
4001

4002
		var numMorphTargets = geometry.morphTargets.length;
4003
		var numMorphNormals = geometry.morphNormals.length;
4004

4005
		geometry.geometryGroups = {};
4006

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

4009 4010
			face = geometry.faces[ f ];
			materialIndex = face.materialIndex;
4011

4012
			materialHash = ( materialIndex !== undefined ) ? materialIndex : -1;
4013

4014
			if ( hash_map[ materialHash ] === undefined ) {
4015

4016
				hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 };
4017 4018 4019

			}

4020
			groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
4021

4022
			if ( geometry.geometryGroups[ groupHash ] === undefined ) {
4023

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

4026
			}
A
alteredq 已提交
4027

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

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

4032 4033
				hash_map[ materialHash ].counter += 1;
				groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
A
alteredq 已提交
4034

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

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

4039
				}
4040

4041
			}
4042

4043
			if ( face instanceof THREE.Face3 ) {
4044

4045
				geometry.geometryGroups[ groupHash ].faces3.push( f );
4046

4047
			} else {
4048

4049
				geometry.geometryGroups[ groupHash ].faces4.push( f );
4050

A
alteredq 已提交
4051
			}
4052

4053
			geometry.geometryGroups[ groupHash ].vertices += vertices;
4054

4055
		}
4056

4057
		geometry.geometryGroupsList = [];
4058

4059
		for ( var g in geometry.geometryGroups ) {
4060

4061
			geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;
4062

4063
			geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );
4064

4065
		}
4066

4067
	};
4068

4069 4070 4071 4072 4073 4074 4075 4076 4077
	// Objects refresh

	this.initWebGLObjects = function ( scene ) {

		if ( !scene.__webglObjects ) {

			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
			scene.__webglSprites = [];
4078
			scene.__webglFlares = [];
4079 4080

		}
4081

4082
		while ( scene.__objectsAdded.length ) {
4083

4084 4085
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
4086

4087
		}
A
alteredq 已提交
4088

4089
		while ( scene.__objectsRemoved.length ) {
4090

4091 4092
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
4093

4094
		}
4095

4096
		// update must be called after objects adding / removal
4097

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

4100
			updateObject( scene.__webglObjects[ o ].object );
M
Mr.doob 已提交
4101 4102 4103 4104 4105

		}

	};

4106
	// Objects adding
M
Mr.doob 已提交
4107

4108
	function addObject ( object, scene ) {
A
alteredq 已提交
4109

4110
		var g, geometry, geometryGroup;
4111

4112
		if ( ! object.__webglInit ) {
M
Mr.doob 已提交
4113

4114
			object.__webglInit = true;
M
Mr.doob 已提交
4115

4116
			object._modelViewMatrix = new THREE.Matrix4();
4117
			object._normalMatrix = new THREE.Matrix3();
M
Mr.doob 已提交
4118

4119
			if ( object instanceof THREE.Mesh ) {
M
Mr.doob 已提交
4120

4121
				geometry = object.geometry;
M
Mr.doob 已提交
4122

4123
				if ( geometry instanceof THREE.Geometry ) {
M
Mr.doob 已提交
4124

4125
					if ( geometry.geometryGroups === undefined ) {
M
Mr.doob 已提交
4126

4127
						sortFacesByMaterial( geometry );
M
Mr.doob 已提交
4128

4129 4130 4131
					}

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

4133
					for ( g in geometry.geometryGroups ) {
M
Mr.doob 已提交
4134

4135
						geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
4136

4137
						// initialise VBO on the first access
M
Mr.doob 已提交
4138

4139
						if ( ! geometryGroup.__webglVertexBuffer ) {
4140

4141 4142
							createMeshBuffers( geometryGroup );
							initMeshBuffers( geometryGroup, object );
M
Mr.doob 已提交
4143

4144
							geometry.verticesNeedUpdate = true;
4145
							geometry.morphTargetsNeedUpdate = true;
M
Mr.doob 已提交
4146
							geometry.elementsNeedUpdate = true;
M
Mr.doob 已提交
4147
							geometry.uvsNeedUpdate = true;
M
Mr.doob 已提交
4148
							geometry.normalsNeedUpdate = true;
4149
							geometry.tangentsNeedUpdate = true;
M
Mr.doob 已提交
4150
							geometry.colorsNeedUpdate = true;
4151 4152

						}
M
Mr.doob 已提交
4153

4154
					}
M
Mr.doob 已提交
4155

4156 4157 4158 4159
				} else if ( geometry instanceof THREE.BufferGeometry ) {

					initDirectBuffers( geometry );

4160
				}
M
Mr.doob 已提交
4161

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

4164
				geometry = object.geometry;
M
Mr.doob 已提交
4165

4166
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
4167

4168 4169
					createRibbonBuffers( geometry );
					initRibbonBuffers( geometry );
M
Mr.doob 已提交
4170

4171
					geometry.verticesNeedUpdate = true;
M
Mr.doob 已提交
4172
					geometry.colorsNeedUpdate = true;
M
Mr.doob 已提交
4173

4174
				}
M
Mr.doob 已提交
4175

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

4178
				geometry = object.geometry;
M
Mr.doob 已提交
4179

4180
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
4181

4182 4183
					createLineBuffers( geometry );
					initLineBuffers( geometry, object );
M
Mr.doob 已提交
4184

4185
					geometry.verticesNeedUpdate = true;
M
Mr.doob 已提交
4186
					geometry.colorsNeedUpdate = true;
4187

4188
				}
4189

4190
			} else if ( object instanceof THREE.ParticleSystem ) {
4191

4192
				geometry = object.geometry;
4193

4194
				if ( ! geometry.__webglVertexBuffer ) {
4195

4196 4197
					createParticleBuffers( geometry );
					initParticleBuffers( geometry, object );
4198

4199
					geometry.verticesNeedUpdate = true;
M
Mr.doob 已提交
4200
					geometry.colorsNeedUpdate = true;
4201

4202
				}
4203

4204
			}
4205

4206
		}
4207

4208
		if ( ! object.__webglActive ) {
4209

4210
			if ( object instanceof THREE.Mesh ) {
4211

4212
				geometry = object.geometry;
4213

4214 4215 4216 4217 4218 4219 4220 4221 4222
				if ( geometry instanceof THREE.BufferGeometry ) {

					addBuffer( scene.__webglObjects, geometry, object );

				} else {

					for ( g in geometry.geometryGroups ) {

						geometryGroup = geometry.geometryGroups[ g ];
4223

4224
						addBuffer( scene.__webglObjects, geometryGroup, object );
4225

4226
					}
4227

4228
				}
4229

4230 4231 4232
			} else if ( object instanceof THREE.Ribbon ||
						object instanceof THREE.Line ||
						object instanceof THREE.ParticleSystem ) {
4233

4234 4235
				geometry = object.geometry;
				addBuffer( scene.__webglObjects, geometry, object );
4236

4237
			} else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
4238

4239
				addBufferImmediate( scene.__webglObjectsImmediate, object );
4240

4241
			} else if ( object instanceof THREE.Sprite ) {
4242

4243
				scene.__webglSprites.push( object );
4244

4245 4246 4247 4248
			} else if ( object instanceof THREE.LensFlare ) {

				scene.__webglFlares.push( object );

4249 4250
			}

4251
			object.__webglActive = true;
4252

4253
		}
4254

4255
	};
4256

4257
	function addBuffer ( objlist, buffer, object ) {
4258

4259 4260 4261 4262 4263 4264 4265 4266
		objlist.push(
			{
				buffer: buffer,
				object: object,
				opaque: null,
				transparent: null
			}
		);
4267

4268
	};
4269

4270
	function addBufferImmediate ( objlist, object ) {
4271

4272 4273 4274 4275 4276
		objlist.push(
			{
				object: object,
				opaque: null,
				transparent: null
4277
			}
4278
		);
4279

4280
	};
4281

4282
	// Objects updates
4283

4284
	function updateObject ( object ) {
4285

4286 4287
		var geometry = object.geometry,
			geometryGroup, customAttributesDirty, material;
4288

4289
		if ( object instanceof THREE.Mesh ) {
4290

4291 4292
			if ( geometry instanceof THREE.BufferGeometry ) {

M
Mr.doob 已提交
4293
				if ( geometry.verticesNeedUpdate || geometry.elementsNeedUpdate ||
M
Mr.doob 已提交
4294
					 geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
4295
					 geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate ) {
4296

4297
					setDirectBuffers( geometry, _gl.DYNAMIC_DRAW, !geometry.dynamic );
4298

4299
				}
4300

4301
				geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4302
				geometry.elementsNeedUpdate = false;
M
Mr.doob 已提交
4303
				geometry.uvsNeedUpdate = false;
M
Mr.doob 已提交
4304
				geometry.normalsNeedUpdate = false;
M
Mr.doob 已提交
4305
				geometry.colorsNeedUpdate = false;
4306
				geometry.tangentsNeedUpdate = false;
4307

4308
			} else {
4309

4310
				// check all geometry groups
4311

4312 4313 4314 4315 4316 4317 4318 4319
				for( var i = 0, il = geometry.geometryGroupsList.length; i < il; i ++ ) {

					geometryGroup = geometry.geometryGroupsList[ i ];

					material = getBufferMaterial( object, geometryGroup );

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

4320
					if ( geometry.verticesNeedUpdate || geometry.morphTargetsNeedUpdate || geometry.elementsNeedUpdate ||
M
Mr.doob 已提交
4321
						 geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
4322
						 geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate || customAttributesDirty ) {
4323 4324 4325 4326

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

					}
4327

4328
				}
M
Mr.doob 已提交
4329

4330
				geometry.verticesNeedUpdate = false;
4331
				geometry.morphTargetsNeedUpdate = false;
M
Mr.doob 已提交
4332
				geometry.elementsNeedUpdate = false;
M
Mr.doob 已提交
4333
				geometry.uvsNeedUpdate = false;
M
Mr.doob 已提交
4334
				geometry.normalsNeedUpdate = false;
M
Mr.doob 已提交
4335
				geometry.colorsNeedUpdate = false;
4336
				geometry.tangentsNeedUpdate = false;
4337

4338
				material.attributes && clearCustomAttributes( material );
4339

4340
			}
4341

4342
		} else if ( object instanceof THREE.Ribbon ) {
4343

M
Mr.doob 已提交
4344
			if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate ) {
4345

4346
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
4347

4348
			}
4349

4350
			geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4351
			geometry.colorsNeedUpdate = false;
4352

4353
		} else if ( object instanceof THREE.Line ) {
4354

4355
			material = getBufferMaterial( object, geometryGroup );
A
alteredq 已提交
4356

4357
			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
A
alteredq 已提交
4358

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

4361
				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
4362

4363
			}
4364

4365
			geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4366
			geometry.colorsNeedUpdate = false;
4367

4368
			material.attributes && clearCustomAttributes( material );
4369

4370
		} else if ( object instanceof THREE.ParticleSystem ) {
4371

4372
			material = getBufferMaterial( object, geometryGroup );
4373

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

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

4378
				setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
4379

4380
			}
4381

4382
			geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4383
			geometry.colorsNeedUpdate = false;
4384

4385
			material.attributes && clearCustomAttributes( material );
4386

4387
		}
4388

4389
	};
4390

4391
	// Objects updates - custom attributes check
4392

4393
	function areCustomAttributesDirty ( material ) {
4394

4395
		for ( var a in material.attributes ) {
4396

4397
			if ( material.attributes[ a ].needsUpdate ) return true;
4398

4399
		}
4400

4401
		return false;
4402

4403
	};
4404

4405 4406 4407
	function clearCustomAttributes ( material ) {

		for ( var a in material.attributes ) {
4408

4409
			material.attributes[ a ].needsUpdate = false;
4410

4411
		}
4412

4413
	};
4414

4415
	// Objects removal
4416

4417
	function removeObject ( object, scene ) {
4418

4419 4420 4421 4422
		if ( object instanceof THREE.Mesh  ||
			 object instanceof THREE.ParticleSystem ||
			 object instanceof THREE.Ribbon ||
			 object instanceof THREE.Line ) {
4423

4424
			removeInstances( scene.__webglObjects, object );
4425

4426
		} else if ( object instanceof THREE.Sprite ) {
4427

4428
			removeInstancesDirect( scene.__webglSprites, object );
4429

4430 4431 4432 4433
		} else if ( object instanceof THREE.LensFlare ) {

			removeInstancesDirect( scene.__webglFlares, object );

4434
		} else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
4435

4436
			removeInstances( scene.__webglObjectsImmediate, object );
4437

4438
		}
4439

4440
		object.__webglActive = false;
4441

4442
	};
4443

4444
	function removeInstances ( objlist, object ) {
4445

4446
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4447

4448
			if ( objlist[ o ].object === object ) {
4449

4450
				objlist.splice( o, 1 );
4451

4452
			}
4453

4454
		}
4455

4456
	};
4457

4458
	function removeInstancesDirect ( objlist, object ) {
4459

4460
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4461

4462
			if ( objlist[ o ] === object ) {
4463

4464
				objlist.splice( o, 1 );
4465

4466
			}
4467

4468
		}
4469

4470
	};
4471

4472
	// Materials
4473

4474
	this.initMaterial = function ( material, lights, fog, object ) {
4475

4476
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
4477

4478
		if ( material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
4479

4480
			shaderID = 'depth';
4481

4482
		} else if ( material instanceof THREE.MeshNormalMaterial ) {
4483

4484
			shaderID = 'normal';
M
Mr.doob 已提交
4485

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

4488
			shaderID = 'basic';
M
Mr.doob 已提交
4489

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

4492
			shaderID = 'lambert';
M
Mr.doob 已提交
4493

4494
		} else if ( material instanceof THREE.MeshPhongMaterial ) {
4495

4496
			shaderID = 'phong';
4497

4498
		} else if ( material instanceof THREE.LineBasicMaterial ) {
4499

4500
			shaderID = 'basic';
4501

4502
		} else if ( material instanceof THREE.ParticleBasicMaterial ) {
4503

4504
			shaderID = 'particle_basic';
4505 4506 4507

		}

4508
		if ( shaderID ) {
4509

4510
			setMaterialShaders( material, THREE.ShaderLib[ shaderID ] );
4511

4512
		}
4513

4514 4515
		// heuristics to create shader parameters according to lights in the scene
		// (not to blow over maxLights budget)
4516

4517
		maxLightCount = allocateLights( lights );
4518

4519
		maxShadows = allocateShadows( lights );
4520

4521
		maxBones = allocateBones( object );
4522

4523
		parameters = {
4524

A
alteredq 已提交
4525 4526 4527 4528
			map: !!material.map,
			envMap: !!material.envMap,
			lightMap: !!material.lightMap,

4529
			vertexColors: material.vertexColors,
A
alteredq 已提交
4530 4531 4532 4533

			fog: fog,
			useFog: material.fog,

4534
			sizeAttenuation: material.sizeAttenuation,
A
alteredq 已提交
4535

4536
			skinning: material.skinning,
A
alteredq 已提交
4537
			maxBones: maxBones,
4538
			useVertexTexture: _supportsBoneTextures && object.useVertexTexture,
4539 4540
			boneTextureWidth: object.boneTextureWidth,
			boneTextureHeight: object.boneTextureHeight,
A
alteredq 已提交
4541

4542
			morphTargets: material.morphTargets,
A
alteredq 已提交
4543
			morphNormals: material.morphNormals,
4544
			maxMorphTargets: this.maxMorphTargets,
A
alteredq 已提交
4545
			maxMorphNormals: this.maxMorphNormals,
A
alteredq 已提交
4546 4547 4548 4549 4550 4551

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

			maxShadows: maxShadows,
4552 4553
			shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
			shadowMapSoft: this.shadowMapSoft,
A
alteredq 已提交
4554 4555
			shadowMapDebug: this.shadowMapDebug,
			shadowMapCascade: this.shadowMapCascade,
A
alteredq 已提交
4556

4557 4558
			alphaTest: material.alphaTest,
			metal: material.metal,
4559
			perPixel: material.perPixel,
4560
			wrapAround: material.wrapAround,
4561
			doubleSided: object && object.doubleSided
4562

4563
		};
M
Mr.doob 已提交
4564

4565
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
4566

4567
		var attributes = material.program.attributes;
4568

4569 4570 4571 4572
		if ( attributes.position >= 0 ) _gl.enableVertexAttribArray( attributes.position );
		if ( attributes.color >= 0 ) _gl.enableVertexAttribArray( attributes.color );
		if ( attributes.normal >= 0 ) _gl.enableVertexAttribArray( attributes.normal );
		if ( attributes.tangent >= 0 ) _gl.enableVertexAttribArray( attributes.tangent );
4573

4574 4575 4576
		if ( material.skinning &&
			 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
M
Mr.doob 已提交
4577

4578 4579 4580 4581
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
M
Mr.doob 已提交
4582 4583

		}
4584

4585
		if ( material.attributes ) {
A
alteredq 已提交
4586

4587
			for ( a in material.attributes ) {
M
Mr.doob 已提交
4588

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

4591
			}
M
Mr.doob 已提交
4592

4593
		}
M
Mr.doob 已提交
4594

4595
		if ( material.morphTargets ) {
M
Mr.doob 已提交
4596

4597
			material.numSupportedMorphTargets = 0;
4598

4599
			var id, base = "morphTarget";
4600

4601
			for ( i = 0; i < this.maxMorphTargets; i ++ ) {
4602

4603
				id = base + i;
M
Mr.doob 已提交
4604

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

4607 4608
					_gl.enableVertexAttribArray( attributes[ id ] );
					material.numSupportedMorphTargets ++;
4609

4610
				}
4611

4612
			}
4613

4614
		}
4615

A
alteredq 已提交
4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636
		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

			var id, base = "morphNormal";

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

				id = base + i;

				if ( attributes[ id ] >= 0 ) {

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

				}

			}

		}

4637
		material.uniformsList = [];
4638

4639
		for ( u in material.uniforms ) {
4640

4641
			material.uniformsList.push( [ material.uniforms[ u ], u ] );
4642

4643
		}
M
Mr.doob 已提交
4644

4645
	};
M
Mr.doob 已提交
4646

4647
	function setMaterialShaders( material, shaders ) {
M
Mr.doob 已提交
4648

4649 4650 4651
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
M
Mr.doob 已提交
4652

4653
	};
M
Mr.doob 已提交
4654

4655
	function setProgram( camera, lights, fog, material, object ) {
4656

A
alteredq 已提交
4657
		if ( material.needsUpdate ) {
4658

4659 4660
			if ( material.program ) _this.deallocateMaterial( material );

4661
			_this.initMaterial( material, lights, fog, object );
A
alteredq 已提交
4662
			material.needsUpdate = false;
4663

4664
		}
4665

4666
		if ( material.morphTargets ) {
4667

4668
			if ( ! object.__webglMorphTargetInfluences ) {
4669

4670
				object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );
4671

4672
			}
4673

4674
		}
4675

4676
		var refreshMaterial = false;
4677

4678 4679 4680
		var program = material.program,
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
4681

4682
		if ( program !== _currentProgram ) {
4683

4684 4685
			_gl.useProgram( program );
			_currentProgram = program;
4686

4687
			refreshMaterial = true;
4688

4689
		}
4690

4691
		if ( material.id !== _currentMaterialId ) {
4692

4693 4694
			_currentMaterialId = material.id;
			refreshMaterial = true;
4695

4696
		}
4697

4698
		if ( refreshMaterial || camera !== _currentCamera ) {
4699

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

4702 4703 4704 4705 4706 4707
			if ( camera !== _currentCamera ) _currentCamera = camera;

		}

		if ( refreshMaterial ) {

4708
			// refresh uniforms common to several materials
4709

4710
			if ( fog && material.fog ) {
4711

4712
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
4713

4714
			}
M
Mr.doob 已提交
4715

4716 4717 4718
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material.lights ) {
4719

4720 4721 4722 4723 4724 4725 4726
				if ( _lightsNeedUpdate ) {

					setupLights( program, lights );
					_lightsNeedUpdate = false;

				}

4727
				refreshUniformsLights( m_uniforms, _lights );
4728

4729
			}
M
Mr.doob 已提交
4730

4731 4732 4733
			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
4734

4735
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
4736 4737 4738

			}

4739
			// refresh single material specific uniforms
M
Mr.doob 已提交
4740

4741
			if ( material instanceof THREE.LineBasicMaterial ) {
4742

4743
				refreshUniformsLine( m_uniforms, material );
M
Mr.doob 已提交
4744

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

4747
				refreshUniformsParticle( m_uniforms, material );
M
Mr.doob 已提交
4748

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

4751
				refreshUniformsPhong( m_uniforms, material );
M
Mr.doob 已提交
4752

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

4755
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
4756

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

4759 4760 4761
				m_uniforms.mNear.value = camera.near;
				m_uniforms.mFar.value = camera.far;
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4762

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

4765
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4766

4767
			}
M
Mr.doob 已提交
4768

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

4771
				refreshUniformsShadow( m_uniforms, lights );
M
Mr.doob 已提交
4772

4773
			}
M
Mr.doob 已提交
4774

4775
			// load common uniforms
M
Mr.doob 已提交
4776

4777
			loadUniformsGeneric( program, material.uniformsList );
M
Mr.doob 已提交
4778

4779 4780
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)
4781

4782 4783 4784
			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
				 material.envMap ) {
4785

4786
				if ( p_uniforms.cameraPosition !== null ) {
4787

4788 4789
					var position = camera.matrixWorld.getPosition();
					_gl.uniform3f( p_uniforms.cameraPosition, position.x, position.y, position.z );
4790

4791
				}
4792 4793 4794

			}

4795 4796 4797 4798
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {
4799

4800
				if ( p_uniforms.viewMatrix !== null ) {
4801

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

4804
				}
4805

4806
			}
M
Mr.doob 已提交
4807

4808 4809 4810 4811
		}

		if ( material.skinning ) {

4812
			if ( _supportsBoneTextures && object.useVertexTexture ) {
4813

4814
				if ( p_uniforms.boneTexture !== null ) {
4815

4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828
					// shadowMap texture array starts from 6
					// texture unit 12 should leave space for 6 shadowmaps

					var textureUnit = 12;

					_gl.uniform1i( p_uniforms.boneTexture, textureUnit );
					_this.setTexture( object.boneTexture, textureUnit );

				}

			} else {

				if ( p_uniforms.boneGlobalMatrices !== null ) {
4829

4830
					_gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.boneMatrices );
4831

4832
				}
4833 4834

			}
4835

4836
		}
M
Mr.doob 已提交
4837

4838
		loadUniformsMatrices( p_uniforms, object );
M
Mr.doob 已提交
4839

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

4842
			_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object.matrixWorld.elements );
4843

4844
		}
4845

4846
		return program;
4847

4848
	};
4849

4850
	// Uniforms (refresh uniforms objects)
A
alteredq 已提交
4851

4852
	function refreshUniformsCommon ( uniforms, material ) {
4853

4854
		uniforms.opacity.value = material.opacity;
4855

4856
		if ( _this.gammaInput ) {
4857

4858
			uniforms.diffuse.value.copyGammaToLinear( material.color );
4859

4860
		} else {
4861

4862
			uniforms.diffuse.value = material.color;
4863

4864
		}
4865

4866
		uniforms.map.texture = material.map;
4867

4868
		if ( material.map ) {
4869

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

4872
		}
M
Mr.doob 已提交
4873

4874
		uniforms.lightMap.texture = material.lightMap;
4875

4876 4877
		uniforms.envMap.texture = material.envMap;
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
4878

4879
		if ( _this.gammaInput ) {
4880

4881 4882
			//uniforms.reflectivity.value = material.reflectivity * material.reflectivity;
			uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
4883

4884
		} else {
4885

4886
			uniforms.reflectivity.value = material.reflectivity;
4887

4888
		}
4889

4890 4891 4892
		uniforms.refractionRatio.value = material.refractionRatio;
		uniforms.combine.value = material.combine;
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
M
Mr.doob 已提交
4893

4894
	};
M
Mr.doob 已提交
4895

4896
	function refreshUniformsLine ( uniforms, material ) {
M
Mr.doob 已提交
4897

4898 4899
		uniforms.diffuse.value = material.color;
		uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4900

4901
	};
M
Mr.doob 已提交
4902

4903
	function refreshUniformsParticle ( uniforms, material ) {
4904

4905 4906 4907 4908
		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.
4909

4910
		uniforms.map.texture = material.map;
4911

4912
	};
4913

4914
	function refreshUniformsFog ( uniforms, fog ) {
4915

4916
		uniforms.fogColor.value = fog.color;
4917

4918
		if ( fog instanceof THREE.Fog ) {
4919

4920 4921
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
4922

4923
		} else if ( fog instanceof THREE.FogExp2 ) {
M
Mikael Emtinger 已提交
4924

4925
			uniforms.fogDensity.value = fog.density;
M
Mikael Emtinger 已提交
4926

4927
		}
M
Mikael Emtinger 已提交
4928

4929
	};
M
Mikael Emtinger 已提交
4930

4931
	function refreshUniformsPhong ( uniforms, material ) {
M
Mikael Emtinger 已提交
4932

4933
		uniforms.shininess.value = material.shininess;
4934

4935
		if ( _this.gammaInput ) {
M
Mikael Emtinger 已提交
4936

4937
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
4938
			uniforms.emissive.value.copyGammaToLinear( material.emissive );
4939
			uniforms.specular.value.copyGammaToLinear( material.specular );
4940

4941
		} else {
4942

4943
			uniforms.ambient.value = material.ambient;
4944
			uniforms.emissive.value = material.emissive;
4945
			uniforms.specular.value = material.specular;
4946

4947
		}
4948

4949 4950 4951 4952 4953 4954
		if ( material.wrapAround ) {

			uniforms.wrapRGB.value.copy( material.wrapRGB );

		}

4955
	};
4956

4957
	function refreshUniformsLambert ( uniforms, material ) {
4958

4959
		if ( _this.gammaInput ) {
4960

4961
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
4962
			uniforms.emissive.value.copyGammaToLinear( material.emissive );
M
Mr.doob 已提交
4963

4964
		} else {
4965

4966
			uniforms.ambient.value = material.ambient;
4967
			uniforms.emissive.value = material.emissive;
4968

4969
		}
4970

4971 4972 4973 4974 4975 4976
		if ( material.wrapAround ) {

			uniforms.wrapRGB.value.copy( material.wrapRGB );

		}

4977
	};
4978

4979
	function refreshUniformsLights ( uniforms, lights ) {
4980

4981
		uniforms.ambientLightColor.value = lights.ambient;
4982

4983 4984
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
4985

4986 4987 4988
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
		uniforms.pointLightDistance.value = lights.point.distances;
4989

A
alteredq 已提交
4990 4991 4992 4993 4994 4995 4996
		uniforms.spotLightColor.value = lights.spot.colors;
		uniforms.spotLightPosition.value = lights.spot.positions;
		uniforms.spotLightDistance.value = lights.spot.distances;
		uniforms.spotLightDirection.value = lights.spot.directions;
		uniforms.spotLightAngle.value = lights.spot.angles;
		uniforms.spotLightExponent.value = lights.spot.exponents;

4997
	};
4998

4999
	function refreshUniformsShadow ( uniforms, lights ) {
M
Mr.doob 已提交
5000

5001
		if ( uniforms.shadowMatrix ) {
5002

5003
			var j = 0;
5004

5005
			for ( var i = 0, il = lights.length; i < il; i ++ ) {
5006

5007
				var light = lights[ i ];
5008

A
alteredq 已提交
5009 5010
				if ( ! light.castShadow ) continue;

5011
				if ( light instanceof THREE.SpotLight || ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) ) {
5012 5013 5014

					uniforms.shadowMap.texture[ j ] = light.shadowMap;
					uniforms.shadowMapSize.value[ j ] = light.shadowMapSize;
5015

5016 5017 5018 5019 5020 5021 5022 5023 5024 5025
					uniforms.shadowMatrix.value[ j ] = light.shadowMatrix;

					uniforms.shadowDarkness.value[ j ] = light.shadowDarkness;
					uniforms.shadowBias.value[ j ] = light.shadowBias;

					j ++;

				}

			}
5026

5027 5028
		}

5029
	};
5030

5031
	// Uniforms (load to GPU)
5032

5033
	function loadUniformsMatrices ( uniforms, object ) {
5034

5035
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrix.elements );
5036

5037
		if ( uniforms.normalMatrix ) {
5038

5039
			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrix.elements );
5040

5041
		}
5042

5043
	};
5044

5045
	function loadUniformsGeneric ( program, uniforms ) {
5046

5047
		var uniform, value, type, location, texture, i, il, j, jl, offset;
5048

M
Mr.doob 已提交
5049
		for ( j = 0, jl = uniforms.length; j < jl; j ++ ) {
5050

5051 5052
			location = program.uniforms[ uniforms[ j ][ 1 ] ];
			if ( !location ) continue;
5053

5054
			uniform = uniforms[ j ][ 0 ];
5055

5056 5057
			type = uniform.type;
			value = uniform.value;
5058

5059
			if ( type === "i" ) { // single integer
5060

5061
				_gl.uniform1i( location, value );
5062

5063
			} else if ( type === "f" ) { // single float
5064

5065
				_gl.uniform1f( location, value );
5066

5067
			} else if ( type === "v2" ) { // single THREE.Vector2
5068

5069
				_gl.uniform2f( location, value.x, value.y );
5070

5071
			} else if ( type === "v3" ) { // single THREE.Vector3
5072

5073
				_gl.uniform3f( location, value.x, value.y, value.z );
5074

5075
			} else if ( type === "v4" ) { // single THREE.Vector4
5076

5077
				_gl.uniform4f( location, value.x, value.y, value.z, value.w );
5078

5079
			} else if ( type === "c" ) { // single THREE.Color
5080

5081
				_gl.uniform3f( location, value.r, value.g, value.b );
5082

5083 5084 5085
			} else if ( type === "iv1" ) { // flat array of integers (JS or typed array)

				_gl.uniform1iv( location, value );
5086 5087 5088 5089

			} else if ( type === "iv" ) { // flat array of integers with 3 x N size (JS or typed array)

				_gl.uniform3iv( location, value );
5090

5091
			} else if ( type === "fv1" ) { // flat array of floats (JS or typed array)
5092

5093
				_gl.uniform1fv( location, value );
5094

5095
			} else if ( type === "fv" ) { // flat array of floats with 3 x N size (JS or typed array)
5096

5097
				_gl.uniform3fv( location, value );
5098

5099
			} else if ( type === "v2v" ) { // array of THREE.Vector2
5100

5101
				if ( uniform._array === undefined ) {
5102

5103
					uniform._array = new Float32Array( 2 * value.length );
5104

5105
				}
5106

5107
				for ( i = 0, il = value.length; i < il; i ++ ) {
5108

5109
					offset = i * 2;
5110

5111 5112
					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;
5113

5114
				}
5115

5116
				_gl.uniform2fv( location, uniform._array );
5117

5118
			} else if ( type === "v3v" ) { // array of THREE.Vector3
5119

5120
				if ( uniform._array === undefined ) {
M
Mr.doob 已提交
5121

5122
					uniform._array = new Float32Array( 3 * value.length );
A
alteredq 已提交
5123

5124
				}
5125

5126
				for ( i = 0, il = value.length; i < il; i ++ ) {
5127

5128
					offset = i * 3;
5129

5130 5131 5132
					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;
					uniform._array[ offset + 2 ] = value[ i ].z;
A
alteredq 已提交
5133

5134
				}
5135

5136
				_gl.uniform3fv( location, uniform._array );
A
alteredq 已提交
5137

5138
			} else if ( type === "v4v" ) { // array of THREE.Vector4
M
Mr.doob 已提交
5139

5140
				if ( uniform._array === undefined ) {
M
Mr.doob 已提交
5141

5142
					uniform._array = new Float32Array( 4 * value.length );
M
Mr.doob 已提交
5143

5144
				}
A
alteredq 已提交
5145

5146
				for ( i = 0, il = value.length; i < il; i ++ ) {
M
Mr.doob 已提交
5147

5148
					offset = i * 4;
M
Mr.doob 已提交
5149

5150 5151 5152 5153
					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 已提交
5154

5155
				}
5156

5157
				_gl.uniform4fv( location, uniform._array );
A
alteredq 已提交
5158

5159
			} else if ( type === "m4") { // single THREE.Matrix4
A
alteredq 已提交
5160

5161
				if ( uniform._array === undefined ) {
A
alteredq 已提交
5162

5163
					uniform._array = new Float32Array( 16 );
A
alteredq 已提交
5164

5165
				}
M
Mr.doob 已提交
5166

5167 5168
				value.flattenToArray( uniform._array );
				_gl.uniformMatrix4fv( location, false, uniform._array );
5169

5170
			} else if ( type === "m4v" ) { // array of THREE.Matrix4
5171

5172
				if ( uniform._array === undefined ) {
5173

5174
					uniform._array = new Float32Array( 16 * value.length );
M
Mr.doob 已提交
5175

5176
				}
M
Mr.doob 已提交
5177

5178
				for ( i = 0, il = value.length; i < il; i ++ ) {
M
Mr.doob 已提交
5179

5180
					value[ i ].flattenToArrayOffset( uniform._array, i * 16 );
A
alteredq 已提交
5181

5182
				}
M
Mr.doob 已提交
5183

5184
				_gl.uniformMatrix4fv( location, false, uniform._array );
M
Mr.doob 已提交
5185

5186
			} else if ( type === "t" ) { // single THREE.Texture (2d or cube)
5187

5188
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
5189

5190
				texture = uniform.texture;
M
Mr.doob 已提交
5191

5192
				if ( !texture ) continue;
M
Mr.doob 已提交
5193

5194
				if ( texture.image instanceof Array && texture.image.length === 6 ) {
M
Mr.doob 已提交
5195

5196
					setCubeTexture( texture, value );
M
Mr.doob 已提交
5197

5198
				} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
M
Mr.doob 已提交
5199

5200
					setCubeTextureDynamic( texture, value );
5201

5202
				} else {
A
alteredq 已提交
5203

5204
					_this.setTexture( texture, value );
A
alteredq 已提交
5205

5206
				}
A
alteredq 已提交
5207

5208
			} else if ( type === "tv" ) { // array of THREE.Texture (2d)
5209

5210
				if ( uniform._array === undefined ) {
5211

5212
					uniform._array = [];
M
Mr.doob 已提交
5213

5214
					for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
M
Mr.doob 已提交
5215

5216
						uniform._array[ i ] = value + i;
M
Mr.doob 已提交
5217 5218 5219

					}

5220
				}
M
Mr.doob 已提交
5221

5222
				_gl.uniform1iv( location, uniform._array );
M
Mr.doob 已提交
5223

5224
				for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
M
Mr.doob 已提交
5225

5226
					texture = uniform.texture[ i ];
M
Mr.doob 已提交
5227

5228
					if ( !texture ) continue;
M
Mr.doob 已提交
5229

5230
					_this.setTexture( texture, uniform._array[ i ] );
M
Mr.doob 已提交
5231

5232
				}
M
Mr.doob 已提交
5233

M
Mr.doob 已提交
5234
			}
M
Mr.doob 已提交
5235

M
Mr.doob 已提交
5236
		}
M
Mr.doob 已提交
5237

5238
	};
M
Mr.doob 已提交
5239

A
alteredq 已提交
5240
	function setupMatrices ( object, camera ) {
M
Mr.doob 已提交
5241

5242
		object._modelViewMatrix.multiply( camera.matrixWorldInverse, object.matrixWorld);
M
Mr.doob 已提交
5243

5244
		object._normalMatrix.getInverse( object._modelViewMatrix );
5245
		object._normalMatrix.transpose();
M
Mr.doob 已提交
5246

A
alteredq 已提交
5247
	};
M
Mr.doob 已提交
5248

5249
	function setupLights ( program, lights ) {
M
Mr.doob 已提交
5250

5251 5252 5253
		var l, ll, light, n,
		r = 0, g = 0, b = 0,
		color, position, intensity, distance,
M
Mr.doob 已提交
5254

5255
		zlights = _lights,
A
alteredq 已提交
5256

5257 5258
		dcolors = zlights.directional.colors,
		dpositions = zlights.directional.positions,
A
alteredq 已提交
5259

5260 5261 5262
		pcolors = zlights.point.colors,
		ppositions = zlights.point.positions,
		pdistances = zlights.point.distances,
5263

A
alteredq 已提交
5264 5265 5266 5267 5268 5269 5270
		scolors = zlights.spot.colors,
		spositions = zlights.spot.positions,
		sdistances = zlights.spot.distances,
		sdirections = zlights.spot.directions,
		sangles = zlights.spot.angles,
		sexponents = zlights.spot.exponents,

5271 5272
		dlength = 0,
		plength = 0,
A
alteredq 已提交
5273
		slength = 0,
5274

5275
		doffset = 0,
A
alteredq 已提交
5276 5277
		poffset = 0,
		soffset = 0;
5278

5279
		for ( l = 0, ll = lights.length; l < ll; l ++ ) {
5280

5281
			light = lights[ l ];
A
alteredq 已提交
5282

5283
			if ( light.onlyShadow || ! light.visible ) continue;
A
alteredq 已提交
5284 5285

			color = light.color;
5286 5287
			intensity = light.intensity;
			distance = light.distance;
A
alteredq 已提交
5288

5289
			if ( light instanceof THREE.AmbientLight ) {
5290

5291
				if ( _this.gammaInput ) {
5292

5293 5294 5295
					r += color.r * color.r;
					g += color.g * color.g;
					b += color.b * color.b;
5296

5297
				} else {
5298

5299 5300 5301
					r += color.r;
					g += color.g;
					b += color.b;
5302

5303
				}
5304

5305
			} else if ( light instanceof THREE.DirectionalLight ) {
5306

5307
				doffset = dlength * 3;
5308

5309
				if ( _this.gammaInput ) {
5310

5311 5312 5313
					dcolors[ doffset ]     = color.r * color.r * intensity * intensity;
					dcolors[ doffset + 1 ] = color.g * color.g * intensity * intensity;
					dcolors[ doffset + 2 ] = color.b * color.b * intensity * intensity;
5314

5315
				} else {
5316

5317 5318 5319
					dcolors[ doffset ]     = color.r * intensity;
					dcolors[ doffset + 1 ] = color.g * intensity;
					dcolors[ doffset + 2 ] = color.b * intensity;
A
alteredq 已提交
5320

5321
				}
A
alteredq 已提交
5322

5323 5324 5325
				_direction.copy( light.matrixWorld.getPosition() );
				_direction.subSelf( light.target.matrixWorld.getPosition() );
				_direction.normalize();
A
alteredq 已提交
5326

5327 5328 5329
				dpositions[ doffset ]     = _direction.x;
				dpositions[ doffset + 1 ] = _direction.y;
				dpositions[ doffset + 2 ] = _direction.z;
A
alteredq 已提交
5330

5331
				dlength += 1;
A
alteredq 已提交
5332

A
alteredq 已提交
5333
			} else if( light instanceof THREE.PointLight ) {
M
Mr.doob 已提交
5334

5335
				poffset = plength * 3;
M
Mr.doob 已提交
5336

5337
				if ( _this.gammaInput ) {
5338

5339 5340 5341
					pcolors[ poffset ]     = color.r * color.r * intensity * intensity;
					pcolors[ poffset + 1 ] = color.g * color.g * intensity * intensity;
					pcolors[ poffset + 2 ] = color.b * color.b * intensity * intensity;
A
alteredq 已提交
5342

5343
				} else {
A
alteredq 已提交
5344

5345 5346 5347
					pcolors[ poffset ]     = color.r * intensity;
					pcolors[ poffset + 1 ] = color.g * intensity;
					pcolors[ poffset + 2 ] = color.b * intensity;
A
alteredq 已提交
5348

5349
				}
A
alteredq 已提交
5350

A
alteredq 已提交
5351 5352
				position = light.matrixWorld.getPosition();

5353 5354 5355
				ppositions[ poffset ]     = position.x;
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
A
alteredq 已提交
5356

5357
				pdistances[ plength ] = distance;
A
alteredq 已提交
5358

5359
				plength += 1;
5360

A
alteredq 已提交
5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399
			} else if( light instanceof THREE.SpotLight ) {

				soffset = slength * 3;

				if ( _this.gammaInput ) {

					scolors[ soffset ]     = color.r * color.r * intensity * intensity;
					scolors[ soffset + 1 ] = color.g * color.g * intensity * intensity;
					scolors[ soffset + 2 ] = color.b * color.b * intensity * intensity;

				} else {

					scolors[ soffset ]     = color.r * intensity;
					scolors[ soffset + 1 ] = color.g * intensity;
					scolors[ soffset + 2 ] = color.b * intensity;

				}

				position = light.matrixWorld.getPosition();

				spositions[ soffset ]     = position.x;
				spositions[ soffset + 1 ] = position.y;
				spositions[ soffset + 2 ] = position.z;

				sdistances[ slength ] = distance;

				_direction.copy( position );
				_direction.subSelf( light.target.matrixWorld.getPosition() );
				_direction.normalize();

				sdirections[ soffset ]     = _direction.x;
				sdirections[ soffset + 1 ] = _direction.y;
				sdirections[ soffset + 2 ] = _direction.z;

				sangles[ slength ] = Math.cos( light.angle );
				sexponents[ slength ] = light.exponent;

				slength += 1;

5400
			}
5401

5402
		}
A
alteredq 已提交
5403

5404 5405
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
A
alteredq 已提交
5406

5407 5408
		for ( l = dlength * 3, ll = dcolors.length; l < ll; l ++ ) dcolors[ l ] = 0.0;
		for ( l = plength * 3, ll = pcolors.length; l < ll; l ++ ) pcolors[ l ] = 0.0;
A
alteredq 已提交
5409
		for ( l = slength * 3, ll = scolors.length; l < ll; l ++ ) scolors[ l ] = 0.0;
A
alteredq 已提交
5410

5411
		zlights.directional.length = dlength;
A
alteredq 已提交
5412 5413
		zlights.point.length = plength;
		zlights.spot.length = slength;
A
alteredq 已提交
5414

5415 5416 5417
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
5418

5419
	};
M
Mr.doob 已提交
5420

5421
	// GL state setting
M
Mr.doob 已提交
5422

5423
	this.setFaceCulling = function ( cullFace, frontFace ) {
M
Mr.doob 已提交
5424

5425
		if ( cullFace ) {
M
Mr.doob 已提交
5426

5427
			if ( !frontFace || frontFace === "ccw" ) {
5428

5429
				_gl.frontFace( _gl.CCW );
5430

5431
			} else {
5432

5433
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
5434

5435
			}
M
Mr.doob 已提交
5436

5437
			if( cullFace === "back" ) {
5438

5439
				_gl.cullFace( _gl.BACK );
5440

5441
			} else if( cullFace === "front" ) {
5442

5443
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
5444

5445
			} else {
5446

5447
				_gl.cullFace( _gl.FRONT_AND_BACK );
5448

5449
			}
5450

5451
			_gl.enable( _gl.CULL_FACE );
5452

5453
		} else {
5454

5455
			_gl.disable( _gl.CULL_FACE );
5456 5457 5458 5459 5460

		}

	};

A
alteredq 已提交
5461
	this.setObjectFaces = function ( object ) {
5462

5463
		if ( _oldDoubleSided !== object.doubleSided ) {
M
Mr.doob 已提交
5464

M
Mr.doob 已提交
5465
			if ( object.doubleSided ) {
M
Mr.doob 已提交
5466

5467
				_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
5468

5469
			} else {
5470

5471
				_gl.enable( _gl.CULL_FACE );
5472

5473
			}
5474

5475
			_oldDoubleSided = object.doubleSided;
5476

5477
		}
5478

5479
		if ( _oldFlipSided !== object.flipSided ) {
5480

M
Mr.doob 已提交
5481
			if ( object.flipSided ) {
5482

5483
				_gl.frontFace( _gl.CW );
5484

5485
			} else {
5486

5487
				_gl.frontFace( _gl.CCW );
5488

5489
			}
5490

5491
			_oldFlipSided = object.flipSided;
5492

5493
		}
5494

5495
	};
5496

A
alteredq 已提交
5497
	this.setDepthTest = function ( depthTest ) {
5498

5499
		if ( _oldDepthTest !== depthTest ) {
5500

5501
			if ( depthTest ) {
5502

5503
				_gl.enable( _gl.DEPTH_TEST );
5504

5505
			} else {
5506

5507
				_gl.disable( _gl.DEPTH_TEST );
5508 5509 5510

			}

5511
			_oldDepthTest = depthTest;
5512

5513
		}
5514

5515
	};
5516

5517
	this.setDepthWrite = function ( depthWrite ) {
A
alteredq 已提交
5518

5519
		if ( _oldDepthWrite !== depthWrite ) {
A
alteredq 已提交
5520

5521 5522
			_gl.depthMask( depthWrite );
			_oldDepthWrite = depthWrite;
A
alteredq 已提交
5523 5524 5525 5526 5527

		}

	};

5528
	function setLineWidth ( width ) {
5529

5530
		if ( width !== _oldLineWidth ) {
5531

5532 5533 5534
			_gl.lineWidth( width );

			_oldLineWidth = width;
5535 5536 5537

		}

5538
	};
5539

5540
	function setPolygonOffset ( polygonoffset, factor, units ) {
5541

5542
		if ( _oldPolygonOffset !== polygonoffset ) {
M
Mr.doob 已提交
5543

5544
			if ( polygonoffset ) {
5545

5546
				_gl.enable( _gl.POLYGON_OFFSET_FILL );
5547

5548
			} else {
5549

5550
				_gl.disable( _gl.POLYGON_OFFSET_FILL );
5551

5552
			}
5553

5554
			_oldPolygonOffset = polygonoffset;
5555

5556
		}
5557

5558
		if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
5559

5560
			_gl.polygonOffset( factor, units );
M
Mr.doob 已提交
5561

5562 5563
			_oldPolygonOffsetFactor = factor;
			_oldPolygonOffsetUnits = units;
M
Mr.doob 已提交
5564

5565
		}
M
Mr.doob 已提交
5566

5567
	};
M
Mr.doob 已提交
5568

5569
	this.setBlending = function ( blending, blendEquation, blendSrc, blendDst ) {
M
Mr.doob 已提交
5570

5571
		if ( blending !== _oldBlending ) {
M
Mr.doob 已提交
5572

5573
			if ( blending === THREE.NoBlending ) {
M
Mr.doob 已提交
5574

5575
				_gl.disable( _gl.BLEND );
M
Mr.doob 已提交
5576

5577
			} else if ( blending === THREE.AdditiveBlending ) {
M
Mr.doob 已提交
5578

5579 5580 5581
				_gl.enable( _gl.BLEND );
				_gl.blendEquation( _gl.FUNC_ADD );
				_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
M
Mr.doob 已提交
5582

5583
			} else if ( blending === THREE.SubtractiveBlending ) {
M
Mr.doob 已提交
5584

5585 5586 5587 5588
				// 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 已提交
5589

5590
			} else if ( blending === THREE.MultiplyBlending ) {
M
Mr.doob 已提交
5591

5592 5593 5594 5595
				// TODO: Find blendFuncSeparate() combination
				_gl.enable( _gl.BLEND );
				_gl.blendEquation( _gl.FUNC_ADD );
				_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
5596

5597
			} else if ( blending === THREE.CustomBlending ) {
5598

5599
				_gl.enable( _gl.BLEND );
5600

5601
			} else {
5602

5603 5604 5605
				_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 );
5606

5607
			}
5608

5609
			_oldBlending = blending;
5610

5611
		}
5612

5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639
		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;

		}

5640
	};
5641

5642 5643 5644
	// Shaders

	function buildProgram ( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
5645

5646
		var p, pl, program, code;
5647
		var chunks = [];
5648 5649 5650

		// Generate code

5651 5652 5653 5654 5655 5656 5657 5658 5659 5660
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

			chunks.push( fragmentShader );
			chunks.push( vertexShader );

		}
5661 5662 5663

		for ( p in parameters ) {

5664 5665
			chunks.push( p );
			chunks.push( parameters[ p ] );
5666 5667 5668

		}

5669 5670
		code = chunks.join();

5671 5672 5673 5674
		// Check if code has been already compiled

		for ( p = 0, pl = _programs.length; p < pl; p ++ ) {

A
alteredq 已提交
5675 5676 5677
			var programInfo = _programs[ p ];

			if ( programInfo.code === code ) {
5678 5679

				// console.log( "Code already compiled." /*: \n\n" + code*/ );
5680

A
alteredq 已提交
5681 5682 5683
				programInfo.usedTimes ++;

				return programInfo.program;
5684 5685 5686 5687

			}

		}
5688

5689
		//console.log( "building new program " );
5690 5691 5692

		//

5693
		program = _gl.createProgram();
M
Mr.doob 已提交
5694

5695
		var prefix_vertex = [
M
Mr.doob 已提交
5696

5697 5698
			"precision " + _precision + " float;",

5699
			_supportsVertexTextures ? "#define VERTEX_TEXTURES" : "",
5700

5701 5702 5703 5704
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

5705 5706
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
5707
			"#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
5708

5709 5710
			"#define MAX_SHADOWS " + parameters.maxShadows,

5711 5712
			"#define MAX_BONES " + parameters.maxBones,

5713
			parameters.map ? "#define USE_MAP" : "",
5714 5715 5716
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5717

5718
			parameters.skinning ? "#define USE_SKINNING" : "",
5719
			parameters.useVertexTexture ? "#define BONE_TEXTURE" : "",
5720 5721
			parameters.boneTextureWidth ? "#define N_BONE_PIXEL_X " + parameters.boneTextureWidth.toFixed( 1 ) : "",
			parameters.boneTextureHeight ? "#define N_BONE_PIXEL_Y " + parameters.boneTextureHeight.toFixed( 1 ) : "",
5722

5723
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
A
alteredq 已提交
5724
			parameters.morphNormals ? "#define USE_MORPHNORMALS" : "",
A
alteredq 已提交
5725
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
5726
			parameters.wrapAround ? "#define WRAP_AROUND" : "",
5727
			parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
5728

5729
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5730
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
A
alteredq 已提交
5731 5732
			parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
			parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
5733

5734 5735
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
5736 5737 5738
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
5739 5740
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
5741
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
5742

M
Mr.doob 已提交
5743 5744 5745
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
5746
			"attribute vec2 uv2;",
5747

5748
			"#ifdef USE_COLOR",
5749

5750
				"attribute vec3 color;",
5751

5752 5753
			"#endif",

5754
			"#ifdef USE_MORPHTARGETS",
5755

5756 5757 5758 5759
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
A
alteredq 已提交
5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775

				"#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",
5776

5777 5778 5779
			"#endif",

			"#ifdef USE_SKINNING",
5780

5781 5782 5783 5784
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
5785

5786
			"#endif",
5787

M
Mr.doob 已提交
5788
			""
A
alteredq 已提交
5789

M
Mr.doob 已提交
5790
		].join("\n");
5791

M
Mr.doob 已提交
5792 5793
		var prefix_fragment = [

5794
			"precision " + _precision + " float;",
M
Mr.doob 已提交
5795 5796 5797

			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
5798
			"#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
M
Mr.doob 已提交
5799

5800 5801
			"#define MAX_SHADOWS " + parameters.maxShadows,

5802 5803
			parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",

5804 5805 5806 5807
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

M
Mr.doob 已提交
5808 5809
			( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
			( parameters.useFog && parameters.fog instanceof THREE.FogExp2 ) ? "#define FOG_EXP2" : "",
M
Mr.doob 已提交
5810 5811 5812 5813 5814

			parameters.map ? "#define USE_MAP" : "",
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5815

5816 5817
			parameters.metal ? "#define METAL" : "",
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
5818
			parameters.wrapAround ? "#define WRAP_AROUND" : "",
5819
			parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
5820

5821
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5822
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
A
alteredq 已提交
5823 5824
			parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
			parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
M
Mr.doob 已提交
5825 5826 5827 5828 5829 5830 5831

			"uniform mat4 viewMatrix;",
			"uniform vec3 cameraPosition;",
			""

		].join("\n");

5832 5833 5834 5835 5836
		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 已提交
5837

M
Mr.doob 已提交
5838
		_gl.linkProgram( program );
N
Nicolas Garcia Belmonte 已提交
5839

M
Mr.doob 已提交
5840
		if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
N
Nicolas Garcia Belmonte 已提交
5841

5842
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
5843

N
Nicolas Garcia Belmonte 已提交
5844
		}
5845

5846 5847 5848 5849 5850
		// clean up

		_gl.deleteShader( glFragmentShader );
		_gl.deleteShader( glVertexShader );

5851 5852
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
5853

M
Mr.doob 已提交
5854
		program.uniforms = {};
5855
		program.attributes = {};
M
Mr.doob 已提交
5856

5857 5858 5859 5860
		var identifiers, u, a, i;

		// cache uniform locations

5861
		identifiers = [
5862

5863
			'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
5864
			'morphTargetInfluences'
M
Mr.doob 已提交
5865

5866
		];
M
Mr.doob 已提交
5867

5868
		if ( parameters.useVertexTexture ) {
5869 5870 5871 5872 5873 5874 5875 5876 5877

			identifiers.push( 'boneTexture' );

		} else {

			identifiers.push( 'boneGlobalMatrices' );

		}

5878
		for ( u in uniforms ) {
M
Mr.doob 已提交
5879

5880
			identifiers.push( u );
M
Mr.doob 已提交
5881

5882
		}
M
Mr.doob 已提交
5883

5884
		cacheUniformLocations( program, identifiers );
M
Mr.doob 已提交
5885

5886
		// cache attributes locations
M
Mr.doob 已提交
5887

5888
		identifiers = [
A
alteredq 已提交
5889

5890 5891
			"position", "normal", "uv", "uv2", "tangent", "color",
			"skinVertexA", "skinVertexB", "skinIndex", "skinWeight"
A
alteredq 已提交
5892

5893
		];
M
Mr.doob 已提交
5894

5895
		for ( i = 0; i < parameters.maxMorphTargets; i ++ ) {
M
Mr.doob 已提交
5896

5897
			identifiers.push( "morphTarget" + i );
M
Mr.doob 已提交
5898

5899
		}
5900

A
alteredq 已提交
5901 5902 5903 5904 5905 5906
		for ( i = 0; i < parameters.maxMorphNormals; i ++ ) {

			identifiers.push( "morphNormal" + i );

		}

5907
		for ( a in attributes ) {
5908

5909
			identifiers.push( a );
5910

5911
		}
5912

5913
		cacheAttributeLocations( program, identifiers );
5914

A
alteredq 已提交
5915
		program.id = _programs_counter ++;
5916

A
alteredq 已提交
5917
		_programs.push( { program: program, code: code, usedTimes: 1 } );
5918

5919
		_this.info.memory.programs = _programs.length;
5920

5921
		return program;
5922

5923
	};
5924

5925
	// Shader parameters cache
5926

5927
	function cacheUniformLocations ( program, identifiers ) {
5928

5929
		var i, l, id;
5930

5931
		for( i = 0, l = identifiers.length; i < l; i ++ ) {
5932

5933 5934
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
5935

5936
		}
M
Mr.doob 已提交
5937

5938
	};
M
Mr.doob 已提交
5939

5940
	function cacheAttributeLocations ( program, identifiers ) {
A
alteredq 已提交
5941

5942
		var i, l, id;
A
alteredq 已提交
5943

5944
		for( i = 0, l = identifiers.length; i < l; i ++ ) {
A
alteredq 已提交
5945

5946 5947
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
A
alteredq 已提交
5948

5949
		}
5950

5951
	};
A
alteredq 已提交
5952

5953
	function getShader ( type, string ) {
A
alteredq 已提交
5954

5955
		var shader;
5956

5957
		if ( type === "fragment" ) {
A
alteredq 已提交
5958

5959
			shader = _gl.createShader( _gl.FRAGMENT_SHADER );
A
alteredq 已提交
5960

5961
		} else if ( type === "vertex" ) {
A
alteredq 已提交
5962

5963
			shader = _gl.createShader( _gl.VERTEX_SHADER );
A
alteredq 已提交
5964

5965
		}
A
alteredq 已提交
5966

5967 5968
		_gl.shaderSource( shader, string );
		_gl.compileShader( shader );
5969

5970
		if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {
5971

5972 5973 5974
			console.error( _gl.getShaderInfoLog( shader ) );
			console.error( string );
			return null;
5975

A
alteredq 已提交
5976 5977
		}

5978 5979
		return shader;

A
alteredq 已提交
5980
	};
5981

5982 5983
	// Textures

5984 5985 5986 5987 5988 5989 5990

	function isPowerOfTwo ( value ) {

		return ( value & ( value - 1 ) ) === 0;

	};

5991
	function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {
5992

5993
		if ( isImagePowerOfTwo ) {
M
Mr.doob 已提交
5994

5995 5996
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
5997

5998 5999
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
6000

6001
		} else {
M
Mr.doob 已提交
6002

6003 6004
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
6005

6006 6007
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
6008

6009
		}
M
Mr.doob 已提交
6010

6011 6012 6013 6014 6015 6016
		if ( _glExtensionTextureFilterAnisotropic ) {

			_gl.texParameterf( textureType, _glExtensionTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, texture.anisotropy );

		}

6017
	};
6018

6019
	this.setTexture = function ( texture, slot ) {
6020

6021
		if ( texture.needsUpdate ) {
A
alteredq 已提交
6022

6023
			if ( ! texture.__webglInit ) {
M
Mr.doob 已提交
6024

6025
				texture.__webglInit = true;
6026
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
6027

M
Mr.doob 已提交
6028 6029
				_this.info.memory.textures ++;

6030
			}
M
Mr.doob 已提交
6031

6032
			_gl.activeTexture( _gl.TEXTURE0 + slot );
6033 6034
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );

6035
			_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
6036 6037
			_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );

6038 6039
			var image = texture.image,
			isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
6040 6041
			glFormat = paramThreeToGL( texture.format ),
			glType = paramThreeToGL( texture.type );
6042

6043 6044
			setTextureParameters( _gl.TEXTURE_2D, texture, isImagePowerOfTwo );

6045
			if ( texture instanceof THREE.DataTexture ) {
6046

6047
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );
M
Mr.doob 已提交
6048

A
alteredq 已提交
6049
			} else {
M
Mr.doob 已提交
6050

6051
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, texture.image );
M
Mr.doob 已提交
6052 6053 6054

			}

6055
			if ( texture.generateMipmaps && isImagePowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
M
Mr.doob 已提交
6056

A
alteredq 已提交
6057
			texture.needsUpdate = false;
6058

6059
			if ( texture.onUpdate ) texture.onUpdate();
6060

6061
		} else {
6062

6063 6064
			_gl.activeTexture( _gl.TEXTURE0 + slot );
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
6065 6066

		}
M
Mr.doob 已提交
6067

6068
	};
M
Mr.doob 已提交
6069

6070 6071 6072 6073 6074 6075 6076 6077 6078 6079
	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.
6080

6081 6082 6083 6084 6085 6086 6087
		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;
6088

6089
		var ctx = canvas.getContext( "2d" );
6090 6091
		ctx.drawImage( image, 0, 0, image.width, image.height, 0, 0, newWidth, newHeight );

6092 6093 6094 6095
		return canvas;

	}

6096
	function setCubeTexture ( texture, slot ) {
6097

6098
		if ( texture.image.length === 6 ) {
6099 6100 6101

			if ( texture.needsUpdate ) {

A
alteredq 已提交
6102
				if ( ! texture.image.__webglTextureCube ) {
6103 6104

					texture.image.__webglTextureCube = _gl.createTexture();
6105

A
alteredq 已提交
6106
				}
6107

A
alteredq 已提交
6108 6109
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
6110

6111
				_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
M
Mr.doob 已提交
6112

6113
				var cubeImage = [];
6114

A
alteredq 已提交
6115
				for ( var i = 0; i < 6; i ++ ) {
6116

6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128
					if ( _this.autoScaleCubemaps ) {

						cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize );

					} else {

						cubeImage[ i ] = texture.image[ i ];

					}

				}

6129 6130
				var image = cubeImage[ 0 ],
				isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
6131 6132
				glFormat = paramThreeToGL( texture.format ),
				glType = paramThreeToGL( texture.type );
6133

6134 6135
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo );

A
alteredq 已提交
6136
				for ( var i = 0; i < 6; i ++ ) {
6137

6138
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
6139

A
alteredq 已提交
6140
				}
6141

M
Mr.doob 已提交
6142 6143 6144 6145 6146
				if ( texture.generateMipmaps && isImagePowerOfTwo ) {

					_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

				}
6147

A
alteredq 已提交
6148
				texture.needsUpdate = false;
6149

6150
				if ( texture.onUpdate ) texture.onUpdate();
6151

A
alteredq 已提交
6152
			} else {
6153

A
alteredq 已提交
6154 6155
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
6156

A
alteredq 已提交
6157
			}
6158

A
alteredq 已提交
6159
		}
6160

A
alteredq 已提交
6161
	};
6162

6163
	function setCubeTextureDynamic ( texture, slot ) {
6164

A
alteredq 已提交
6165 6166
		_gl.activeTexture( _gl.TEXTURE0 + slot );
		_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
6167 6168 6169

	};

6170 6171 6172
	// Render targets

	function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
6173

6174 6175
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
A
alteredq 已提交
6176

6177
	};
M
Mr.doob 已提交
6178

6179
	function setupRenderBuffer ( renderbuffer, renderTarget  ) {
M
Mikael Emtinger 已提交
6180

6181
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
6182

6183
		if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
M
Mr.doob 已提交
6184

6185 6186
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
6187

6188 6189
		/* For some reason this is not working. Defaulting to RGBA4.
		} else if( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
A
alteredq 已提交
6190

6191 6192 6193 6194
			_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 已提交
6195

6196 6197
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
6198

6199
		} else {
A
alteredq 已提交
6200

6201
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
A
alteredq 已提交
6202

6203
		}
A
alteredq 已提交
6204

6205
	};
A
alteredq 已提交
6206

A
alteredq 已提交
6207
	this.setRenderTarget = function ( renderTarget ) {
A
alteredq 已提交
6208

6209
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
A
alteredq 已提交
6210

6211
		if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
A
alteredq 已提交
6212

M
Mr.doob 已提交
6213 6214
			if ( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
			if ( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
A
alteredq 已提交
6215

6216
			renderTarget.__webglTexture = _gl.createTexture();
A
alteredq 已提交
6217

6218
			// Setup texture, create render and frame buffers
6219

6220 6221
			var isTargetPowerOfTwo = isPowerOfTwo( renderTarget.width ) && isPowerOfTwo( renderTarget.height ),
				glFormat = paramThreeToGL( renderTarget.format ),
6222 6223
				glType = paramThreeToGL( renderTarget.type );

6224
			if ( isCube ) {
M
Mr.doob 已提交
6225

6226 6227
				renderTarget.__webglFramebuffer = [];
				renderTarget.__webglRenderbuffer = [];
M
Mikael Emtinger 已提交
6228

6229
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
6230
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, isTargetPowerOfTwo );
A
alteredq 已提交
6231

6232
				for ( var i = 0; i < 6; i ++ ) {
A
alteredq 已提交
6233

6234 6235
					renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
					renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
A
alteredq 已提交
6236

6237
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
A
alteredq 已提交
6238

6239 6240
					setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
					setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
A
alteredq 已提交
6241

6242
				}
6243

6244 6245
				if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

6246
			} else {
6247

6248 6249
				renderTarget.__webglFramebuffer = _gl.createFramebuffer();
				renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
6250

6251
				_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
6252
				setTextureParameters( _gl.TEXTURE_2D, renderTarget, isTargetPowerOfTwo );
6253

6254
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
6255

6256 6257
				setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
				setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
6258

6259 6260
				if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );

M
Mikael Emtinger 已提交
6261
			}
6262

6263
			// Release everything
M
Mr.doob 已提交
6264

A
alteredq 已提交
6265 6266 6267 6268 6269 6270 6271 6272 6273 6274
			if ( isCube ) {

				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

			} else {

				_gl.bindTexture( _gl.TEXTURE_2D, null );

			}

6275 6276
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
6277

6278 6279
		}

6280
		var framebuffer, width, height, vx, vy;
M
Mr.doob 已提交
6281

6282
		if ( renderTarget ) {
M
Mr.doob 已提交
6283

A
alteredq 已提交
6284 6285
			if ( isCube ) {

6286
				framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
A
alteredq 已提交
6287 6288 6289

			} else {

6290
				framebuffer = renderTarget.__webglFramebuffer;
A
alteredq 已提交
6291 6292 6293

			}

6294 6295
			width = renderTarget.width;
			height = renderTarget.height;
M
Mr.doob 已提交
6296

6297 6298 6299
			vx = 0;
			vy = 0;

6300
		} else {
M
Mr.doob 已提交
6301

6302
			framebuffer = null;
6303

6304 6305
			width = _viewportWidth;
			height = _viewportHeight;
6306

6307 6308
			vx = _viewportX;
			vy = _viewportY;
M
Mr.doob 已提交
6309

6310
		}
M
Mr.doob 已提交
6311

6312
		if ( framebuffer !== _currentFramebuffer ) {
M
Mr.doob 已提交
6313

6314
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
6315
			_gl.viewport( vx, vy, width, height );
M
Mr.doob 已提交
6316

6317
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
6318

6319
		}
6320

A
alteredq 已提交
6321 6322 6323
		_currentWidth = width;
		_currentHeight = height;

6324
	};
M
Mr.doob 已提交
6325

6326
	function updateRenderTargetMipmap ( renderTarget ) {
M
Mr.doob 已提交
6327

A
alteredq 已提交
6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340
		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 已提交
6341 6342

	};
6343

6344
	// Fallback filters for non-power-of-2 textures
6345

6346
	function filterFallback ( f ) {
6347

6348
		if ( f === THREE.NearestFilter || f === THREE.NearestMipMapNearestFilter || f === THREE.NearestMipMapLinearFilter ) {
6349

6350
			return _gl.NEAREST;
6351 6352

		}
6353

6354 6355
		return _gl.LINEAR;

6356
	};
6357

6358 6359
	// Map three.js constants to WebGL constants

6360
	function paramThreeToGL ( p ) {
M
Mr.doob 已提交
6361

6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407
		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 已提交
6408

6409
		return 0;
M
Mr.doob 已提交
6410

6411 6412
	};

6413
	// Allocations
6414

6415
	function allocateBones ( object ) {
6416

6417
		if ( _supportsBoneTextures && object.useVertexTexture ) {
6418 6419

			return 1024;
6420

6421
		} else {
6422

6423 6424 6425 6426 6427 6428 6429
			// 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)
6430

6431 6432
			var nVertexUniforms = _gl.getParameter( _gl.MAX_VERTEX_UNIFORM_VECTORS );
			var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );
6433

6434
			var maxBones = nVertexMatrices;
6435

6436
			if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
6437

6438
				maxBones = Math.min( object.bones.length, maxBones );
6439

6440
				if ( maxBones < object.bones.length ) {
6441

6442
					console.warn( "WebGLRenderer: too many bones - " + object.bones.length + ", this GPU supports just " + maxBones + " (try OpenGL instead of ANGLE)" );
6443

6444
				}
6445

6446
			}
6447

6448
			return maxBones;
6449

6450 6451 6452
		}

	};
6453

6454
	function allocateLights ( lights ) {
6455

A
alteredq 已提交
6456
		var l, ll, light, dirLights, pointLights, spotLights, maxDirLights, maxPointLights, maxSpotLights;
6457

A
alteredq 已提交
6458 6459 6460
		dirLights = pointLights = spotLights = maxDirLights = maxPointLights = maxSpotLights = 0;

		for ( l = 0, ll = lights.length; l < ll; l ++ ) {
6461

6462
			light = lights[ l ];
6463

A
alteredq 已提交
6464 6465
			if ( light.onlyShadow ) continue;

6466 6467
			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
			if ( light instanceof THREE.PointLight ) pointLights ++;
A
alteredq 已提交
6468
			if ( light instanceof THREE.SpotLight ) spotLights ++;
6469

6470
		}
6471

A
alteredq 已提交
6472
		if ( ( pointLights + spotLights + dirLights ) <= _maxLights ) {
6473

6474 6475
			maxDirLights = dirLights;
			maxPointLights = pointLights;
A
alteredq 已提交
6476
			maxSpotLights = spotLights;
6477

6478
		} else {
6479

6480 6481
			maxDirLights = Math.ceil( _maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = _maxLights - maxDirLights;
A
alteredq 已提交
6482
			maxSpotLights = maxPointLights; // this is not really correct
6483 6484 6485

		}

A
alteredq 已提交
6486
		return { 'directional' : maxDirLights, 'point' : maxPointLights, 'spot': maxSpotLights };
6487 6488

	};
M
Mr.doob 已提交
6489

6490
	function allocateShadows ( lights ) {
6491

M
Mr.doob 已提交
6492
		var l, ll, light, maxShadows = 0;
6493 6494 6495 6496 6497

		for ( l = 0, ll = lights.length; l < ll; l++ ) {

			light = lights[ l ];

A
alteredq 已提交
6498 6499
			if ( ! light.castShadow ) continue;

6500 6501
			if ( light instanceof THREE.SpotLight ) maxShadows ++;
			if ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) maxShadows ++;
6502 6503 6504 6505 6506 6507 6508

		}

		return maxShadows;

	};

6509
	// Initialization
M
Mr.doob 已提交
6510

6511 6512 6513 6514
	function initGL () {

		try {

6515
			if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { alpha: _alpha, premultipliedAlpha: _premultipliedAlpha, antialias: _antialias, stencil: _stencil, preserveDrawingBuffer: _preserveDrawingBuffer } ) ) ) {
6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526

				throw 'Error creating WebGL context.';

			}

		} catch ( error ) {

			console.error( error );

		}

6527 6528 6529
		_glExtensionTextureFloat = _gl.getExtension( 'OES_texture_float' );

		if ( ! _glExtensionTextureFloat ) {
6530 6531 6532 6533 6534

			console.log( 'THREE.WebGLRenderer: Float textures not supported.' );

		}

6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548
		_glExtensionTextureFilterAnisotropic = _gl.getExtension( 'EXT_texture_filter_anisotropic' ) ||
											   _gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) ||
											   _gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );

		if ( ! _glExtensionTextureFilterAnisotropic ) {

			console.log( 'THREE.WebGLRenderer: Anisotropic texture filtering not supported.' );

		} else {



		}

6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571
	};

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

	};

6572 6573
	// default plugins (order is important)

A
alteredq 已提交
6574 6575 6576 6577 6578
	this.shadowMapPlugin = new THREE.ShadowMapPlugin();
	this.addPrePlugin( this.shadowMapPlugin );

	this.addPostPlugin( new THREE.SpritePlugin() );
	this.addPostPlugin( new THREE.LensFlarePlugin() );
6579

6580
};