WebGLRenderer.js 163.4 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 117
	_usedTextureUnits = 0,

118
	// GL state cache
119

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

123
	_oldBlending = -1,
124

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

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

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

136
	_oldLineWidth = null,
137

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

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

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

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

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

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

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

158 159
	_direction = new THREE.Vector3(),

160 161
	_lightsNeedUpdate = true,

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

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

170
	};
M
Mr.doob 已提交
171

172
	// initialize
M
Mikael Emtinger 已提交
173

174
	var _gl;
A
alteredq 已提交
175

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

	initGL();
M
Mikael Emtinger 已提交
182

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

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

187 188
	// GPU capabilities

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

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

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

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

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

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

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

207
	};
M
Mr.doob 已提交
208

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

211
		return _supportsVertexTextures;
M
Mikael Emtinger 已提交
212

213
	};
M
Mikael Emtinger 已提交
214

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

		return _maxAnisotropy;

	};

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

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

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

	};
N
Nicolas Garcia Belmonte 已提交
229

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

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

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

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

N
Nicolas Garcia Belmonte 已提交
240
	};
241

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

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

246
	};
247

248
	this.enableScissorTest = function ( enable ) {
249

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

	};
253

254 255
	// Clearing

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

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

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

263
	};
A
alteredq 已提交
264

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

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

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

	};
273

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

		return _clearColor;

	};

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

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

	};

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

		var bits = 0;

290 291 292
		if ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;
		if ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;
		if ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;
M
Mr.doob 已提交
293 294

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

	};

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

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

	};

305 306
	// Plugins

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

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

	};

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

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

	};
320

321 322
	// Deallocation

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

		if ( ! object.__webglInit ) return;

		object.__webglInit = false;

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

		delete object._normalMatrixArray;
		delete object._modelViewMatrixArray;
334
		delete object._modelMatrixArray;
335 336 337

		if ( object instanceof THREE.Mesh ) {

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

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

369 370
	};

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

		}

	};

458
	// Rendering
459

460
	this.updateShadowMap = function ( scene, camera ) {
461

A
alteredq 已提交
462 463 464 465 466 467
		_currentProgram = null;
		_oldBlending = -1;
		_oldDepthTest = -1;
		_oldDepthWrite = -1;
		_currentGeometryGroupHash = -1;
		_currentMaterialId = -1;
468 469 470
		_lightsNeedUpdate = true;
		_oldDoubleSided = -1;
		_oldFlipSided = -1;
A
alteredq 已提交
471 472

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

474
	};
M
Mr.doob 已提交
475

476
	// Internal functions
477

478
	// Buffer allocation
479

480
	function createParticleBuffers ( geometry ) {
481

482 483
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
484

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

487
	};
488

489
	function createLineBuffers ( geometry ) {
490

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

494
		_this.info.memory.geometries ++;
495

496
	};
497

498
	function createRibbonBuffers ( geometry ) {
499

500 501
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
502

503
		_this.info.memory.geometries ++;
M
Mr.doob 已提交
504

505
	};
506

507
	function createMeshBuffers ( geometryGroup ) {
508

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

516 517
		geometryGroup.__webglSkinIndicesBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinWeightsBuffer = _gl.createBuffer();
518

519 520
		geometryGroup.__webglFaceBuffer = _gl.createBuffer();
		geometryGroup.__webglLineBuffer = _gl.createBuffer();
521

522
		var m, ml;
523

524
		if ( geometryGroup.numMorphTargets ) {
525

526
			geometryGroup.__webglMorphTargetsBuffers = [];
527

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

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

			}

		}

		if ( geometryGroup.numMorphNormals ) {

			geometryGroup.__webglMorphNormalsBuffers = [];

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

A
alteredq 已提交
542
				geometryGroup.__webglMorphNormalsBuffers.push( _gl.createBuffer() );
543

544
			}
545

546
		}
547

548
		_this.info.memory.geometries ++;
549

550
	};
551

552
	// Buffer deallocation
553

554
	function deleteParticleBuffers ( geometry ) {
555

556 557
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
558

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

561
	};
562

563
	function deleteLineBuffers ( geometry ) {
564

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

M
Mr.doob 已提交
568 569
		_this.info.memory.geometries --;

570 571
	};

572
	function deleteRibbonBuffers ( geometry ) {
573 574 575 576

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

M
Mr.doob 已提交
577 578
		_this.info.memory.geometries --;

579 580
	};

581
	function deleteMeshBuffers ( geometryGroup ) {
582 583 584 585 586 587 588 589 590 591 592 593 594 595

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

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

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

596 597
		var m, ml;

598 599
		if ( geometryGroup.numMorphTargets ) {

600
			for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
601 602

				_gl.deleteBuffer( geometryGroup.__webglMorphTargetsBuffers[ m ] );
603 604 605 606 607 608 609 610 611

			}

		}

		if ( geometryGroup.numMorphNormals ) {

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

A
alteredq 已提交
612
				_gl.deleteBuffer( geometryGroup.__webglMorphNormalsBuffers[ m ] );
613 614 615 616 617

			}

		}

618 619 620 621 622 623 624 625 626 627 628

		if ( geometryGroup.__webglCustomAttributesList ) {

			for ( var id in geometryGroup.__webglCustomAttributesList ) {

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

			}

		}

M
Mr.doob 已提交
629 630
		_this.info.memory.geometries --;

631 632
	};

633
	// Buffer initialization
634

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

637 638
		var nvertices = geometry.vertices.length;

639
		var material = object.material;
640

641
		if ( material.attributes ) {
642

643
			if ( geometry.__webglCustomAttributesList === undefined ) {
644

645
				geometry.__webglCustomAttributesList = [];
646

647
			}
648

649
			for ( var a in material.attributes ) {
650

651
				var attribute = material.attributes[ a ];
652

653
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
654

655
					attribute.__webglInitialized = true;
656

A
alteredq 已提交
657
					var size = 1;		// "f" and "i"
658

659 660 661 662
					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;
663

664
					attribute.size = size;
A
alteredq 已提交
665

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

668 669
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
670

671
					attribute.needsUpdate = true;
672

673
				}
674

675
				geometry.__webglCustomAttributesList.push( attribute );
676

677
			}
678

679
		}
680

681
	};
682

683
	function initParticleBuffers ( geometry, object ) {
A
alteredq 已提交
684 685 686 687 688 689

		var nvertices = geometry.vertices.length;

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

690 691 692
		geometry.__sortArray = [];

		geometry.__webglParticleCount = nvertices;
A
alteredq 已提交
693 694 695 696 697

		initCustomAttributes ( geometry, object );

	};

698
	function initLineBuffers ( geometry, object ) {
A
alteredq 已提交
699 700 701 702 703 704

		var nvertices = geometry.vertices.length;

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

705
		geometry.__webglLineCount = nvertices;
A
alteredq 已提交
706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721

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

724 725 726
		var geometry = object.geometry,
			faces3 = geometryGroup.faces3,
			faces4 = geometryGroup.faces4,
M
Mr.doob 已提交
727

728 729 730
			nvertices = faces3.length * 3 + faces4.length * 4,
			ntris     = faces3.length * 1 + faces4.length * 2,
			nlines    = faces3.length * 3 + faces4.length * 4,
731

732
			material = getBufferMaterial( object, geometryGroup ),
733

734 735 736
			uvType = bufferGuessUVType( material ),
			normalType = bufferGuessNormalType( material ),
			vertexColorType = bufferGuessVertexColorType( material );
A
alteredq 已提交
737

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

740
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
741

742
		if ( normalType ) {
M
Mr.doob 已提交
743

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

746
		}
747

748
		if ( geometry.hasTangents ) {
749

750
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
751

752
		}
753

754
		if ( vertexColorType ) {
755

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

758
		}
M
Mr.doob 已提交
759

760
		if ( uvType ) {
761

762
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
763

764 765 766 767 768
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

770 771 772 773 774 775 776 777 778 779 780 781 782
				geometryGroup.__uv2Array = new Float32Array( nvertices * 2 );

			}

		}

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

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

		}

783
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
784
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
785

786 787
		var m, ml;

788 789
		if ( geometryGroup.numMorphTargets ) {

M
Mr.doob 已提交
790
			geometryGroup.__morphTargetsArrays = [];
791

792
			for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
793

794
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );
795 796 797 798 799 800 801 802 803 804 805

			}

		}

		if ( geometryGroup.numMorphNormals ) {

			geometryGroup.__morphNormalsArrays = [];

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

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

808 809 810
			}

		}
811

812
		geometryGroup.__webglFaceCount = ntris * 3;
813
		geometryGroup.__webglLineCount = nlines * 2;
814

M
Mr.doob 已提交
815

816
		// custom attributes
M
Mr.doob 已提交
817

818
		if ( material.attributes ) {
819

820
			if ( geometryGroup.__webglCustomAttributesList === undefined ) {
821

822
				geometryGroup.__webglCustomAttributesList = [];
823

824
			}
825

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

828 829
				// Do a shallow copy of the attribute object so different geometryGroup chunks use different
				// attribute buffers which are correctly indexed in the setMeshBuffers function
830

831
				var originalAttribute = material.attributes[ a ];
832

833
				var attribute = {};
834

835
				for ( var property in originalAttribute ) {
M
Mr.doob 已提交
836

837
					attribute[ property ] = originalAttribute[ property ];
838

839
				}
840

A
alteredq 已提交
841
				if ( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
842

843
					attribute.__webglInitialized = true;
844

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

847 848 849 850
					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;
851

852
					attribute.size = size;
A
alteredq 已提交
853

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

856 857
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
858

859 860
					originalAttribute.needsUpdate = true;
					attribute.__original = originalAttribute;
861 862 863

				}

864 865
				geometryGroup.__webglCustomAttributesList.push( attribute );

866
			}
M
Mr.doob 已提交
867

868
		}
869

870 871
		geometryGroup.__inittedArrays = true;

872
	};
M
Mr.doob 已提交
873

874
	function getBufferMaterial( object, geometryGroup ) {
875

876
		if ( object.material && ! ( object.material instanceof THREE.MeshFaceMaterial ) ) {
877

878
			return object.material;
879

880
		} else if ( geometryGroup.materialIndex >= 0 ) {
881

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

884
		}
885

886
	};
M
Mr.doob 已提交
887

888
	function materialNeedsSmoothNormals ( material ) {
889

890
		return material && material.shading !== undefined && material.shading === THREE.SmoothShading;
891

892
	};
M
Mr.doob 已提交
893

894
	function bufferGuessNormalType ( material ) {
895

896
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
897

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

900
			return false;
901

902
		}
903

904
		if ( materialNeedsSmoothNormals( material ) ) {
905

906
			return THREE.SmoothShading;
M
Mr.doob 已提交
907

908
		} else {
909

910
			return THREE.FlatShading;
911

912
		}
913

914
	};
915

916
	function bufferGuessVertexColorType ( material ) {
917

918
		if ( material.vertexColors ) {
919

920
			return material.vertexColors;
921

922
		}
M
Mr.doob 已提交
923

924
		return false;
M
Mr.doob 已提交
925

926
	};
M
Mr.doob 已提交
927

928
	function bufferGuessUVType ( material ) {
929

930 931
		// material must use some texture to require uvs

932
		if ( material.map || material.lightMap || material.bumpMap || material.normalMap || material.specularMap || material instanceof THREE.ShaderMaterial ) {
933 934 935 936 937 938 939 940 941

			return true;

		}

		return false;

	};

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

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

		}

	};

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

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

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

		if ( object.sortParticles ) {

A
alteredq 已提交
999 1000
			_projScreenMatrixPS.copy( _projScreenMatrix );
			_projScreenMatrixPS.multiplySelf( object.matrixWorld );
1001 1002 1003

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

1004
				vertex = vertices[ v ];
1005 1006

				_vector3.copy( vertex );
A
alteredq 已提交
1007
				_projScreenMatrixPS.multiplyVector3( _vector3 );
1008 1009 1010 1011 1012 1013 1014 1015 1016

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

			}

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

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

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

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

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

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

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

		customAttributes = geometry.__webglCustomAttributesList,

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

		if ( dirtyVertices ) {

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

1320
				vertex = vertices[ v ];
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 1458 1459 1460

				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,

1461
		dirtyVertices = geometry.verticesNeedUpdate,
M
Mr.doob 已提交
1462
		dirtyColors = geometry.colorsNeedUpdate;
1463 1464 1465 1466 1467

		if ( dirtyVertices ) {

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

1468
				vertex = vertices[ v ];
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 1501 1502 1503

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

		}

	};

1504
	function setMeshBuffers( geometryGroup, object, hint, dispose, material ) {
1505 1506 1507 1508 1509 1510 1511 1512

		if ( ! geometryGroup.__inittedArrays ) {

			// console.log( object );
			return;

		}

1513 1514 1515 1516 1517 1518
		var normalType = bufferGuessNormalType( material ),
		vertexColorType = bufferGuessVertexColorType( material ),
		uvType = bufferGuessUVType( material ),

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

1519 1520 1521 1522
		var f, fl, fi, face,
		vertexNormals, faceNormal, normal,
		vertexColors, faceColor,
		vertexTangents,
A
alteredq 已提交
1523
		uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4, n1, n2, n3, n4,
1524 1525 1526 1527 1528 1529 1530 1531
		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 已提交
1532
		nka, chf, faceVertexNormals,
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 1562
		a,

		vertexIndex = 0,

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

		value,

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

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

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

		customAttributes = geometryGroup.__webglCustomAttributesList,
		customAttribute,

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

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

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

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

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

		obj_colors = geometry.colors,

		obj_skinIndices = geometry.skinIndices,
		obj_skinWeights = geometry.skinWeights,

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

		if ( dirtyVertices ) {

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

				face = obj_faces[ chunk_faces3[ f ] ];

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

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

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

1621
			}
1622

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

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

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

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

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

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

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

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

A
alteredq 已提交
1650
			}
1651

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

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

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

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

1661
				offset_morphTarget = 0;
1662

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

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

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

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

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

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

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

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

A
alteredq 已提交
1688 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
					// 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;

					}

					//

1726
					offset_morphTarget += 9;
1727

1728
				}
1729

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

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

					// morph positions
1736

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

1742
					vka = morphTargetsArrays[ vk ];
1743

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

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

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

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

A
alteredq 已提交
1760 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
					// 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;

					}

					//

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

1806
				}
A
alteredq 已提交
1807 1808 1809

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

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

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

				}

1818
			}
1819

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

		if ( obj_skinWeights.length ) {

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

				face = obj_faces[ chunk_faces3[ f ]	];
1827

1828
				// weights
A
alteredq 已提交
1829

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

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

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

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

1849
				// indices
A
alteredq 已提交
1850

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

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

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

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

1870
				offset_skin += 12;
1871

1872
			}
1873

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

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

A
alteredq 已提交
1878
				// weights
1879

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

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

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

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

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

A
alteredq 已提交
1905
				// indices
1906

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

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

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

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

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

A
alteredq 已提交
1932
				offset_skin += 16;
M
Mr.doob 已提交
1933

A
alteredq 已提交
1934
			}
M
Mr.doob 已提交
1935

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

A
alteredq 已提交
1938 1939 1940 1941 1942
				_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 );
1943

1944
			}
1945

A
alteredq 已提交
1946
		}
M
Mr.doob 已提交
1947

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

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

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

A
alteredq 已提交
1954 1955
				vertexColors = face.vertexColors;
				faceColor = face.color;
1956

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

A
alteredq 已提交
1959 1960 1961
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
1962

A
alteredq 已提交
1963
				} else {
1964

A
alteredq 已提交
1965 1966 1967
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
1968

A
alteredq 已提交
1969
				}
1970

A
alteredq 已提交
1971 1972 1973
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
1974

A
alteredq 已提交
1975 1976 1977
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
1978

A
alteredq 已提交
1979 1980 1981
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
1982

A
alteredq 已提交
1983
				offset_color += 9;
M
Mr.doob 已提交
1984

A
alteredq 已提交
1985
			}
M
Mr.doob 已提交
1986

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

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

A
alteredq 已提交
1991 1992
				vertexColors = face.vertexColors;
				faceColor = face.color;
M
Mr.doob 已提交
1993

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

A
alteredq 已提交
1996 1997 1998 1999
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
					c4 = vertexColors[ 3 ];
2000

A
alteredq 已提交
2001
				} else {
M
Mr.doob 已提交
2002

A
alteredq 已提交
2003 2004 2005 2006
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
					c4 = faceColor;
M
Mr.doob 已提交
2007

A
alteredq 已提交
2008
				}
2009

A
alteredq 已提交
2010 2011 2012
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
2013

A
alteredq 已提交
2014 2015 2016
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
M
Mr.doob 已提交
2017

A
alteredq 已提交
2018 2019 2020
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
M
Mr.doob 已提交
2021

A
alteredq 已提交
2022 2023 2024
				colorArray[ offset_color + 9 ]  = c4.r;
				colorArray[ offset_color + 10 ] = c4.g;
				colorArray[ offset_color + 11 ] = c4.b;
M
Mr.doob 已提交
2025

A
alteredq 已提交
2026
				offset_color += 12;
2027

2028
			}
2029

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

A
alteredq 已提交
2032 2033
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
M
Mr.doob 已提交
2034

2035
			}
2036

A
alteredq 已提交
2037
		}
M
Mr.doob 已提交
2038

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

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

A
alteredq 已提交
2043
				face = obj_faces[ chunk_faces3[ f ]	];
2044

A
alteredq 已提交
2045
				vertexTangents = face.vertexTangents;
M
Mr.doob 已提交
2046

A
alteredq 已提交
2047 2048 2049
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
2050

A
alteredq 已提交
2051 2052 2053 2054
				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 已提交
2055

A
alteredq 已提交
2056 2057 2058 2059
				tangentArray[ offset_tangent + 4 ] = t2.x;
				tangentArray[ offset_tangent + 5 ] = t2.y;
				tangentArray[ offset_tangent + 6 ] = t2.z;
				tangentArray[ offset_tangent + 7 ] = t2.w;
2060

A
alteredq 已提交
2061 2062 2063 2064
				tangentArray[ offset_tangent + 8 ]  = t3.x;
				tangentArray[ offset_tangent + 9 ]  = t3.y;
				tangentArray[ offset_tangent + 10 ] = t3.z;
				tangentArray[ offset_tangent + 11 ] = t3.w;
2065

A
alteredq 已提交
2066
				offset_tangent += 12;
2067

2068
			}
2069

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

A
alteredq 已提交
2072
				face = obj_faces[ chunk_faces4[ f ] ];
2073

A
alteredq 已提交
2074
				vertexTangents = face.vertexTangents;
2075

A
alteredq 已提交
2076 2077 2078 2079
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
				t4 = vertexTangents[ 3 ];
2080

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

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

A
alteredq 已提交
2091 2092 2093 2094
				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 已提交
2095

A
alteredq 已提交
2096 2097 2098 2099
				tangentArray[ offset_tangent + 12 ] = t4.x;
				tangentArray[ offset_tangent + 13 ] = t4.y;
				tangentArray[ offset_tangent + 14 ] = t4.z;
				tangentArray[ offset_tangent + 15 ] = t4.w;
2100

A
alteredq 已提交
2101
				offset_tangent += 16;
2102

A
alteredq 已提交
2103
			}
2104

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

A
alteredq 已提交
2108
		}
2109

A
alteredq 已提交
2110
		if ( dirtyNormals && normalType ) {
2111

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

A
alteredq 已提交
2114
				face = obj_faces[ chunk_faces3[ f ]	];
2115

A
alteredq 已提交
2116 2117
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
2118

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

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

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

A
alteredq 已提交
2125 2126 2127
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
2128

A
alteredq 已提交
2129
						offset_normal += 3;
2130

A
alteredq 已提交
2131
					}
2132

A
alteredq 已提交
2133
				} else {
M
Mr.doob 已提交
2134

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

A
alteredq 已提交
2137 2138 2139
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
2140

A
alteredq 已提交
2141
						offset_normal += 3;
M
Mr.doob 已提交
2142

A
alteredq 已提交
2143
					}
2144

A
alteredq 已提交
2145
				}
2146

A
alteredq 已提交
2147
			}
2148

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

A
alteredq 已提交
2151
				face = obj_faces[ chunk_faces4[ f ] ];
2152

A
alteredq 已提交
2153 2154
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
2155

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

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

A
alteredq 已提交
2160
						vn = vertexNormals[ i ];
2161

A
alteredq 已提交
2162 2163 2164
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
2165

A
alteredq 已提交
2166
						offset_normal += 3;
2167

A
alteredq 已提交
2168
					}
M
Mr.doob 已提交
2169

A
alteredq 已提交
2170
				} else {
2171

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

A
alteredq 已提交
2174 2175 2176
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
2177

A
alteredq 已提交
2178
						offset_normal += 3;
M
Mr.doob 已提交
2179

A
alteredq 已提交
2180
					}
2181

A
alteredq 已提交
2182
				}
2183

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

A
alteredq 已提交
2186 2187
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
2188

A
alteredq 已提交
2189
		}
M
Mr.doob 已提交
2190

A
alteredq 已提交
2191
		if ( dirtyUvs && obj_uvs && uvType ) {
2192

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

A
alteredq 已提交
2195
				fi = chunk_faces3[ f ];
2196

A
alteredq 已提交
2197
				uv = obj_uvs[ fi ];
2198

A
alteredq 已提交
2199
				if ( uv === undefined ) continue;
2200

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

A
alteredq 已提交
2203
					uvi = uv[ i ];
2204

A
alteredq 已提交
2205 2206
					uvArray[ offset_uv ]     = uvi.u;
					uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
2207

A
alteredq 已提交
2208
					offset_uv += 2;
M
Mr.doob 已提交
2209

A
alteredq 已提交
2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229
				}

			}

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

				fi = chunk_faces4[ f ];

				uv = obj_uvs[ fi ];

				if ( uv === undefined ) continue;

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

					uvi = uv[ i ];

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

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

2231 2232
				}

2233
			}
2234

A
alteredq 已提交
2235
			if ( offset_uv > 0 ) {
2236

A
alteredq 已提交
2237 2238
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
2239

A
alteredq 已提交
2240
			}
2241

A
alteredq 已提交
2242
		}
2243

A
alteredq 已提交
2244
		if ( dirtyUvs && obj_uvs2 && uvType ) {
2245

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

A
alteredq 已提交
2248
				fi = chunk_faces3[ f ];
2249

A
alteredq 已提交
2250
				uv2 = obj_uvs2[ fi ];
2251

A
alteredq 已提交
2252 2253 2254 2255 2256 2257 2258 2259 2260 2261
				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;
2262

2263 2264
				}

A
alteredq 已提交
2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284
			}

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

				fi = chunk_faces4[ f ];

				uv2 = obj_uvs2[ fi ];

				if ( uv2 === undefined ) continue;

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

					uv2i = uv2[ i ];

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

					offset_uv2 += 2;

				}
2285

2286
			}
2287

A
alteredq 已提交
2288
			if ( offset_uv2 > 0 ) {
2289

A
alteredq 已提交
2290 2291
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );
2292

A
alteredq 已提交
2293
			}
2294

A
alteredq 已提交
2295
		}
2296

A
alteredq 已提交
2297
		if ( dirtyElements ) {
2298

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

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

A
alteredq 已提交
2305
				offset_face += 3;
2306

A
alteredq 已提交
2307 2308
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2309

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

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

A
alteredq 已提交
2316
				offset_line += 6;
2317

A
alteredq 已提交
2318
				vertexIndex += 3;
2319

A
alteredq 已提交
2320
			}
2321

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

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

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

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

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

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

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

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

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

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

2350
			}
2351

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

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

A
alteredq 已提交
2358
		}
2359

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

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

2364
				customAttribute = customAttributes[ i ];
2365

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

2368 2369
				offset_custom = 0;
				offset_customSrc = 0;
2370

2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403
				if ( customAttribute.size === 1 ) {

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

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

							face = obj_faces[ chunk_faces3[ f ]	];

							customAttribute.array[ offset_custom ] 	   = customAttribute.value[ face.a ];
							customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];
							customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];

							offset_custom += 3;

						}

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

							face = obj_faces[ chunk_faces4[ f ] ];

							customAttribute.array[ offset_custom ] 	   = customAttribute.value[ face.a ];
							customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];
							customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];
							customAttribute.array[ offset_custom + 3 ] = customAttribute.value[ face.d ];

							offset_custom += 4;

						}

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

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

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

							customAttribute.array[ offset_custom ] 	   = value;
							customAttribute.array[ offset_custom + 1 ] = value;
							customAttribute.array[ offset_custom + 2 ] = value;

							offset_custom += 3;

						}

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

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

							customAttribute.array[ offset_custom ] 	   = value;
							customAttribute.array[ offset_custom + 1 ] = value;
							customAttribute.array[ offset_custom + 2 ] = value;
							customAttribute.array[ offset_custom + 3 ] = value;

							offset_custom += 4;

						}
2426

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

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

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

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

							face = obj_faces[ chunk_faces3[ f ]	];

							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];

							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;

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

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

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

2452
						}
A
alteredq 已提交
2453

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

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

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

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

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

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

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

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

2477
						}
A
alteredq 已提交
2478

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

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

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

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

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

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

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

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

2500
						}
A
alteredq 已提交
2501

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

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

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

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

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

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

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

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

2525
						}
M
Mr.doob 已提交
2526

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

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

2531
					var pp;
2532

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

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

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

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

2541
					}
2542

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

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

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

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

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

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

2561 2562 2563
							customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
M
Mr.doob 已提交
2564

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

2567
						}
M
Mr.doob 已提交
2568

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

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

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

2578 2579 2580
							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
M
Mr.doob 已提交
2581

2582 2583 2584
							customAttribute.array[ offset_custom + 3  ] = v2[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 4  ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5  ] = v2[ pp[ 2 ] ];
M
Mr.doob 已提交
2585

2586 2587 2588
							customAttribute.array[ offset_custom + 6  ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7  ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8  ] = v3[ pp[ 2 ] ];
M
Mr.doob 已提交
2589

2590 2591 2592
							customAttribute.array[ offset_custom + 9  ] = v4[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];
M
Mr.doob 已提交
2593

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

2596
						}
M
Mr.doob 已提交
2597

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

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

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

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

2608 2609 2610
							customAttribute.array[ offset_custom ] 	   = v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
M
Mr.doob 已提交
2611

2612 2613 2614
							customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
M
Mr.doob 已提交
2615

2616 2617 2618
							customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
M
Mr.doob 已提交
2619

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

2622
						}
2623

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

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

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

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

2637
							customAttribute.array[ offset_custom + 3  ] = v2[ pp[ 0 ] ];
2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692
							customAttribute.array[ offset_custom + 4  ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5  ] = v2[ pp[ 2 ] ];

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

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

							offset_custom += 12;

						}

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

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

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

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

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

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

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

							offset_custom += 9;

						}

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

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

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

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

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

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

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

2704
							offset_custom += 12;
2705

2706
						}
2707

A
alteredq 已提交
2708
					}
M
Mr.doob 已提交
2709

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

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

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

2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777
							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 ++ ) {

2778
							value = customAttribute.value[ chunk_faces3[ f ] ];
2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795

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

2799
							offset_custom += 12;
A
alteredq 已提交
2800

2801 2802
						}

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

2805
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2806

2807 2808 2809 2810
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2811

2812 2813 2814 2815
							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;
2816

2817 2818 2819 2820
							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;
2821

2822 2823 2824 2825
							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;
2826

2827 2828 2829 2830
							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;
2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892

							offset_custom += 16;

						}

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

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

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

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

							customAttribute.array[ offset_custom  ] 	= v1.x;
							customAttribute.array[ offset_custom + 1  ] = v1.y;
							customAttribute.array[ offset_custom + 2  ] = v1.z;
							customAttribute.array[ offset_custom + 3  ] = v1.w;

							customAttribute.array[ offset_custom + 4  ] = v2.x;
							customAttribute.array[ offset_custom + 5  ] = v2.y;
							customAttribute.array[ offset_custom + 6  ] = v2.z;
							customAttribute.array[ offset_custom + 7  ] = v2.w;

							customAttribute.array[ offset_custom + 8  ] = v3.x;
							customAttribute.array[ offset_custom + 9  ] = v3.y;
							customAttribute.array[ offset_custom + 10 ] = v3.z;
							customAttribute.array[ offset_custom + 11 ] = v3.w;

							offset_custom += 12;

						}

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

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

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

							customAttribute.array[ offset_custom  ] 	= v1.x;
							customAttribute.array[ offset_custom + 1  ] = v1.y;
							customAttribute.array[ offset_custom + 2  ] = v1.z;
							customAttribute.array[ offset_custom + 3  ] = v1.w;

							customAttribute.array[ offset_custom + 4  ] = v2.x;
							customAttribute.array[ offset_custom + 5  ] = v2.y;
							customAttribute.array[ offset_custom + 6  ] = v2.z;
							customAttribute.array[ offset_custom + 7  ] = v2.w;

							customAttribute.array[ offset_custom + 8  ] = v3.x;
							customAttribute.array[ offset_custom + 9  ] = v3.y;
							customAttribute.array[ offset_custom + 10 ] = v3.z;
							customAttribute.array[ offset_custom + 11 ] = v3.w;

							customAttribute.array[ offset_custom + 12 ] = v4.x;
							customAttribute.array[ offset_custom + 13 ] = v4.y;
							customAttribute.array[ offset_custom + 14 ] = v4.z;
							customAttribute.array[ offset_custom + 15 ] = v4.w;
2893

2894
							offset_custom += 16;
A
alteredq 已提交
2895

2896
						}
A
alteredq 已提交
2897 2898 2899 2900 2901

					}

				}

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

A
alteredq 已提交
2905 2906 2907 2908
			}

		}

2909
		if ( dispose ) {
2910

2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921
			delete geometryGroup.__inittedArrays;
			delete geometryGroup.__colorArray;
			delete geometryGroup.__normalArray;
			delete geometryGroup.__tangentArray;
			delete geometryGroup.__uvArray;
			delete geometryGroup.__uv2Array;
			delete geometryGroup.__faceArray;
			delete geometryGroup.__vertexArray;
			delete geometryGroup.__lineArray;
			delete geometryGroup.__skinIndexArray;
			delete geometryGroup.__skinWeightArray;
A
alteredq 已提交
2922

2923
		}
A
alteredq 已提交
2924

2925
	};
A
alteredq 已提交
2926

2927 2928
	function setDirectBuffers ( geometry, hint, dispose ) {

2929
		var attributes = geometry.attributes;
2930

2931 2932 2933 2934 2935
		var index = attributes[ "index" ];
		var position = attributes[ "position" ];
		var normal = attributes[ "normal" ];
		var uv = attributes[ "uv" ];
		var color = attributes[ "color" ];
2936
		var tangent = attributes[ "tangent" ];
2937 2938 2939 2940 2941

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

			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, index.array, hint );
2942 2943 2944

		}

2945
		if ( geometry.verticesNeedUpdate && position !== undefined ) {
2946

2947 2948
			_gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, position.array, hint );
2949 2950 2951

		}

2952
		if ( geometry.normalsNeedUpdate && normal !== undefined ) {
2953

2954 2955
			_gl.bindBuffer( _gl.ARRAY_BUFFER, normal.buffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, normal.array, hint );
2956 2957 2958

		}

2959
		if ( geometry.uvsNeedUpdate && uv !== undefined ) {
2960

2961 2962
			_gl.bindBuffer( _gl.ARRAY_BUFFER, uv.buffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, uv.array, hint );
2963 2964 2965

		}

2966
		if ( geometry.colorsNeedUpdate && color !== undefined ) {
2967

2968 2969
			_gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, color.array, hint );
2970 2971 2972

		}

2973 2974 2975 2976 2977 2978
		if ( geometry.tangentsNeedUpdate && tangent !== undefined ) {

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

		}
2979 2980 2981

		if ( dispose ) {

2982 2983 2984 2985 2986
			for ( var i in geometry.attributes ) {

				delete geometry.attributes[ i ].array;

			}
2987 2988 2989 2990 2991

		}

	};

2992
	// Buffer rendering
A
alteredq 已提交
2993

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

2996 2997 2998
		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();
2999
		if ( object.hasColors && ! object.__webglColorBuffer ) object.__webglColorBuffer = _gl.createBuffer();
A
alteredq 已提交
3000

3001
		if ( object.hasPositions ) {
A
alteredq 已提交
3002

3003 3004 3005 3006
			_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 已提交
3007 3008 3009

		}

3010
		if ( object.hasNormals ) {
A
alteredq 已提交
3011

3012
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
A
alteredq 已提交
3013

3014
			if ( material.shading === THREE.FlatShading ) {
3015

3016 3017 3018 3019
				var nx, ny, nz,
					nax, nbx, ncx, nay, nby, ncy, naz, nbz, ncz,
					normalArray,
					i, il = object.count * 3;
3020

3021
				for( i = 0; i < il; i += 9 ) {
3022

3023
					normalArray = object.normalArray;
3024

3025 3026 3027
					nax  = normalArray[ i ];
					nay  = normalArray[ i + 1 ];
					naz  = normalArray[ i + 2 ];
3028

3029 3030 3031
					nbx  = normalArray[ i + 3 ];
					nby  = normalArray[ i + 4 ];
					nbz  = normalArray[ i + 5 ];
3032

3033 3034 3035
					ncx  = normalArray[ i + 6 ];
					ncy  = normalArray[ i + 7 ];
					ncz  = normalArray[ i + 8 ];
3036

3037 3038 3039
					nx = ( nax + nbx + ncx ) / 3;
					ny = ( nay + nby + ncy ) / 3;
					nz = ( naz + nbz + ncz ) / 3;
3040

3041 3042 3043
					normalArray[ i ] 	 = nx;
					normalArray[ i + 1 ] = ny;
					normalArray[ i + 2 ] = nz;
3044

3045 3046 3047
					normalArray[ i + 3 ] = nx;
					normalArray[ i + 4 ] = ny;
					normalArray[ i + 5 ] = nz;
3048

3049 3050 3051
					normalArray[ i + 6 ] = nx;
					normalArray[ i + 7 ] = ny;
					normalArray[ i + 8 ] = nz;
3052

3053
				}
3054

3055
			}
3056

3057 3058 3059
			_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 );
3060

3061
		}
3062

3063
		if ( object.hasUvs && material.map ) {
3064 3065 3066 3067 3068 3069 3070 3071

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

		}

3072 3073 3074 3075 3076 3077 3078 3079 3080
		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 );

		}

3081
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );
3082

3083
		object.count = 0;
3084

3085
	};
3086

3087
	this.renderBufferDirect = function ( camera, lights, fog, material, geometry, object ) {
3088

3089 3090
		if ( material.visible === false ) return;

3091
		var program, attributes, linewidth, primitives, a, attribute;
3092 3093 3094 3095 3096 3097 3098

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

		attributes = program.attributes;

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

3101
		if ( geometryHash !== _currentGeometryGroupHash ) {
3102

3103
			_currentGeometryGroupHash = geometryHash;
3104 3105 3106 3107 3108 3109 3110 3111
			updateBuffers = true;

		}

		// render mesh

		if ( object instanceof THREE.Mesh ) {

3112
			var offsets = geometry.offsets;
3113

3114
			// if there is more than 1 chunk
3115
			// must set attribute pointers to use new offsets for each chunk
3116 3117 3118 3119
			// even if geometry and materials didn't change

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

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

3122 3123
				var startIndex = offsets[ i ].index;

3124 3125 3126 3127
				if ( updateBuffers ) {

					// vertices

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

3131 3132
					_gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
					_gl.vertexAttribPointer( attributes.position, positionSize, _gl.FLOAT, false, 0, startIndex * positionSize * 4 ); // 4 bytes per Float32
3133 3134 3135

					// normals

3136
					var normal = geometry.attributes[ "normal" ];
3137

3138
					if ( attributes.normal >= 0 && normal ) {
3139

3140 3141 3142 3143
						var normalSize = normal.itemSize;

						_gl.bindBuffer( _gl.ARRAY_BUFFER, normal.buffer );
						_gl.vertexAttribPointer( attributes.normal, normalSize, _gl.FLOAT, false, 0, startIndex * normalSize * 4 );
3144 3145 3146 3147 3148

					}

					// uvs

3149 3150 3151
					var uv = geometry.attributes[ "uv" ];

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

3153
						if ( uv.buffer ) {
3154

3155
							var uvSize = uv.itemSize;
3156

3157 3158
							_gl.bindBuffer( _gl.ARRAY_BUFFER, uv.buffer );
							_gl.vertexAttribPointer( attributes.uv, uvSize, _gl.FLOAT, false, 0, startIndex * uvSize * 4 );
3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171

							_gl.enableVertexAttribArray( attributes.uv );

						} else {

							_gl.disableVertexAttribArray( attributes.uv );

						}

					}

					// colors

3172 3173 3174
					var color = geometry.attributes[ "color" ];

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

3176
						var colorSize = color.itemSize;
3177

3178 3179
						_gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
						_gl.vertexAttribPointer( attributes.color, colorSize, _gl.FLOAT, false, 0, startIndex * colorSize * 4 );
3180

3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192
					}

					// 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 );
3193 3194 3195

					}

3196 3197 3198 3199 3200
					// indices

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

					_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
3201 3202 3203 3204 3205

				}

				// render indexed triangles

3206
				_gl.drawElements( _gl.TRIANGLES, offsets[ i ].count, _gl.UNSIGNED_SHORT, offsets[ i ].start * 2 ); // 2 bytes per Uint16
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;

			}

3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249
		// render particles

		} else if ( object instanceof THREE.ParticleSystem ) {

			if ( updateBuffers ) {

				// vertices

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

				_gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
				_gl.vertexAttribPointer( attributes.position, positionSize, _gl.FLOAT, false, 0, 0 );

				// colors

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

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

					var colorSize = color.itemSize;

					_gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
					_gl.vertexAttribPointer( attributes.color, colorSize, _gl.FLOAT, false, 0, 0 );

				}

				// render particles

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

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

			}

3250 3251 3252 3253
		}

	};

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

3256 3257
		if ( material.visible === false ) return;

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

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

3262
		attributes = program.attributes;
3263

3264 3265 3266
		var updateBuffers = false,
			wireframeBit = material.wireframe ? 1 : 0,
			geometryGroupHash = ( geometryGroup.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit;
3267

3268
		if ( geometryGroupHash !== _currentGeometryGroupHash ) {
A
alteredq 已提交
3269

3270 3271
			_currentGeometryGroupHash = geometryGroupHash;
			updateBuffers = true;
3272

3273
		}
3274

3275
		// vertices
3276

3277
		if ( !material.morphTargets && attributes.position >= 0 ) {
3278

3279
			if ( updateBuffers ) {
3280

3281 3282
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
				_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3283

3284
			}
3285

3286
		} else {
3287

3288
			if ( object.morphTargetBase ) {
3289

3290
				setupMorphTargets( material, geometryGroup, object );
3291

3292
			}
3293

3294
		}
3295

3296

3297
		if ( updateBuffers ) {
3298

3299
			// custom attributes
3300

3301
			// Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
3302

3303
			if ( geometryGroup.__webglCustomAttributesList ) {
3304

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

3307
					attribute = geometryGroup.__webglCustomAttributesList[ i ];
3308

3309
					if( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
3310

3311 3312
						_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
						_gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 );
3313

3314
					}
3315

3316
				}
3317

3318
			}
3319 3320


3321
			// colors
3322

3323
			if ( attributes.color >= 0 ) {
3324

3325 3326
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
3327

3328
			}
3329

3330
			// normals
3331

3332
			if ( attributes.normal >= 0 ) {
3333

3334 3335
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
				_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
3336

3337
			}
3338

3339
			// tangents
3340

3341
			if ( attributes.tangent >= 0 ) {
3342

3343 3344
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
				_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
3345

3346
			}
3347

3348
			// uvs
3349

3350
			if ( attributes.uv >= 0 ) {
3351

3352
				if ( geometryGroup.__webglUVBuffer ) {
3353

3354 3355
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
					_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
3356

3357
					_gl.enableVertexAttribArray( attributes.uv );
3358

3359
				} else {
3360

3361
					_gl.disableVertexAttribArray( attributes.uv );
3362 3363 3364 3365 3366

				}

			}

3367
			if ( attributes.uv2 >= 0 ) {
3368

3369
				if ( geometryGroup.__webglUV2Buffer ) {
3370

3371 3372
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
					_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
3373

3374
					_gl.enableVertexAttribArray( attributes.uv2 );
3375

3376
				} else {
3377

3378
					_gl.disableVertexAttribArray( attributes.uv2 );
3379 3380

				}
3381 3382

			}
3383

3384 3385
			if ( material.skinning &&
				 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
A
alteredq 已提交
3386

3387 3388
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
				_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3389

3390 3391
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
				_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
3392

A
alteredq 已提交
3393
			}
3394

3395
		}
3396

3397
		// render mesh
3398

3399
		if ( object instanceof THREE.Mesh ) {
3400

3401
			// wireframe
3402

3403
			if ( material.wireframe ) {
3404

3405
				setLineWidth( material.wireframeLinewidth );
3406

3407 3408
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
3409

3410
			// triangles
3411

3412
			} else {
3413

3414 3415
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3416

3417
			}
3418

3419 3420 3421
			_this.info.render.calls ++;
			_this.info.render.vertices += geometryGroup.__webglFaceCount;
			_this.info.render.faces += geometryGroup.__webglFaceCount / 3;
3422

3423
		// render lines
3424

3425
		} else if ( object instanceof THREE.Line ) {
3426

3427
			primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
3428

3429
			setLineWidth( material.linewidth );
3430

3431
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
3432

3433
			_this.info.render.calls ++;
3434

3435
		// render particles
3436

3437
		} else if ( object instanceof THREE.ParticleSystem ) {
3438

3439
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
3440

3441
			_this.info.render.calls ++;
3442
			_this.info.render.points += geometryGroup.__webglParticleCount;
3443

3444
		// render ribbon
3445

3446
		} else if ( object instanceof THREE.Ribbon ) {
3447

3448
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
3449

3450
			_this.info.render.calls ++;
3451

3452
		}
3453

3454
	};
3455

3456
	function setupMorphTargets ( material, geometryGroup, object ) {
3457

3458
		// set base
3459

3460
		var attributes = material.program.attributes;
3461

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

3464 3465
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3466

3467
		} else if ( attributes.position >= 0 ) {
3468

3469 3470
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3471

3472
		}
3473

3474
		if ( object.morphTargetForcedOrder.length ) {
3475

3476
			// set forced order
3477

3478 3479 3480 3481 3482
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;

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

3484 3485 3486
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ order[ m ] ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );

A
alteredq 已提交
3487 3488 3489 3490 3491 3492 3493
				if ( material.morphNormals ) {

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

				}

3494 3495 3496
				object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ] ];

				m ++;
3497 3498
			}

3499 3500
		} else {

A
alteredq 已提交
3501
			// find the most influencing
3502

A
alteredq 已提交
3503
			var influence, activeInfluenceIndices = [];
3504 3505
			var influences = object.morphTargetInfluences;
			var i, il = influences.length;
3506

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

A
alteredq 已提交
3509 3510 3511 3512
				influence = influences[ i ];

				if ( influence > 0 ) {

3513
					activeInfluenceIndices.push( [ i, influence ] );
3514

I
ide user ide_gero3 已提交
3515
				}
A
alteredq 已提交
3516

I
ide user ide_gero3 已提交
3517
			}
A
alteredq 已提交
3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529

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

3530
				activeInfluenceIndices.push( [ 0, 0 ] );
A
alteredq 已提交
3531 3532 3533 3534

			};

			var influenceIndex, m = 0;
3535

3536
			while ( m < material.numSupportedMorphTargets ) {
3537

3538
				if ( activeInfluenceIndices[ m ] ) {
3539 3540 3541

					influenceIndex = activeInfluenceIndices[ m ][ 0 ];

A
alteredq 已提交
3542 3543 3544
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ influenceIndex ] );

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

A
alteredq 已提交
3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557
					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 );
3558

A
alteredq 已提交
3559
					if ( material.morphNormals ) {
3560

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

3563
					}
3564

A
alteredq 已提交
3565 3566
					object.__webglMorphTargetInfluences[ m ] = 0;

3567
				}
A
alteredq 已提交
3568

3569
				m ++;
3570 3571 3572 3573 3574

			}

		}

3575
		// load updated influences uniform
3576

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

3579
			_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
3580

3581
		}
3582

3583
	};
3584

A
alteredq 已提交
3585
	// Sorting
3586

3587
	function painterSort ( a, b ) {
3588

3589
		return b.z - a.z;
3590

3591
	};
3592

3593
	function numericalSort ( a, b ) {
A
alteredq 已提交
3594

3595
		return b[ 1 ] - a[ 1 ];
A
alteredq 已提交
3596 3597 3598 3599

	};


3600
	// Rendering
3601

3602
	this.render = function ( scene, camera, renderTarget, forceClear ) {
3603

M
Mr.doob 已提交
3604 3605 3606 3607 3608 3609 3610
		if ( camera instanceof THREE.Camera === false ) {

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

		}

3611 3612 3613 3614 3615
		var i, il,

		webglObject, object,
		renderList,

3616
		lights = scene.__lights,
3617
		fog = scene.fog;
M
Mr.doob 已提交
3618

3619 3620
		// reset caching for this frame

3621
		_currentMaterialId = -1;
3622
		_lightsNeedUpdate = true;
3623

A
alteredq 已提交
3624
		// update scene graph
3625

3626
		if ( this.autoUpdateScene ) scene.updateMatrixWorld();
3627

A
alteredq 已提交
3628
		// update camera matrices and frustum
A
alteredq 已提交
3629

3630 3631
		if ( camera.parent === undefined ) camera.updateMatrixWorld();

A
alteredq 已提交
3632 3633
		if ( ! camera._viewMatrixArray ) camera._viewMatrixArray = new Float32Array( 16 );
		if ( ! camera._projectionMatrixArray ) camera._projectionMatrixArray = new Float32Array( 16 );
A
alteredq 已提交
3634

3635
		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
A
alteredq 已提交
3636 3637 3638

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

3640
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
A
alteredq 已提交
3641
		_frustum.setFromMatrix( _projScreenMatrix );
3642

A
alteredq 已提交
3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657
		// 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 已提交
3658
		this.setRenderTarget( renderTarget );
3659

3660
		if ( this.autoClear || forceClear ) {
3661

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

3664
		}
M
Mr.doob 已提交
3665

3666
		// set matrices for regular objects (frustum culled)
3667

3668
		renderList = scene.__webglObjects;
3669

3670
		for ( i = 0, il = renderList.length; i < il; i ++ ) {
3671

3672
			webglObject = renderList[ i ];
3673
			object = webglObject.object;
3674

A
alteredq 已提交
3675 3676
			webglObject.render = false;

3677
			if ( object.visible ) {
3678

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

3681
					//object.matrixWorld.flattenToArray( object._modelMatrixArray );
3682

A
alteredq 已提交
3683
					setupMatrices( object, camera );
3684

3685
					unrollBufferMaterial( webglObject );
3686

3687
					webglObject.render = true;
3688

3689
					if ( this.sortObjects === true ) {
3690

3691
						if ( object.renderDepth !== null ) {
3692

3693
							webglObject.z = object.renderDepth;
M
Mr.doob 已提交
3694

3695
						} else {
M
Mr.doob 已提交
3696

3697
							_vector3.copy( object.matrixWorld.getPosition() );
3698
							_projScreenMatrix.multiplyVector3( _vector3 );
3699

3700
							webglObject.z = _vector3.z;
3701

3702
						}
M
Mr.doob 已提交
3703

3704
					}
M
Mr.doob 已提交
3705

3706
				}
3707 3708

			}
3709 3710 3711

		}

3712
		if ( this.sortObjects ) {
M
Mr.doob 已提交
3713

3714
			renderList.sort( painterSort );
3715

3716
		}
3717

3718
		// set matrices for immediate objects
3719

3720
		renderList = scene.__webglObjectsImmediate;
3721

3722 3723 3724
		for ( i = 0, il = renderList.length; i < il; i ++ ) {

			webglObject = renderList[ i ];
3725
			object = webglObject.object;
3726

3727
			if ( object.visible ) {
3728

M
Mr.doob 已提交
3729 3730
				/*
				if ( object.matrixAutoUpdate ) {
3731

3732
					object.matrixWorld.flattenToArray( object._modelMatrixArray );
M
Mr.doob 已提交
3733

3734
				}
M
Mr.doob 已提交
3735
				*/
M
Mr.doob 已提交
3736

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

3739
				unrollImmediateBufferMaterial( webglObject );
M
Mr.doob 已提交
3740

3741
			}
M
Mr.doob 已提交
3742

3743
		}
3744

3745
		if ( scene.overrideMaterial ) {
3746

3747 3748 3749 3750 3751 3752
			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 );
3753

3754 3755
			renderObjects( scene.__webglObjects, false, "", camera, lights, fog, true, material );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "", camera, lights, fog, false, material );
M
Mr.doob 已提交
3756

3757
		} else {
3758

3759
			// opaque pass (front-to-back order)
3760

3761
			this.setBlending( THREE.NormalBlending );
3762

3763 3764
			renderObjects( scene.__webglObjects, true, "opaque", camera, lights, fog, false );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "opaque", camera, lights, fog, false );
3765

3766
			// transparent pass (back-to-front order)
3767

3768 3769
			renderObjects( scene.__webglObjects, false, "transparent", camera, lights, fog, true );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "transparent", camera, lights, fog, true );
3770

3771
		}
3772

A
alteredq 已提交
3773
		// custom render plugins (post pass)
3774

A
alteredq 已提交
3775
		renderPlugins( this.renderPluginsPost, scene, camera );
3776 3777


3778
		// Generate mipmap if we're using any kind of mipmap filtering
3779

3780
		if ( renderTarget && renderTarget.generateMipmaps && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {
3781

3782
			updateRenderTargetMipmap( renderTarget );
3783

3784
		}
3785

3786 3787 3788
		// Ensure depth buffer writing is enabled so it can be cleared on next render

		this.setDepthTest( true );
3789
		this.setDepthWrite( true );
3790

3791
		// _gl.finish();
3792

3793
	};
3794

A
alteredq 已提交
3795 3796 3797 3798 3799 3800
	function renderPlugins( plugins, scene, camera ) {

		if ( ! plugins.length ) return;

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

3801 3802
			// reset state for plugin (to start from clean slate)

A
alteredq 已提交
3803
			_currentProgram = null;
3804
			_currentCamera = null;
3805

A
alteredq 已提交
3806 3807 3808
			_oldBlending = -1;
			_oldDepthTest = -1;
			_oldDepthWrite = -1;
3809 3810
			_oldDoubleSided = -1;
			_oldFlipSided = -1;
A
alteredq 已提交
3811 3812
			_currentGeometryGroupHash = -1;
			_currentMaterialId = -1;
3813

3814
			_lightsNeedUpdate = true;
A
alteredq 已提交
3815

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

3818 3819
			// reset state after plugin (anything could have changed)

A
alteredq 已提交
3820
			_currentProgram = null;
3821
			_currentCamera = null;
3822

A
alteredq 已提交
3823 3824 3825
			_oldBlending = -1;
			_oldDepthTest = -1;
			_oldDepthWrite = -1;
3826 3827
			_oldDoubleSided = -1;
			_oldFlipSided = -1;
A
alteredq 已提交
3828 3829
			_currentGeometryGroupHash = -1;
			_currentMaterialId = -1;
3830

3831
			_lightsNeedUpdate = true;
A
alteredq 已提交
3832 3833 3834 3835 3836

		}

	};

3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872
	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;

3873
					if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
3874

A
alteredq 已提交
3875
					_this.setDepthTest( material.depthTest );
3876
					_this.setDepthWrite( material.depthWrite );
3877 3878 3879 3880
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

3881
				_this.setMaterialFaces( material );
3882 3883 3884 3885 3886 3887 3888 3889 3890 3891

				if ( buffer instanceof THREE.BufferGeometry ) {

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

				} else {

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

				}
3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919

			}

		}

	};

	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;

3920
					if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
3921

A
alteredq 已提交
3922
					_this.setDepthTest( material.depthTest );
3923
					_this.setDepthWrite( material.depthWrite );
3924 3925 3926 3927
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

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

A
alteredq 已提交
3930
			}
3931

A
alteredq 已提交
3932
		}
3933

A
alteredq 已提交
3934
	};
3935

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

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

A
alteredq 已提交
3940
		_currentGeometryGroupHash = -1;
3941

3942
		_this.setMaterialFaces( material );
A
alteredq 已提交
3943 3944 3945 3946 3947 3948 3949

		if ( object.immediateRenderCallback ) {

			object.immediateRenderCallback( program, _gl, _frustum );

		} else {

3950
			object.render( function( object ) { _this.renderBufferImmediate( object, program, material ); } );
3951 3952 3953 3954 3955

		}

	};

3956
	function unrollImmediateBufferMaterial ( globject ) {
3957

3958 3959
		var object = globject.object,
			material = object.material;
3960

3961
		if ( material.transparent ) {
3962

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

3966
		} else {
3967

3968 3969
			globject.opaque = material;
			globject.transparent = null;
3970

3971
		}
A
alteredq 已提交
3972

3973
	};
A
alteredq 已提交
3974

3975
	function unrollBufferMaterial ( globject ) {
A
alteredq 已提交
3976

3977 3978 3979
		var object = globject.object,
			buffer = globject.buffer,
			material, materialIndex, meshMaterial;
3980

3981
		meshMaterial = object.material;
3982

3983
		if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
M
Mr.doob 已提交
3984

3985
			materialIndex = buffer.materialIndex;
3986

3987
			if ( materialIndex >= 0 ) {
3988

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

3991
				if ( material.transparent ) {
M
Mr.doob 已提交
3992

3993 3994
					globject.transparent = material;
					globject.opaque = null;
3995

3996
				} else {
3997

3998 3999
					globject.opaque = material;
					globject.transparent = null;
4000

4001
				}
4002

4003
			}
4004

4005
		} else {
4006

4007
			material = meshMaterial;
4008

4009
			if ( material ) {
4010

4011
				if ( material.transparent ) {
M
Mr.doob 已提交
4012

4013 4014
					globject.transparent = material;
					globject.opaque = null;
A
alteredq 已提交
4015

4016
				} else {
4017

4018 4019
					globject.opaque = material;
					globject.transparent = null;
4020

4021
				}
4022

4023
			}
4024

4025
		}
4026

4027
	};
4028

4029
	// Geometry splitting
4030

4031
	function sortFacesByMaterial ( geometry ) {
4032

4033 4034 4035
		var f, fl, face, materialIndex, vertices,
			materialHash, groupHash,
			hash_map = {};
4036

4037
		var numMorphTargets = geometry.morphTargets.length;
4038
		var numMorphNormals = geometry.morphNormals.length;
4039

4040
		geometry.geometryGroups = {};
4041

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

4044 4045
			face = geometry.faces[ f ];
			materialIndex = face.materialIndex;
4046

4047
			materialHash = ( materialIndex !== undefined ) ? materialIndex : -1;
4048

4049
			if ( hash_map[ materialHash ] === undefined ) {
4050

4051
				hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 };
4052 4053 4054

			}

4055
			groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
4056

4057
			if ( geometry.geometryGroups[ groupHash ] === undefined ) {
4058

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

4061
			}
A
alteredq 已提交
4062

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

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

4067 4068
				hash_map[ materialHash ].counter += 1;
				groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
A
alteredq 已提交
4069

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

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

4074
				}
4075

4076
			}
4077

4078
			if ( face instanceof THREE.Face3 ) {
4079

4080
				geometry.geometryGroups[ groupHash ].faces3.push( f );
4081

4082
			} else {
4083

4084
				geometry.geometryGroups[ groupHash ].faces4.push( f );
4085

A
alteredq 已提交
4086
			}
4087

4088
			geometry.geometryGroups[ groupHash ].vertices += vertices;
4089

4090
		}
4091

4092
		geometry.geometryGroupsList = [];
4093

4094
		for ( var g in geometry.geometryGroups ) {
4095

4096
			geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;
4097

4098
			geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );
4099

4100
		}
4101

4102
	};
4103

4104 4105 4106 4107 4108 4109 4110 4111 4112
	// Objects refresh

	this.initWebGLObjects = function ( scene ) {

		if ( !scene.__webglObjects ) {

			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
			scene.__webglSprites = [];
4113
			scene.__webglFlares = [];
4114 4115

		}
4116

4117
		while ( scene.__objectsAdded.length ) {
4118

4119 4120
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
4121

4122
		}
A
alteredq 已提交
4123

4124
		while ( scene.__objectsRemoved.length ) {
4125

4126 4127
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
4128

4129
		}
4130

4131
		// update must be called after objects adding / removal
4132

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

4135
			updateObject( scene.__webglObjects[ o ].object );
M
Mr.doob 已提交
4136 4137 4138 4139 4140

		}

	};

4141
	// Objects adding
M
Mr.doob 已提交
4142

4143
	function addObject ( object, scene ) {
A
alteredq 已提交
4144

4145
		var g, geometry, geometryGroup;
4146

4147
		if ( ! object.__webglInit ) {
M
Mr.doob 已提交
4148

4149
			object.__webglInit = true;
M
Mr.doob 已提交
4150

4151
			object._modelViewMatrix = new THREE.Matrix4();
4152
			object._normalMatrix = new THREE.Matrix3();
M
Mr.doob 已提交
4153

4154
			if ( object instanceof THREE.Mesh ) {
M
Mr.doob 已提交
4155

4156
				geometry = object.geometry;
M
Mr.doob 已提交
4157

4158
				if ( geometry instanceof THREE.Geometry ) {
M
Mr.doob 已提交
4159

4160
					if ( geometry.geometryGroups === undefined ) {
M
Mr.doob 已提交
4161

4162
						sortFacesByMaterial( geometry );
M
Mr.doob 已提交
4163

4164 4165 4166
					}

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

4168
					for ( g in geometry.geometryGroups ) {
M
Mr.doob 已提交
4169

4170
						geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
4171

4172
						// initialise VBO on the first access
M
Mr.doob 已提交
4173

4174
						if ( ! geometryGroup.__webglVertexBuffer ) {
4175

4176 4177
							createMeshBuffers( geometryGroup );
							initMeshBuffers( geometryGroup, object );
M
Mr.doob 已提交
4178

4179
							geometry.verticesNeedUpdate = true;
4180
							geometry.morphTargetsNeedUpdate = true;
M
Mr.doob 已提交
4181
							geometry.elementsNeedUpdate = true;
M
Mr.doob 已提交
4182
							geometry.uvsNeedUpdate = true;
M
Mr.doob 已提交
4183
							geometry.normalsNeedUpdate = true;
4184
							geometry.tangentsNeedUpdate = true;
M
Mr.doob 已提交
4185
							geometry.colorsNeedUpdate = true;
4186 4187

						}
M
Mr.doob 已提交
4188

4189
					}
M
Mr.doob 已提交
4190

4191 4192 4193 4194
				} else if ( geometry instanceof THREE.BufferGeometry ) {

					initDirectBuffers( geometry );

4195
				}
M
Mr.doob 已提交
4196

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

4199
				geometry = object.geometry;
M
Mr.doob 已提交
4200

4201
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
4202

4203 4204
					createRibbonBuffers( geometry );
					initRibbonBuffers( geometry );
M
Mr.doob 已提交
4205

4206
					geometry.verticesNeedUpdate = true;
M
Mr.doob 已提交
4207
					geometry.colorsNeedUpdate = true;
M
Mr.doob 已提交
4208

4209
				}
M
Mr.doob 已提交
4210

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

4213
				geometry = object.geometry;
M
Mr.doob 已提交
4214

4215
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
4216

4217 4218
					createLineBuffers( geometry );
					initLineBuffers( geometry, object );
M
Mr.doob 已提交
4219

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

4223
				}
4224

4225
			} else if ( object instanceof THREE.ParticleSystem ) {
4226

4227
				geometry = object.geometry;
4228

4229
				if ( ! geometry.__webglVertexBuffer ) {
4230

4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243
					if ( geometry instanceof THREE.Geometry ) {

						createParticleBuffers( geometry );
						initParticleBuffers( geometry, object );

						geometry.verticesNeedUpdate = true;
						geometry.colorsNeedUpdate = true;

					} else if ( geometry instanceof THREE.BufferGeometry ) {

						initDirectBuffers( geometry );

					}
4244

4245

4246
				}
4247

4248
			}
4249

4250
		}
4251

4252
		if ( ! object.__webglActive ) {
4253

4254
			if ( object instanceof THREE.Mesh ) {
4255

4256
				geometry = object.geometry;
4257

4258 4259 4260 4261 4262 4263 4264 4265 4266
				if ( geometry instanceof THREE.BufferGeometry ) {

					addBuffer( scene.__webglObjects, geometry, object );

				} else {

					for ( g in geometry.geometryGroups ) {

						geometryGroup = geometry.geometryGroups[ g ];
4267

4268
						addBuffer( scene.__webglObjects, geometryGroup, object );
4269

4270
					}
4271

4272
				}
4273

4274 4275 4276
			} else if ( object instanceof THREE.Ribbon ||
						object instanceof THREE.Line ||
						object instanceof THREE.ParticleSystem ) {
4277

4278 4279
				geometry = object.geometry;
				addBuffer( scene.__webglObjects, geometry, object );
4280

4281
			} else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
4282

4283
				addBufferImmediate( scene.__webglObjectsImmediate, object );
4284

4285
			} else if ( object instanceof THREE.Sprite ) {
4286

4287
				scene.__webglSprites.push( object );
4288

4289 4290 4291 4292
			} else if ( object instanceof THREE.LensFlare ) {

				scene.__webglFlares.push( object );

4293 4294
			}

4295
			object.__webglActive = true;
4296

4297
		}
4298

4299
	};
4300

4301
	function addBuffer ( objlist, buffer, object ) {
4302

4303 4304 4305 4306 4307 4308 4309 4310
		objlist.push(
			{
				buffer: buffer,
				object: object,
				opaque: null,
				transparent: null
			}
		);
4311

4312
	};
4313

4314
	function addBufferImmediate ( objlist, object ) {
4315

4316 4317 4318 4319 4320
		objlist.push(
			{
				object: object,
				opaque: null,
				transparent: null
4321
			}
4322
		);
4323

4324
	};
4325

4326
	// Objects updates
4327

4328
	function updateObject ( object ) {
4329

4330 4331
		var geometry = object.geometry,
			geometryGroup, customAttributesDirty, material;
4332

4333
		if ( object instanceof THREE.Mesh ) {
4334

4335 4336
			if ( geometry instanceof THREE.BufferGeometry ) {

M
Mr.doob 已提交
4337
				if ( geometry.verticesNeedUpdate || geometry.elementsNeedUpdate ||
M
Mr.doob 已提交
4338
					 geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
4339
					 geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate ) {
4340

4341
					setDirectBuffers( geometry, _gl.DYNAMIC_DRAW, !geometry.dynamic );
4342

4343
				}
4344

4345
				geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4346
				geometry.elementsNeedUpdate = false;
M
Mr.doob 已提交
4347
				geometry.uvsNeedUpdate = false;
M
Mr.doob 已提交
4348
				geometry.normalsNeedUpdate = false;
M
Mr.doob 已提交
4349
				geometry.colorsNeedUpdate = false;
4350
				geometry.tangentsNeedUpdate = false;
4351

4352
			} else {
4353

4354
				// check all geometry groups
4355

4356 4357 4358 4359 4360 4361
				for( var i = 0, il = geometry.geometryGroupsList.length; i < il; i ++ ) {

					geometryGroup = geometry.geometryGroupsList[ i ];

					material = getBufferMaterial( object, geometryGroup );

A
alteredq 已提交
4362 4363 4364 4365 4366 4367
					if ( geometry.buffersNeedUpdate ) {

						initMeshBuffers( geometryGroup, object );

					}

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

4370
					if ( geometry.verticesNeedUpdate || geometry.morphTargetsNeedUpdate || geometry.elementsNeedUpdate ||
M
Mr.doob 已提交
4371
						 geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
4372
						 geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate || customAttributesDirty ) {
4373 4374 4375 4376

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

					}
4377

4378
				}
M
Mr.doob 已提交
4379

4380
				geometry.verticesNeedUpdate = false;
4381
				geometry.morphTargetsNeedUpdate = false;
M
Mr.doob 已提交
4382
				geometry.elementsNeedUpdate = false;
M
Mr.doob 已提交
4383
				geometry.uvsNeedUpdate = false;
M
Mr.doob 已提交
4384
				geometry.normalsNeedUpdate = false;
M
Mr.doob 已提交
4385
				geometry.colorsNeedUpdate = false;
4386
				geometry.tangentsNeedUpdate = false;
4387

A
alteredq 已提交
4388 4389
				geometry.buffersNeedUpdate = false;

4390
				material.attributes && clearCustomAttributes( material );
4391

4392
			}
4393

4394
		} else if ( object instanceof THREE.Ribbon ) {
4395

M
Mr.doob 已提交
4396
			if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate ) {
4397

4398
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
4399

4400
			}
4401

4402
			geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4403
			geometry.colorsNeedUpdate = false;
4404

4405
		} else if ( object instanceof THREE.Line ) {
4406

4407
			material = getBufferMaterial( object, geometryGroup );
A
alteredq 已提交
4408

4409
			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
A
alteredq 已提交
4410

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

4413
				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
4414

4415
			}
4416

4417
			geometry.verticesNeedUpdate = false;
M
Mr.doob 已提交
4418
			geometry.colorsNeedUpdate = false;
4419

4420
			material.attributes && clearCustomAttributes( material );
4421

4422
		} else if ( object instanceof THREE.ParticleSystem ) {
4423

4424
			if ( geometry instanceof THREE.BufferGeometry ) {
4425

4426
				if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate ) {
4427

4428
					setDirectBuffers( geometry, _gl.DYNAMIC_DRAW, !geometry.dynamic );
4429

4430
				}
4431

4432 4433
				geometry.verticesNeedUpdate = false;
				geometry.colorsNeedUpdate = false;
4434

4435
			} else {
4436

4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452
				material = getBufferMaterial( object, geometryGroup );

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

				if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || object.sortParticles || customAttributesDirty ) {

					setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );

				}

				geometry.verticesNeedUpdate = false;
				geometry.colorsNeedUpdate = false;

				material.attributes && clearCustomAttributes( material );

			}
4453

4454
		}
4455

4456
	};
4457

4458
	// Objects updates - custom attributes check
4459

4460
	function areCustomAttributesDirty ( material ) {
4461

4462
		for ( var a in material.attributes ) {
4463

4464
			if ( material.attributes[ a ].needsUpdate ) return true;
4465

4466
		}
4467

4468
		return false;
4469

4470
	};
4471

4472 4473 4474
	function clearCustomAttributes ( material ) {

		for ( var a in material.attributes ) {
4475

4476
			material.attributes[ a ].needsUpdate = false;
4477

4478
		}
4479

4480
	};
4481

4482
	// Objects removal
4483

4484
	function removeObject ( object, scene ) {
4485

4486 4487 4488 4489
		if ( object instanceof THREE.Mesh  ||
			 object instanceof THREE.ParticleSystem ||
			 object instanceof THREE.Ribbon ||
			 object instanceof THREE.Line ) {
4490

4491
			removeInstances( scene.__webglObjects, object );
4492

4493
		} else if ( object instanceof THREE.Sprite ) {
4494

4495
			removeInstancesDirect( scene.__webglSprites, object );
4496

4497 4498 4499 4500
		} else if ( object instanceof THREE.LensFlare ) {

			removeInstancesDirect( scene.__webglFlares, object );

4501
		} else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
4502

4503
			removeInstances( scene.__webglObjectsImmediate, object );
4504

4505
		}
4506

4507
		object.__webglActive = false;
4508

4509
	};
4510

4511
	function removeInstances ( objlist, object ) {
4512

4513
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4514

4515
			if ( objlist[ o ].object === object ) {
4516

4517
				objlist.splice( o, 1 );
4518

4519
			}
4520

4521
		}
4522

4523
	};
4524

4525
	function removeInstancesDirect ( objlist, object ) {
4526

4527
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4528

4529
			if ( objlist[ o ] === object ) {
4530

4531
				objlist.splice( o, 1 );
4532

4533
			}
4534

4535
		}
4536

4537
	};
4538

4539
	// Materials
4540

4541
	this.initMaterial = function ( material, lights, fog, object ) {
4542

4543
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
4544

4545
		if ( material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
4546

4547
			shaderID = 'depth';
4548

4549
		} else if ( material instanceof THREE.MeshNormalMaterial ) {
4550

4551
			shaderID = 'normal';
M
Mr.doob 已提交
4552

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

4555
			shaderID = 'basic';
M
Mr.doob 已提交
4556

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

4559
			shaderID = 'lambert';
M
Mr.doob 已提交
4560

4561
		} else if ( material instanceof THREE.MeshPhongMaterial ) {
4562

4563
			shaderID = 'phong';
4564

4565
		} else if ( material instanceof THREE.LineBasicMaterial ) {
4566

4567
			shaderID = 'basic';
4568

4569
		} else if ( material instanceof THREE.ParticleBasicMaterial ) {
4570

4571
			shaderID = 'particle_basic';
4572 4573 4574

		}

4575
		if ( shaderID ) {
4576

4577
			setMaterialShaders( material, THREE.ShaderLib[ shaderID ] );
4578

4579
		}
4580

4581 4582
		// heuristics to create shader parameters according to lights in the scene
		// (not to blow over maxLights budget)
4583

4584
		maxLightCount = allocateLights( lights );
4585

4586
		maxShadows = allocateShadows( lights );
4587

4588
		maxBones = allocateBones( object );
4589

4590
		parameters = {
4591

A
alteredq 已提交
4592 4593 4594
			map: !!material.map,
			envMap: !!material.envMap,
			lightMap: !!material.lightMap,
4595
			bumpMap: !!material.bumpMap,
4596
			normalMap: !!material.normalMap,
4597
			specularMap: !!material.specularMap,
A
alteredq 已提交
4598

4599
			vertexColors: material.vertexColors,
A
alteredq 已提交
4600 4601 4602 4603

			fog: fog,
			useFog: material.fog,

4604
			sizeAttenuation: material.sizeAttenuation,
A
alteredq 已提交
4605

4606
			skinning: material.skinning,
A
alteredq 已提交
4607
			maxBones: maxBones,
4608 4609 4610
			useVertexTexture: _supportsBoneTextures && object && object.useVertexTexture,
			boneTextureWidth: object && object.boneTextureWidth,
			boneTextureHeight: object && object.boneTextureHeight,
A
alteredq 已提交
4611

4612
			morphTargets: material.morphTargets,
A
alteredq 已提交
4613
			morphNormals: material.morphNormals,
4614
			maxMorphTargets: this.maxMorphTargets,
A
alteredq 已提交
4615
			maxMorphNormals: this.maxMorphNormals,
A
alteredq 已提交
4616 4617 4618 4619

			maxDirLights: maxLightCount.directional,
			maxPointLights: maxLightCount.point,
			maxSpotLights: maxLightCount.spot,
A
alteredq 已提交
4620
			maxHemiLights: maxLightCount.hemi,
A
alteredq 已提交
4621 4622

			maxShadows: maxShadows,
4623 4624
			shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
			shadowMapSoft: this.shadowMapSoft,
A
alteredq 已提交
4625 4626
			shadowMapDebug: this.shadowMapDebug,
			shadowMapCascade: this.shadowMapCascade,
A
alteredq 已提交
4627

4628 4629
			alphaTest: material.alphaTest,
			metal: material.metal,
4630
			perPixel: material.perPixel,
4631
			wrapAround: material.wrapAround,
4632 4633
			doubleSided: material.side === THREE.DoubleSide,
			flipSided: material.side === THREE.BackSide
4634

4635
		};
M
Mr.doob 已提交
4636

4637
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, material.defines, parameters );
4638

4639
		var attributes = material.program.attributes;
4640

4641 4642 4643 4644
		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 );
4645

4646 4647
		if ( material.skinning &&
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
M
Mr.doob 已提交
4648

4649 4650
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
M
Mr.doob 已提交
4651 4652

		}
4653

4654
		if ( material.attributes ) {
A
alteredq 已提交
4655

4656
			for ( a in material.attributes ) {
M
Mr.doob 已提交
4657

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

4660
			}
M
Mr.doob 已提交
4661

4662
		}
M
Mr.doob 已提交
4663

4664
		if ( material.morphTargets ) {
M
Mr.doob 已提交
4665

4666
			material.numSupportedMorphTargets = 0;
4667

4668
			var id, base = "morphTarget";
4669

4670
			for ( i = 0; i < this.maxMorphTargets; i ++ ) {
4671

4672
				id = base + i;
M
Mr.doob 已提交
4673

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

4676 4677
					_gl.enableVertexAttribArray( attributes[ id ] );
					material.numSupportedMorphTargets ++;
4678

4679
				}
4680

4681
			}
4682

4683
		}
4684

A
alteredq 已提交
4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705
		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 ++;

				}

			}

		}

4706
		material.uniformsList = [];
4707

4708
		for ( u in material.uniforms ) {
4709

4710
			material.uniformsList.push( [ material.uniforms[ u ], u ] );
4711

4712
		}
M
Mr.doob 已提交
4713

4714
	};
M
Mr.doob 已提交
4715

4716
	function setMaterialShaders( material, shaders ) {
M
Mr.doob 已提交
4717

4718 4719 4720
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
M
Mr.doob 已提交
4721

4722
	};
M
Mr.doob 已提交
4723

4724
	function setProgram( camera, lights, fog, material, object ) {
4725

4726 4727
		_usedTextureUnits = 0;

A
alteredq 已提交
4728
		if ( material.needsUpdate ) {
4729

4730 4731
			if ( material.program ) _this.deallocateMaterial( material );

4732
			_this.initMaterial( material, lights, fog, object );
A
alteredq 已提交
4733
			material.needsUpdate = false;
4734

4735
		}
4736

4737
		if ( material.morphTargets ) {
4738

4739
			if ( ! object.__webglMorphTargetInfluences ) {
4740

4741
				object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );
4742

4743
			}
4744

4745
		}
4746

4747
		var refreshMaterial = false;
4748

4749 4750 4751
		var program = material.program,
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
4752

4753
		if ( program !== _currentProgram ) {
4754

4755 4756
			_gl.useProgram( program );
			_currentProgram = program;
4757

4758
			refreshMaterial = true;
4759

4760
		}
4761

4762
		if ( material.id !== _currentMaterialId ) {
4763

4764 4765
			_currentMaterialId = material.id;
			refreshMaterial = true;
4766

4767
		}
4768

4769
		if ( refreshMaterial || camera !== _currentCamera ) {
4770

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

4773 4774 4775 4776
			if ( camera !== _currentCamera ) _currentCamera = camera;

		}

4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805
		// skinning uniforms must be set even if material didn't change
		// auto-setting of texture unit for bone texture must go before other textures
		// not sure why, but otherwise weird things happen

		if ( material.skinning ) {

			if ( _supportsBoneTextures && object.useVertexTexture ) {

				if ( p_uniforms.boneTexture !== null ) {

					var textureUnit = getTextureUnit();

					_gl.uniform1i( p_uniforms.boneTexture, textureUnit );
					_this.setTexture( object.boneTexture, textureUnit );

				}

			} else {

				if ( p_uniforms.boneGlobalMatrices !== null ) {

					_gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.boneMatrices );

				}

			}

		}

4806 4807
		if ( refreshMaterial ) {

4808
			// refresh uniforms common to several materials
4809

4810
			if ( fog && material.fog ) {
4811

4812
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
4813

4814
			}
M
Mr.doob 已提交
4815

4816 4817 4818
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material.lights ) {
4819

4820 4821 4822 4823 4824 4825 4826
				if ( _lightsNeedUpdate ) {

					setupLights( program, lights );
					_lightsNeedUpdate = false;

				}

4827
				refreshUniformsLights( m_uniforms, _lights );
4828

4829
			}
M
Mr.doob 已提交
4830

4831 4832 4833
			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
4834

4835
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
4836 4837 4838

			}

4839
			// refresh single material specific uniforms
M
Mr.doob 已提交
4840

4841
			if ( material instanceof THREE.LineBasicMaterial ) {
4842

4843
				refreshUniformsLine( m_uniforms, material );
M
Mr.doob 已提交
4844

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

4847
				refreshUniformsParticle( m_uniforms, material );
M
Mr.doob 已提交
4848

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

4851
				refreshUniformsPhong( m_uniforms, material );
M
Mr.doob 已提交
4852

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

4855
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
4856

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

4859 4860 4861
				m_uniforms.mNear.value = camera.near;
				m_uniforms.mFar.value = camera.far;
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4862

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

4865
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4866

4867
			}
M
Mr.doob 已提交
4868

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

4871
				refreshUniformsShadow( m_uniforms, lights );
M
Mr.doob 已提交
4872

4873
			}
M
Mr.doob 已提交
4874

4875
			// load common uniforms
M
Mr.doob 已提交
4876

4877
			loadUniformsGeneric( program, material.uniformsList );
M
Mr.doob 已提交
4878

4879 4880
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)
4881

4882 4883 4884
			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
				 material.envMap ) {
4885

4886
				if ( p_uniforms.cameraPosition !== null ) {
4887

4888 4889
					var position = camera.matrixWorld.getPosition();
					_gl.uniform3f( p_uniforms.cameraPosition, position.x, position.y, position.z );
4890

4891
				}
4892 4893 4894

			}

4895 4896 4897 4898
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {
4899

4900
				if ( p_uniforms.viewMatrix !== null ) {
4901

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

4904
				}
4905

4906
			}
M
Mr.doob 已提交
4907

4908 4909
		}

4910
		loadUniformsMatrices( p_uniforms, object );
M
Mr.doob 已提交
4911

4912
		if ( p_uniforms.modelMatrix !== null ) {
M
Mr.doob 已提交
4913

4914
			_gl.uniformMatrix4fv( p_uniforms.modelMatrix, false, object.matrixWorld.elements );
4915

4916
		}
4917

4918
		return program;
4919

4920
	};
4921

4922
	// Uniforms (refresh uniforms objects)
A
alteredq 已提交
4923

4924
	function refreshUniformsCommon ( uniforms, material ) {
4925

4926
		uniforms.opacity.value = material.opacity;
4927

4928
		if ( _this.gammaInput ) {
4929

4930
			uniforms.diffuse.value.copyGammaToLinear( material.color );
4931

4932
		} else {
4933

4934
			uniforms.diffuse.value = material.color;
4935

4936
		}
4937

4938 4939 4940
		uniforms.map.value = material.map;
		uniforms.lightMap.value = material.lightMap;
		uniforms.specularMap.value = material.specularMap;
4941

4942
		if ( material.bumpMap ) {
4943

4944
			uniforms.bumpMap.value = material.bumpMap;
4945
			uniforms.bumpScale.value = material.bumpScale;
M
Mr.doob 已提交
4946

4947
		}
M
Mr.doob 已提交
4948

4949 4950
		if ( material.normalMap ) {

4951
			uniforms.normalMap.value = material.normalMap;
4952
			uniforms.normalScale.value.copy( material.normalScale );
4953

4954
		}
M
Mr.doob 已提交
4955

4956 4957 4958
		// uv repeat and offset setting priorities
		//	1. color map
		//	2. specular map
4959 4960
		//	3. normal map
		//	4. bump map
4961

4962
		var uvScaleMap;
4963

4964
		if ( material.map ) {
4965

4966
			uvScaleMap = material.map;
4967

4968
		} else if ( material.specularMap ) {
4969

4970 4971
			uvScaleMap = material.specularMap;

4972 4973 4974 4975
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987
		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

		}

		if ( uvScaleMap !== undefined ) {

			var offset = uvScaleMap.offset;
			var repeat = uvScaleMap.repeat;

			uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
4988

4989
		}
4990

4991
		uniforms.envMap.value = material.envMap;
4992
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
4993

4994
		if ( _this.gammaInput ) {
4995

4996 4997
			//uniforms.reflectivity.value = material.reflectivity * material.reflectivity;
			uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
4998

4999
		} else {
5000

5001
			uniforms.reflectivity.value = material.reflectivity;
5002

5003
		}
5004

5005 5006 5007
		uniforms.refractionRatio.value = material.refractionRatio;
		uniforms.combine.value = material.combine;
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
M
Mr.doob 已提交
5008

5009
	};
M
Mr.doob 已提交
5010

5011
	function refreshUniformsLine ( uniforms, material ) {
M
Mr.doob 已提交
5012

5013 5014
		uniforms.diffuse.value = material.color;
		uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
5015

5016
	};
M
Mr.doob 已提交
5017

5018
	function refreshUniformsParticle ( uniforms, material ) {
5019

5020 5021 5022 5023
		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.
5024

5025
		uniforms.map.value = material.map;
5026

5027
	};
5028

5029
	function refreshUniformsFog ( uniforms, fog ) {
5030

5031
		uniforms.fogColor.value = fog.color;
5032

5033
		if ( fog instanceof THREE.Fog ) {
5034

5035 5036
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
5037

5038
		} else if ( fog instanceof THREE.FogExp2 ) {
M
Mikael Emtinger 已提交
5039

5040
			uniforms.fogDensity.value = fog.density;
M
Mikael Emtinger 已提交
5041

5042
		}
M
Mikael Emtinger 已提交
5043

5044
	};
M
Mikael Emtinger 已提交
5045

5046
	function refreshUniformsPhong ( uniforms, material ) {
M
Mikael Emtinger 已提交
5047

5048
		uniforms.shininess.value = material.shininess;
5049

5050
		if ( _this.gammaInput ) {
M
Mikael Emtinger 已提交
5051

5052
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
5053
			uniforms.emissive.value.copyGammaToLinear( material.emissive );
5054
			uniforms.specular.value.copyGammaToLinear( material.specular );
5055

5056
		} else {
5057

5058
			uniforms.ambient.value = material.ambient;
5059
			uniforms.emissive.value = material.emissive;
5060
			uniforms.specular.value = material.specular;
5061

5062
		}
5063

5064 5065 5066 5067 5068 5069
		if ( material.wrapAround ) {

			uniforms.wrapRGB.value.copy( material.wrapRGB );

		}

5070
	};
5071

5072
	function refreshUniformsLambert ( uniforms, material ) {
5073

5074
		if ( _this.gammaInput ) {
5075

5076
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
5077
			uniforms.emissive.value.copyGammaToLinear( material.emissive );
M
Mr.doob 已提交
5078

5079
		} else {
5080

5081
			uniforms.ambient.value = material.ambient;
5082
			uniforms.emissive.value = material.emissive;
5083

5084
		}
5085

5086 5087 5088 5089 5090 5091
		if ( material.wrapAround ) {

			uniforms.wrapRGB.value.copy( material.wrapRGB );

		}

5092
	};
5093

5094
	function refreshUniformsLights ( uniforms, lights ) {
5095

5096
		uniforms.ambientLightColor.value = lights.ambient;
5097

5098 5099
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
5100

5101 5102 5103
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
		uniforms.pointLightDistance.value = lights.point.distances;
5104

A
alteredq 已提交
5105 5106 5107 5108 5109 5110 5111
		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;

A
alteredq 已提交
5112 5113 5114 5115
		uniforms.hemisphereLightSkyColor.value = lights.hemi.skyColors;
		uniforms.hemisphereLightGroundColor.value = lights.hemi.groundColors;
		uniforms.hemisphereLightPosition.value = lights.hemi.positions;

5116
	};
5117

5118
	function refreshUniformsShadow ( uniforms, lights ) {
M
Mr.doob 已提交
5119

5120
		if ( uniforms.shadowMatrix ) {
5121

5122
			var j = 0;
5123

5124
			for ( var i = 0, il = lights.length; i < il; i ++ ) {
5125

5126
				var light = lights[ i ];
5127

A
alteredq 已提交
5128 5129
				if ( ! light.castShadow ) continue;

5130
				if ( light instanceof THREE.SpotLight || ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) ) {
5131

5132
					uniforms.shadowMap.value[ j ] = light.shadowMap;
5133
					uniforms.shadowMapSize.value[ j ] = light.shadowMapSize;
5134

5135 5136 5137 5138 5139 5140 5141 5142 5143 5144
					uniforms.shadowMatrix.value[ j ] = light.shadowMatrix;

					uniforms.shadowDarkness.value[ j ] = light.shadowDarkness;
					uniforms.shadowBias.value[ j ] = light.shadowBias;

					j ++;

				}

			}
5145

5146 5147
		}

5148
	};
5149

5150
	// Uniforms (load to GPU)
5151

5152
	function loadUniformsMatrices ( uniforms, object ) {
5153

5154
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrix.elements );
5155

5156
		if ( uniforms.normalMatrix ) {
5157

5158
			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrix.elements );
5159

5160
		}
5161

5162
	};
5163

5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179
	function getTextureUnit() {

		var textureUnit = _usedTextureUnits;

		if ( textureUnit >= _maxTextures ) {

			console.warn( "Trying to use " + textureUnit + " texture units while this GPU supports only " + _maxTextures );

		}

		_usedTextureUnits += 1;

		return textureUnit;

	};

5180
	function loadUniformsGeneric ( program, uniforms ) {
5181

5182
		var uniform, value, type, location, texture, textureUnit, i, il, j, jl, offset;
5183

M
Mr.doob 已提交
5184
		for ( j = 0, jl = uniforms.length; j < jl; j ++ ) {
5185

5186 5187
			location = program.uniforms[ uniforms[ j ][ 1 ] ];
			if ( !location ) continue;
5188

5189
			uniform = uniforms[ j ][ 0 ];
5190

5191 5192
			type = uniform.type;
			value = uniform.value;
5193

5194
			if ( type === "i" ) { // single integer
5195

5196
				_gl.uniform1i( location, value );
5197

5198
			} else if ( type === "f" ) { // single float
5199

5200
				_gl.uniform1f( location, value );
5201

5202
			} else if ( type === "v2" ) { // single THREE.Vector2
5203

5204
				_gl.uniform2f( location, value.x, value.y );
5205

5206
			} else if ( type === "v3" ) { // single THREE.Vector3
5207

5208
				_gl.uniform3f( location, value.x, value.y, value.z );
5209

5210
			} else if ( type === "v4" ) { // single THREE.Vector4
5211

5212
				_gl.uniform4f( location, value.x, value.y, value.z, value.w );
5213

5214
			} else if ( type === "c" ) { // single THREE.Color
5215

5216
				_gl.uniform3f( location, value.r, value.g, value.b );
5217

5218 5219 5220
			} else if ( type === "iv1" ) { // flat array of integers (JS or typed array)

				_gl.uniform1iv( location, value );
5221 5222 5223 5224

			} else if ( type === "iv" ) { // flat array of integers with 3 x N size (JS or typed array)

				_gl.uniform3iv( location, value );
5225

5226
			} else if ( type === "fv1" ) { // flat array of floats (JS or typed array)
5227

5228
				_gl.uniform1fv( location, value );
5229

5230
			} else if ( type === "fv" ) { // flat array of floats with 3 x N size (JS or typed array)
5231

5232
				_gl.uniform3fv( location, value );
5233

5234
			} else if ( type === "v2v" ) { // array of THREE.Vector2
5235

5236
				if ( uniform._array === undefined ) {
5237

5238
					uniform._array = new Float32Array( 2 * value.length );
5239

5240
				}
5241

5242
				for ( i = 0, il = value.length; i < il; i ++ ) {
5243

5244
					offset = i * 2;
5245

5246 5247
					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;
5248

5249
				}
5250

5251
				_gl.uniform2fv( location, uniform._array );
5252

5253
			} else if ( type === "v3v" ) { // array of THREE.Vector3
5254

5255
				if ( uniform._array === undefined ) {
M
Mr.doob 已提交
5256

5257
					uniform._array = new Float32Array( 3 * value.length );
A
alteredq 已提交
5258

5259
				}
5260

5261
				for ( i = 0, il = value.length; i < il; i ++ ) {
5262

5263
					offset = i * 3;
5264

5265 5266 5267
					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;
					uniform._array[ offset + 2 ] = value[ i ].z;
A
alteredq 已提交
5268

5269
				}
5270

5271
				_gl.uniform3fv( location, uniform._array );
A
alteredq 已提交
5272

5273
			} else if ( type === "v4v" ) { // array of THREE.Vector4
M
Mr.doob 已提交
5274

5275
				if ( uniform._array === undefined ) {
M
Mr.doob 已提交
5276

5277
					uniform._array = new Float32Array( 4 * value.length );
M
Mr.doob 已提交
5278

5279
				}
A
alteredq 已提交
5280

5281
				for ( i = 0, il = value.length; i < il; i ++ ) {
M
Mr.doob 已提交
5282

5283
					offset = i * 4;
M
Mr.doob 已提交
5284

5285 5286 5287 5288
					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 已提交
5289

5290
				}
5291

5292
				_gl.uniform4fv( location, uniform._array );
A
alteredq 已提交
5293

5294
			} else if ( type === "m4") { // single THREE.Matrix4
A
alteredq 已提交
5295

5296
				if ( uniform._array === undefined ) {
A
alteredq 已提交
5297

5298
					uniform._array = new Float32Array( 16 );
A
alteredq 已提交
5299

5300
				}
M
Mr.doob 已提交
5301

5302 5303
				value.flattenToArray( uniform._array );
				_gl.uniformMatrix4fv( location, false, uniform._array );
5304

5305
			} else if ( type === "m4v" ) { // array of THREE.Matrix4
5306

5307
				if ( uniform._array === undefined ) {
5308

5309
					uniform._array = new Float32Array( 16 * value.length );
M
Mr.doob 已提交
5310

5311
				}
M
Mr.doob 已提交
5312

5313
				for ( i = 0, il = value.length; i < il; i ++ ) {
M
Mr.doob 已提交
5314

5315
					value[ i ].flattenToArrayOffset( uniform._array, i * 16 );
A
alteredq 已提交
5316

5317
				}
M
Mr.doob 已提交
5318

5319
				_gl.uniformMatrix4fv( location, false, uniform._array );
M
Mr.doob 已提交
5320

5321
			} else if ( type === "t" ) { // single THREE.Texture (2d or cube)
5322

5323 5324
				texture = value;
				textureUnit = getTextureUnit();
M
Mr.doob 已提交
5325

5326
				_gl.uniform1i( location, textureUnit );
M
Mr.doob 已提交
5327

5328
				if ( !texture ) continue;
M
Mr.doob 已提交
5329

5330
				if ( texture.image instanceof Array && texture.image.length === 6 ) {
M
Mr.doob 已提交
5331

5332
					setCubeTexture( texture, textureUnit );
M
Mr.doob 已提交
5333

5334
				} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
M
Mr.doob 已提交
5335

5336
					setCubeTextureDynamic( texture, textureUnit );
5337

5338
				} else {
A
alteredq 已提交
5339

5340
					_this.setTexture( texture, textureUnit );
A
alteredq 已提交
5341

5342
				}
A
alteredq 已提交
5343

5344
			} else if ( type === "tv" ) { // array of THREE.Texture (2d)
5345

5346
				if ( uniform._array === undefined ) {
5347

5348
					uniform._array = [];
M
Mr.doob 已提交
5349

5350
				}
M
Mr.doob 已提交
5351

5352
				for( i = 0, il = uniform.value.length; i < il; i ++ ) {
M
Mr.doob 已提交
5353

5354
					uniform._array[ i ] = getTextureUnit();
M
Mr.doob 已提交
5355

5356
				}
M
Mr.doob 已提交
5357

5358
				_gl.uniform1iv( location, uniform._array );
M
Mr.doob 已提交
5359

5360
				for( i = 0, il = uniform.value.length; i < il; i ++ ) {
M
Mr.doob 已提交
5361

5362 5363
					texture = uniform.value[ i ];
					textureUnit = uniform._array[ i ];
M
Mr.doob 已提交
5364

5365
					if ( !texture ) continue;
M
Mr.doob 已提交
5366

5367
					_this.setTexture( texture, textureUnit );
M
Mr.doob 已提交
5368

5369
				}
M
Mr.doob 已提交
5370

M
Mr.doob 已提交
5371
			}
M
Mr.doob 已提交
5372

M
Mr.doob 已提交
5373
		}
M
Mr.doob 已提交
5374

5375
	};
M
Mr.doob 已提交
5376

A
alteredq 已提交
5377
	function setupMatrices ( object, camera ) {
M
Mr.doob 已提交
5378

5379
		object._modelViewMatrix.multiply( camera.matrixWorldInverse, object.matrixWorld );
M
Mr.doob 已提交
5380

5381
		object._normalMatrix.getInverse( object._modelViewMatrix );
5382
		object._normalMatrix.transpose();
M
Mr.doob 已提交
5383

A
alteredq 已提交
5384
	};
M
Mr.doob 已提交
5385

A
alteredq 已提交
5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403
	//

	function setColorGamma( array, offset, color, intensitySq ) {

		array[ offset ]     = color.r * color.r * intensitySq;
		array[ offset + 1 ] = color.g * color.g * intensitySq;
		array[ offset + 2 ] = color.b * color.b * intensitySq;

	};

	function setColorLinear( array, offset, color, intensity ) {

		array[ offset ]     = color.r * intensity;
		array[ offset + 1 ] = color.g * intensity;
		array[ offset + 2 ] = color.b * intensity;

	};

5404
	function setupLights ( program, lights ) {
M
Mr.doob 已提交
5405

5406 5407
		var l, ll, light, n,
		r = 0, g = 0, b = 0,
A
alteredq 已提交
5408 5409 5410 5411
		color, skyColor, groundColor,
		intensity,  intensitySq,
		position,
		distance,
M
Mr.doob 已提交
5412

5413
		zlights = _lights,
A
alteredq 已提交
5414

A
alteredq 已提交
5415 5416 5417 5418 5419 5420
		dirColors = zlights.directional.colors,
		dirPositions = zlights.directional.positions,

		pointColors = zlights.point.colors,
		pointPositions = zlights.point.positions,
		pointDistances = zlights.point.distances,
A
alteredq 已提交
5421

A
alteredq 已提交
5422 5423 5424 5425 5426 5427
		spotColors = zlights.spot.colors,
		spotPositions = zlights.spot.positions,
		spotDistances = zlights.spot.distances,
		spotDirections = zlights.spot.directions,
		spotAngles = zlights.spot.angles,
		spotExponents = zlights.spot.exponents,
5428

A
alteredq 已提交
5429 5430 5431
		hemiSkyColors = zlights.hemi.skyColors,
		hemiGroundColors = zlights.hemi.groundColors,
		hemiPositions = zlights.hemi.positions,
A
alteredq 已提交
5432

A
alteredq 已提交
5433 5434 5435 5436
		dirLength = 0,
		pointLength = 0,
		spotLength = 0,
		hemiLength = 0,
5437

A
alteredq 已提交
5438 5439 5440 5441
		dirOffset = 0,
		pointOffset = 0,
		spotOffset = 0,
		hemiOffset = 0;
5442

5443
		for ( l = 0, ll = lights.length; l < ll; l ++ ) {
5444

5445
			light = lights[ l ];
A
alteredq 已提交
5446

5447
			if ( light.onlyShadow || ! light.visible ) continue;
A
alteredq 已提交
5448 5449

			color = light.color;
5450 5451
			intensity = light.intensity;
			distance = light.distance;
A
alteredq 已提交
5452

5453
			if ( light instanceof THREE.AmbientLight ) {
5454

5455
				if ( _this.gammaInput ) {
5456

5457 5458 5459
					r += color.r * color.r;
					g += color.g * color.g;
					b += color.b * color.b;
5460

5461
				} else {
5462

5463 5464 5465
					r += color.r;
					g += color.g;
					b += color.b;
5466

5467
				}
5468

5469
			} else if ( light instanceof THREE.DirectionalLight ) {
5470

A
alteredq 已提交
5471
				dirOffset = dirLength * 3;
5472

5473
				if ( _this.gammaInput ) {
5474

A
alteredq 已提交
5475
					setColorGamma( dirColors, dirOffset, color, intensity * intensity );
5476

5477
				} else {
5478

A
alteredq 已提交
5479
					setColorLinear( dirColors, dirOffset, color, intensity );
A
alteredq 已提交
5480

5481
				}
A
alteredq 已提交
5482

5483 5484 5485
				_direction.copy( light.matrixWorld.getPosition() );
				_direction.subSelf( light.target.matrixWorld.getPosition() );
				_direction.normalize();
A
alteredq 已提交
5486

A
alteredq 已提交
5487 5488 5489
				dirPositions[ dirOffset ]     = _direction.x;
				dirPositions[ dirOffset + 1 ] = _direction.y;
				dirPositions[ dirOffset + 2 ] = _direction.z;
A
alteredq 已提交
5490

A
alteredq 已提交
5491
				dirLength += 1;
A
alteredq 已提交
5492

A
alteredq 已提交
5493
			} else if( light instanceof THREE.PointLight ) {
M
Mr.doob 已提交
5494

A
alteredq 已提交
5495
				pointOffset = pointLength * 3;
M
Mr.doob 已提交
5496

5497
				if ( _this.gammaInput ) {
5498

A
alteredq 已提交
5499
					setColorGamma( pointColors, pointOffset, color, intensity * intensity );
A
alteredq 已提交
5500

5501
				} else {
A
alteredq 已提交
5502

A
alteredq 已提交
5503
					setColorLinear( pointColors, pointOffset, color, intensity );
A
alteredq 已提交
5504

5505
				}
A
alteredq 已提交
5506

A
alteredq 已提交
5507 5508
				position = light.matrixWorld.getPosition();

A
alteredq 已提交
5509 5510 5511
				pointPositions[ pointOffset ]     = position.x;
				pointPositions[ pointOffset + 1 ] = position.y;
				pointPositions[ pointOffset + 2 ] = position.z;
A
alteredq 已提交
5512

A
alteredq 已提交
5513
				pointDistances[ pointLength ] = distance;
A
alteredq 已提交
5514

A
alteredq 已提交
5515
				pointLength += 1;
5516

A
alteredq 已提交
5517 5518
			} else if( light instanceof THREE.SpotLight ) {

A
alteredq 已提交
5519
				spotOffset = spotLength * 3;
A
alteredq 已提交
5520 5521 5522

				if ( _this.gammaInput ) {

A
alteredq 已提交
5523
					setColorGamma( spotColors, spotOffset, color, intensity * intensity );
A
alteredq 已提交
5524 5525 5526

				} else {

A
alteredq 已提交
5527
					setColorLinear( spotColors, spotOffset, color, intensity );
A
alteredq 已提交
5528 5529 5530 5531 5532

				}

				position = light.matrixWorld.getPosition();

A
alteredq 已提交
5533 5534 5535
				spotPositions[ spotOffset ]     = position.x;
				spotPositions[ spotOffset + 1 ] = position.y;
				spotPositions[ spotOffset + 2 ] = position.z;
A
alteredq 已提交
5536

A
alteredq 已提交
5537
				spotDistances[ spotLength ] = distance;
A
alteredq 已提交
5538 5539 5540 5541 5542

				_direction.copy( position );
				_direction.subSelf( light.target.matrixWorld.getPosition() );
				_direction.normalize();

A
alteredq 已提交
5543 5544 5545 5546 5547 5548 5549 5550 5551 5552
				spotDirections[ spotOffset ]     = _direction.x;
				spotDirections[ spotOffset + 1 ] = _direction.y;
				spotDirections[ spotOffset + 2 ] = _direction.z;

				spotAngles[ spotLength ] = Math.cos( light.angle );
				spotExponents[ spotLength ] = light.exponent;

				spotLength += 1;

			} else if ( light instanceof THREE.HemisphereLight ) {
A
alteredq 已提交
5553

A
alteredq 已提交
5554 5555
				skyColor = light.color;
				groundColor = light.groundColor;
A
alteredq 已提交
5556

A
alteredq 已提交
5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579
				hemiOffset = hemiLength * 3;

				if ( _this.gammaInput ) {

					intensitySq = intensity * intensity;

					setColorGamma( hemiSkyColors, hemiOffset, skyColor, intensitySq );
					setColorGamma( hemiGroundColors, hemiOffset, groundColor, intensitySq );

				} else {

					setColorLinear( hemiSkyColors, hemiOffset, skyColor, intensity );
					setColorLinear( hemiGroundColors, hemiOffset, groundColor, intensity );

				}

				position = light.matrixWorld.getPosition();

				hemiPositions[ hemiOffset ]     = position.x;
				hemiPositions[ hemiOffset + 1 ] = position.y;
				hemiPositions[ hemiOffset + 2 ] = position.z;

				hemiLength += 1;
A
alteredq 已提交
5580

5581
			}
5582

5583
		}
A
alteredq 已提交
5584

5585 5586
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
A
alteredq 已提交
5587

A
alteredq 已提交
5588 5589 5590 5591 5592
		for ( l = dirLength * 3, ll = dirColors.length; l < ll; l ++ ) dirColors[ l ] = 0.0;
		for ( l = pointLength * 3, ll = pointColors.length; l < ll; l ++ ) pointColors[ l ] = 0.0;
		for ( l = spotLength * 3, ll = spotColors.length; l < ll; l ++ ) spotColors[ l ] = 0.0;
		for ( l = hemiLength * 3, ll = hemiSkyColors.length; l < ll; l ++ ) hemiSkyColors[ l ] = 0.0;
		for ( l = hemiLength * 3, ll = hemiGroundColors.length; l < ll; l ++ ) hemiGroundColors[ l ] = 0.0;
A
alteredq 已提交
5593

A
alteredq 已提交
5594 5595 5596 5597
		zlights.directional.length = dirLength;
		zlights.point.length = pointLength;
		zlights.spot.length = spotLength;
		zlights.hemi.length = hemiLength;
A
alteredq 已提交
5598

5599 5600 5601
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
5602

5603
	};
M
Mr.doob 已提交
5604

5605
	// GL state setting
M
Mr.doob 已提交
5606

5607
	this.setFaceCulling = function ( cullFace, frontFace ) {
M
Mr.doob 已提交
5608

5609
		if ( cullFace ) {
M
Mr.doob 已提交
5610

5611
			if ( !frontFace || frontFace === "ccw" ) {
5612

5613
				_gl.frontFace( _gl.CCW );
5614

5615
			} else {
5616

5617
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
5618

5619
			}
M
Mr.doob 已提交
5620

5621
			if( cullFace === "back" ) {
5622

5623
				_gl.cullFace( _gl.BACK );
5624

5625
			} else if( cullFace === "front" ) {
5626

5627
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
5628

5629
			} else {
5630

5631
				_gl.cullFace( _gl.FRONT_AND_BACK );
5632

5633
			}
5634

5635
			_gl.enable( _gl.CULL_FACE );
5636

5637
		} else {
5638

5639
			_gl.disable( _gl.CULL_FACE );
5640 5641 5642 5643 5644

		}

	};

5645
	this.setMaterialFaces = function ( material ) {
5646

5647 5648
		var doubleSided = material.side === THREE.DoubleSide;
		var flipSided = material.side === THREE.BackSide;
M
Mr.doob 已提交
5649

5650 5651 5652
		if ( _oldDoubleSided !== doubleSided ) {

			if ( doubleSided ) {
M
Mr.doob 已提交
5653

5654
				_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
5655

5656
			} else {
5657

5658
				_gl.enable( _gl.CULL_FACE );
5659

5660
			}
5661

5662
			_oldDoubleSided = doubleSided;
5663

5664
		}
5665

5666
		if ( _oldFlipSided !== flipSided ) {
5667

5668
			if ( flipSided ) {
5669

5670
				_gl.frontFace( _gl.CW );
5671

5672
			} else {
5673

5674
				_gl.frontFace( _gl.CCW );
5675

5676
			}
5677

5678
			_oldFlipSided = flipSided;
5679

5680
		}
5681

5682
	};
5683

A
alteredq 已提交
5684
	this.setDepthTest = function ( depthTest ) {
5685

5686
		if ( _oldDepthTest !== depthTest ) {
5687

5688
			if ( depthTest ) {
5689

5690
				_gl.enable( _gl.DEPTH_TEST );
5691

5692
			} else {
5693

5694
				_gl.disable( _gl.DEPTH_TEST );
5695 5696 5697

			}

5698
			_oldDepthTest = depthTest;
5699

5700
		}
5701

5702
	};
5703

5704
	this.setDepthWrite = function ( depthWrite ) {
A
alteredq 已提交
5705

5706
		if ( _oldDepthWrite !== depthWrite ) {
A
alteredq 已提交
5707

5708 5709
			_gl.depthMask( depthWrite );
			_oldDepthWrite = depthWrite;
A
alteredq 已提交
5710 5711 5712 5713 5714

		}

	};

5715
	function setLineWidth ( width ) {
5716

5717
		if ( width !== _oldLineWidth ) {
5718

5719 5720 5721
			_gl.lineWidth( width );

			_oldLineWidth = width;
5722 5723 5724

		}

5725
	};
5726

5727
	function setPolygonOffset ( polygonoffset, factor, units ) {
5728

5729
		if ( _oldPolygonOffset !== polygonoffset ) {
M
Mr.doob 已提交
5730

5731
			if ( polygonoffset ) {
5732

5733
				_gl.enable( _gl.POLYGON_OFFSET_FILL );
5734

5735
			} else {
5736

5737
				_gl.disable( _gl.POLYGON_OFFSET_FILL );
5738

5739
			}
5740

5741
			_oldPolygonOffset = polygonoffset;
5742

5743
		}
5744

5745
		if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
5746

5747
			_gl.polygonOffset( factor, units );
M
Mr.doob 已提交
5748

5749 5750
			_oldPolygonOffsetFactor = factor;
			_oldPolygonOffsetUnits = units;
M
Mr.doob 已提交
5751

5752
		}
M
Mr.doob 已提交
5753

5754
	};
M
Mr.doob 已提交
5755

5756
	this.setBlending = function ( blending, blendEquation, blendSrc, blendDst ) {
M
Mr.doob 已提交
5757

5758
		if ( blending !== _oldBlending ) {
M
Mr.doob 已提交
5759

5760
			if ( blending === THREE.NoBlending ) {
M
Mr.doob 已提交
5761

5762
				_gl.disable( _gl.BLEND );
M
Mr.doob 已提交
5763

5764
			} else if ( blending === THREE.AdditiveBlending ) {
M
Mr.doob 已提交
5765

5766 5767 5768
				_gl.enable( _gl.BLEND );
				_gl.blendEquation( _gl.FUNC_ADD );
				_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
M
Mr.doob 已提交
5769

5770
			} else if ( blending === THREE.SubtractiveBlending ) {
M
Mr.doob 已提交
5771

5772 5773 5774 5775
				// 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 已提交
5776

5777
			} else if ( blending === THREE.MultiplyBlending ) {
M
Mr.doob 已提交
5778

5779 5780 5781 5782
				// TODO: Find blendFuncSeparate() combination
				_gl.enable( _gl.BLEND );
				_gl.blendEquation( _gl.FUNC_ADD );
				_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
5783

5784
			} else if ( blending === THREE.CustomBlending ) {
5785

5786
				_gl.enable( _gl.BLEND );
5787

5788
			} else {
5789

5790 5791 5792
				_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 );
5793

5794
			}
5795

5796
			_oldBlending = blending;
5797

5798
		}
5799

5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826
		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;

		}

5827
	};
5828

5829 5830 5831 5832
	// Defines

	function generateDefines ( defines ) {

5833
		var value, chunk, chunks = [];
5834 5835 5836

		for ( var d in defines ) {

5837 5838 5839 5840
			value = defines[ d ];
			if ( value === false ) continue;

			chunk = "#define " + d + " " + value;
5841 5842 5843 5844 5845 5846 5847 5848
			chunks.push( chunk );

		}

		return chunks.join( "\n" );

	};

5849 5850
	// Shaders

5851
	function buildProgram ( shaderID, fragmentShader, vertexShader, uniforms, attributes, defines, parameters ) {
5852

5853
		var p, pl, d, program, code;
5854
		var chunks = [];
5855 5856 5857

		// Generate code

5858 5859 5860 5861 5862 5863 5864 5865 5866 5867
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

			chunks.push( fragmentShader );
			chunks.push( vertexShader );

		}
5868

5869 5870 5871 5872 5873 5874 5875
		for ( d in defines ) {

			chunks.push( d );
			chunks.push( defines[ d ] );

		}

5876 5877
		for ( p in parameters ) {

5878 5879
			chunks.push( p );
			chunks.push( parameters[ p ] );
5880 5881 5882

		}

5883 5884
		code = chunks.join();

5885 5886 5887 5888
		// Check if code has been already compiled

		for ( p = 0, pl = _programs.length; p < pl; p ++ ) {

A
alteredq 已提交
5889 5890 5891
			var programInfo = _programs[ p ];

			if ( programInfo.code === code ) {
5892 5893

				// console.log( "Code already compiled." /*: \n\n" + code*/ );
5894

A
alteredq 已提交
5895 5896 5897
				programInfo.usedTimes ++;

				return programInfo.program;
5898 5899 5900 5901

			}

		}
5902

5903
		//console.log( "building new program " );
5904 5905 5906

		//

5907 5908 5909 5910
		var customDefines = generateDefines( defines );

		//

5911
		program = _gl.createProgram();
M
Mr.doob 已提交
5912

5913
		var prefix_vertex = [
M
Mr.doob 已提交
5914

5915 5916
			"precision " + _precision + " float;",

5917 5918
			customDefines,

5919
			_supportsVertexTextures ? "#define VERTEX_TEXTURES" : "",
5920

5921 5922 5923 5924
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

5925 5926
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
5927
			"#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
A
alteredq 已提交
5928
			"#define MAX_HEMI_LIGHTS " + parameters.maxHemiLights,
5929

5930 5931
			"#define MAX_SHADOWS " + parameters.maxShadows,

5932 5933
			"#define MAX_BONES " + parameters.maxBones,

5934
			parameters.map ? "#define USE_MAP" : "",
5935 5936
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
5937
			parameters.bumpMap ? "#define USE_BUMPMAP" : "",
5938
			parameters.normalMap ? "#define USE_NORMALMAP" : "",
5939
			parameters.specularMap ? "#define USE_SPECULARMAP" : "",
5940
			parameters.vertexColors ? "#define USE_COLOR" : "",
5941

5942
			parameters.skinning ? "#define USE_SKINNING" : "",
5943
			parameters.useVertexTexture ? "#define BONE_TEXTURE" : "",
5944 5945
			parameters.boneTextureWidth ? "#define N_BONE_PIXEL_X " + parameters.boneTextureWidth.toFixed( 1 ) : "",
			parameters.boneTextureHeight ? "#define N_BONE_PIXEL_Y " + parameters.boneTextureHeight.toFixed( 1 ) : "",
5946

5947
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
A
alteredq 已提交
5948
			parameters.morphNormals ? "#define USE_MORPHNORMALS" : "",
A
alteredq 已提交
5949
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
5950
			parameters.wrapAround ? "#define WRAP_AROUND" : "",
5951
			parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
5952
			parameters.flipSided ? "#define FLIP_SIDED" : "",
5953

5954
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5955
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
A
alteredq 已提交
5956 5957
			parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
			parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
5958

5959 5960
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

5961
			"uniform mat4 modelMatrix;",
M
Mr.doob 已提交
5962 5963
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
5964 5965
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
5966
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
5967

M
Mr.doob 已提交
5968 5969 5970
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
5971
			"attribute vec2 uv2;",
5972

5973
			"#ifdef USE_COLOR",
5974

5975
				"attribute vec3 color;",
5976

5977 5978
			"#endif",

5979
			"#ifdef USE_MORPHTARGETS",
5980

5981 5982 5983 5984
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
A
alteredq 已提交
5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000

				"#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",
6001

6002 6003 6004
			"#endif",

			"#ifdef USE_SKINNING",
6005

6006 6007
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
6008

6009
			"#endif",
6010

M
Mr.doob 已提交
6011
			""
A
alteredq 已提交
6012

M
Mr.doob 已提交
6013
		].join("\n");
6014

M
Mr.doob 已提交
6015 6016
		var prefix_fragment = [

6017
			"precision " + _precision + " float;",
M
Mr.doob 已提交
6018

6019
			( parameters.bumpMap || parameters.normalMap ) ? "#extension GL_OES_standard_derivatives : enable" : "",
6020

6021 6022
			customDefines,

M
Mr.doob 已提交
6023 6024
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
6025
			"#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
A
alteredq 已提交
6026
			"#define MAX_HEMI_LIGHTS " + parameters.maxHemiLights,
M
Mr.doob 已提交
6027

6028 6029
			"#define MAX_SHADOWS " + parameters.maxShadows,

6030 6031
			parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",

6032 6033 6034 6035
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

M
Mr.doob 已提交
6036 6037
			( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
			( parameters.useFog && parameters.fog instanceof THREE.FogExp2 ) ? "#define FOG_EXP2" : "",
M
Mr.doob 已提交
6038 6039 6040 6041

			parameters.map ? "#define USE_MAP" : "",
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
6042
			parameters.bumpMap ? "#define USE_BUMPMAP" : "",
6043
			parameters.normalMap ? "#define USE_NORMALMAP" : "",
6044
			parameters.specularMap ? "#define USE_SPECULARMAP" : "",
M
Mr.doob 已提交
6045
			parameters.vertexColors ? "#define USE_COLOR" : "",
6046

6047 6048
			parameters.metal ? "#define METAL" : "",
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
6049
			parameters.wrapAround ? "#define WRAP_AROUND" : "",
6050
			parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
6051
			parameters.flipSided ? "#define FLIP_SIDED" : "",
6052

6053
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
6054
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
A
alteredq 已提交
6055 6056
			parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
			parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
M
Mr.doob 已提交
6057 6058 6059 6060 6061 6062 6063

			"uniform mat4 viewMatrix;",
			"uniform vec3 cameraPosition;",
			""

		].join("\n");

6064 6065 6066 6067 6068
		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 已提交
6069

M
Mr.doob 已提交
6070
		_gl.linkProgram( program );
N
Nicolas Garcia Belmonte 已提交
6071

M
Mr.doob 已提交
6072
		if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
N
Nicolas Garcia Belmonte 已提交
6073

6074
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
6075

N
Nicolas Garcia Belmonte 已提交
6076
		}
6077

6078 6079 6080 6081 6082
		// clean up

		_gl.deleteShader( glFragmentShader );
		_gl.deleteShader( glVertexShader );

6083 6084
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
6085

M
Mr.doob 已提交
6086
		program.uniforms = {};
6087
		program.attributes = {};
M
Mr.doob 已提交
6088

6089 6090 6091 6092
		var identifiers, u, a, i;

		// cache uniform locations

6093
		identifiers = [
6094

6095
			'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'modelMatrix', 'cameraPosition',
6096
			'morphTargetInfluences'
M
Mr.doob 已提交
6097

6098
		];
M
Mr.doob 已提交
6099

6100
		if ( parameters.useVertexTexture ) {
6101 6102 6103 6104 6105 6106 6107 6108 6109

			identifiers.push( 'boneTexture' );

		} else {

			identifiers.push( 'boneGlobalMatrices' );

		}

6110
		for ( u in uniforms ) {
M
Mr.doob 已提交
6111

6112
			identifiers.push( u );
M
Mr.doob 已提交
6113

6114
		}
M
Mr.doob 已提交
6115

6116
		cacheUniformLocations( program, identifiers );
M
Mr.doob 已提交
6117

6118
		// cache attributes locations
M
Mr.doob 已提交
6119

6120
		identifiers = [
A
alteredq 已提交
6121

6122
			"position", "normal", "uv", "uv2", "tangent", "color",
6123
			"skinIndex", "skinWeight"
A
alteredq 已提交
6124

6125
		];
M
Mr.doob 已提交
6126

6127
		for ( i = 0; i < parameters.maxMorphTargets; i ++ ) {
M
Mr.doob 已提交
6128

6129
			identifiers.push( "morphTarget" + i );
M
Mr.doob 已提交
6130

6131
		}
6132

A
alteredq 已提交
6133 6134 6135 6136 6137 6138
		for ( i = 0; i < parameters.maxMorphNormals; i ++ ) {

			identifiers.push( "morphNormal" + i );

		}

6139
		for ( a in attributes ) {
6140

6141
			identifiers.push( a );
6142

6143
		}
6144

6145
		cacheAttributeLocations( program, identifiers );
6146

A
alteredq 已提交
6147
		program.id = _programs_counter ++;
6148

A
alteredq 已提交
6149
		_programs.push( { program: program, code: code, usedTimes: 1 } );
6150

6151
		_this.info.memory.programs = _programs.length;
6152

6153
		return program;
6154

6155
	};
6156

6157
	// Shader parameters cache
6158

6159
	function cacheUniformLocations ( program, identifiers ) {
6160

6161
		var i, l, id;
6162

6163
		for( i = 0, l = identifiers.length; i < l; i ++ ) {
6164

6165 6166
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
6167

6168
		}
M
Mr.doob 已提交
6169

6170
	};
M
Mr.doob 已提交
6171

6172
	function cacheAttributeLocations ( program, identifiers ) {
A
alteredq 已提交
6173

6174
		var i, l, id;
A
alteredq 已提交
6175

6176
		for( i = 0, l = identifiers.length; i < l; i ++ ) {
A
alteredq 已提交
6177

6178 6179
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
A
alteredq 已提交
6180

6181
		}
6182

6183
	};
A
alteredq 已提交
6184

6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201
	function addLineNumbers ( string ) {

		var chunks = string.split( "\n" );

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

			// Chrome reports shader errors on lines
			// starting counting from 1

			chunks[ i ] = ( i + 1 ) + ": " + chunks[ i ];

		}

		return chunks.join( "\n" );

	};

6202
	function getShader ( type, string ) {
A
alteredq 已提交
6203

6204
		var shader;
6205

6206
		if ( type === "fragment" ) {
A
alteredq 已提交
6207

6208
			shader = _gl.createShader( _gl.FRAGMENT_SHADER );
A
alteredq 已提交
6209

6210
		} else if ( type === "vertex" ) {
A
alteredq 已提交
6211

6212
			shader = _gl.createShader( _gl.VERTEX_SHADER );
A
alteredq 已提交
6213

6214
		}
A
alteredq 已提交
6215

6216 6217
		_gl.shaderSource( shader, string );
		_gl.compileShader( shader );
6218

6219
		if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {
6220

6221
			console.error( _gl.getShaderInfoLog( shader ) );
6222
			console.error( addLineNumbers( string ) );
6223
			return null;
6224

A
alteredq 已提交
6225 6226
		}

6227 6228
		return shader;

A
alteredq 已提交
6229
	};
6230

6231 6232
	// Textures

6233 6234 6235 6236 6237 6238 6239

	function isPowerOfTwo ( value ) {

		return ( value & ( value - 1 ) ) === 0;

	};

6240
	function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {
6241

6242
		if ( isImagePowerOfTwo ) {
M
Mr.doob 已提交
6243

6244 6245
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
6246

6247 6248
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
6249

6250
		} else {
M
Mr.doob 已提交
6251

6252 6253
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
6254

6255 6256
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
6257

6258
		}
M
Mr.doob 已提交
6259

6260
		if ( _glExtensionTextureFilterAnisotropic && texture.type !== THREE.FloatType ) {
6261

6262 6263 6264 6265 6266 6267
			if ( texture.anisotropy > 1 || texture.__oldAnisotropy ) {

				_gl.texParameterf( textureType, _glExtensionTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _maxAnisotropy ) );
				texture.__oldAnisotropy = texture.anisotropy;

			}
6268 6269 6270

		}

6271
	};
6272

6273
	this.setTexture = function ( texture, slot ) {
6274

6275
		if ( texture.needsUpdate ) {
A
alteredq 已提交
6276

6277
			if ( ! texture.__webglInit ) {
M
Mr.doob 已提交
6278

6279
				texture.__webglInit = true;
6280
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
6281

M
Mr.doob 已提交
6282 6283
				_this.info.memory.textures ++;

6284
			}
M
Mr.doob 已提交
6285

6286
			_gl.activeTexture( _gl.TEXTURE0 + slot );
6287 6288
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );

6289
			_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
6290 6291
			_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );

6292 6293
			var image = texture.image,
			isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
6294 6295
			glFormat = paramThreeToGL( texture.format ),
			glType = paramThreeToGL( texture.type );
6296

6297 6298
			setTextureParameters( _gl.TEXTURE_2D, texture, isImagePowerOfTwo );

6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310
			if ( texture instanceof THREE.CompressedTexture ) {

				var mipmap, mipmaps = texture.mipmaps;

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

					mipmap = mipmaps[ i ];
					_gl.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );

				}

			} else if ( texture instanceof THREE.DataTexture ) {
6311

6312
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );
M
Mr.doob 已提交
6313

A
alteredq 已提交
6314
			} else {
M
Mr.doob 已提交
6315

6316
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, texture.image );
M
Mr.doob 已提交
6317 6318 6319

			}

6320
			if ( texture.generateMipmaps && isImagePowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
M
Mr.doob 已提交
6321

A
alteredq 已提交
6322
			texture.needsUpdate = false;
6323

6324
			if ( texture.onUpdate ) texture.onUpdate();
6325

6326
		} else {
6327

6328 6329
			_gl.activeTexture( _gl.TEXTURE0 + slot );
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
6330 6331

		}
M
Mr.doob 已提交
6332

6333
	};
M
Mr.doob 已提交
6334

6335 6336 6337 6338 6339 6340 6341 6342 6343 6344
	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.
6345

6346 6347 6348 6349 6350 6351 6352
		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;
6353

6354
		var ctx = canvas.getContext( "2d" );
6355 6356
		ctx.drawImage( image, 0, 0, image.width, image.height, 0, 0, newWidth, newHeight );

6357 6358 6359 6360
		return canvas;

	}

6361
	function setCubeTexture ( texture, slot ) {
6362

6363
		if ( texture.image.length === 6 ) {
6364 6365 6366

			if ( texture.needsUpdate ) {

A
alteredq 已提交
6367
				if ( ! texture.image.__webglTextureCube ) {
6368 6369

					texture.image.__webglTextureCube = _gl.createTexture();
6370

A
alteredq 已提交
6371
				}
6372

A
alteredq 已提交
6373 6374
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
6375

6376
				_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
M
Mr.doob 已提交
6377

6378 6379
				var isCompressed = texture instanceof THREE.CompressedTexture;

6380
				var cubeImage = [];
6381

A
alteredq 已提交
6382
				for ( var i = 0; i < 6; i ++ ) {
6383

6384
					if ( _this.autoScaleCubemaps && ! isCompressed ) {
6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395

						cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize );

					} else {

						cubeImage[ i ] = texture.image[ i ];

					}

				}

6396 6397
				var image = cubeImage[ 0 ],
				isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
6398 6399
				glFormat = paramThreeToGL( texture.format ),
				glType = paramThreeToGL( texture.type );
6400

6401 6402
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo );

A
alteredq 已提交
6403
				for ( var i = 0; i < 6; i ++ ) {
6404

6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420
					if ( isCompressed ) {

						var mipmap, mipmaps = cubeImage[ i ].mipmaps;

						for( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {

							mipmap = mipmaps[ j ];
							_gl.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );

						}

					} else {

						_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );

					}
6421

A
alteredq 已提交
6422
				}
6423

M
Mr.doob 已提交
6424 6425 6426 6427 6428
				if ( texture.generateMipmaps && isImagePowerOfTwo ) {

					_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

				}
6429

A
alteredq 已提交
6430
				texture.needsUpdate = false;
6431

6432
				if ( texture.onUpdate ) texture.onUpdate();
6433

A
alteredq 已提交
6434
			} else {
6435

A
alteredq 已提交
6436 6437
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
6438

A
alteredq 已提交
6439
			}
6440

A
alteredq 已提交
6441
		}
6442

A
alteredq 已提交
6443
	};
6444

6445
	function setCubeTextureDynamic ( texture, slot ) {
6446

A
alteredq 已提交
6447 6448
		_gl.activeTexture( _gl.TEXTURE0 + slot );
		_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
6449 6450 6451

	};

6452 6453 6454
	// Render targets

	function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
6455

6456 6457
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
A
alteredq 已提交
6458

6459
	};
M
Mr.doob 已提交
6460

6461
	function setupRenderBuffer ( renderbuffer, renderTarget  ) {
M
Mikael Emtinger 已提交
6462

6463
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
6464

6465
		if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
M
Mr.doob 已提交
6466

6467 6468
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
6469

6470 6471
		/* For some reason this is not working. Defaulting to RGBA4.
		} else if( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
A
alteredq 已提交
6472

6473 6474 6475 6476
			_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 已提交
6477

6478 6479
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
6480

6481
		} else {
A
alteredq 已提交
6482

6483
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
A
alteredq 已提交
6484

6485
		}
A
alteredq 已提交
6486

6487
	};
A
alteredq 已提交
6488

A
alteredq 已提交
6489
	this.setRenderTarget = function ( renderTarget ) {
A
alteredq 已提交
6490

6491
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
A
alteredq 已提交
6492

6493
		if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
A
alteredq 已提交
6494

M
Mr.doob 已提交
6495 6496
			if ( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
			if ( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
A
alteredq 已提交
6497

6498
			renderTarget.__webglTexture = _gl.createTexture();
A
alteredq 已提交
6499

6500
			// Setup texture, create render and frame buffers
6501

6502 6503
			var isTargetPowerOfTwo = isPowerOfTwo( renderTarget.width ) && isPowerOfTwo( renderTarget.height ),
				glFormat = paramThreeToGL( renderTarget.format ),
6504 6505
				glType = paramThreeToGL( renderTarget.type );

6506
			if ( isCube ) {
M
Mr.doob 已提交
6507

6508 6509
				renderTarget.__webglFramebuffer = [];
				renderTarget.__webglRenderbuffer = [];
M
Mikael Emtinger 已提交
6510

6511
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
6512
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, isTargetPowerOfTwo );
A
alteredq 已提交
6513

6514
				for ( var i = 0; i < 6; i ++ ) {
A
alteredq 已提交
6515

6516 6517
					renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
					renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
A
alteredq 已提交
6518

6519
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
A
alteredq 已提交
6520

6521 6522
					setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
					setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
A
alteredq 已提交
6523

6524
				}
6525

6526 6527
				if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

6528
			} else {
6529

6530 6531
				renderTarget.__webglFramebuffer = _gl.createFramebuffer();
				renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
6532

6533
				_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
6534
				setTextureParameters( _gl.TEXTURE_2D, renderTarget, isTargetPowerOfTwo );
6535

6536
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
6537

6538 6539
				setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
				setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
6540

6541 6542
				if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );

M
Mikael Emtinger 已提交
6543
			}
6544

6545
			// Release everything
M
Mr.doob 已提交
6546

A
alteredq 已提交
6547 6548 6549 6550 6551 6552 6553 6554 6555 6556
			if ( isCube ) {

				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

			} else {

				_gl.bindTexture( _gl.TEXTURE_2D, null );

			}

6557 6558
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
6559

6560 6561
		}

6562
		var framebuffer, width, height, vx, vy;
M
Mr.doob 已提交
6563

6564
		if ( renderTarget ) {
M
Mr.doob 已提交
6565

A
alteredq 已提交
6566 6567
			if ( isCube ) {

6568
				framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
A
alteredq 已提交
6569 6570 6571

			} else {

6572
				framebuffer = renderTarget.__webglFramebuffer;
A
alteredq 已提交
6573 6574 6575

			}

6576 6577
			width = renderTarget.width;
			height = renderTarget.height;
M
Mr.doob 已提交
6578

6579 6580 6581
			vx = 0;
			vy = 0;

6582
		} else {
M
Mr.doob 已提交
6583

6584
			framebuffer = null;
6585

6586 6587
			width = _viewportWidth;
			height = _viewportHeight;
6588

6589 6590
			vx = _viewportX;
			vy = _viewportY;
M
Mr.doob 已提交
6591

6592
		}
M
Mr.doob 已提交
6593

6594
		if ( framebuffer !== _currentFramebuffer ) {
M
Mr.doob 已提交
6595

6596
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
6597
			_gl.viewport( vx, vy, width, height );
M
Mr.doob 已提交
6598

6599
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
6600

6601
		}
6602

A
alteredq 已提交
6603 6604 6605
		_currentWidth = width;
		_currentHeight = height;

6606
	};
M
Mr.doob 已提交
6607

6608
	function updateRenderTargetMipmap ( renderTarget ) {
M
Mr.doob 已提交
6609

A
alteredq 已提交
6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622
		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 已提交
6623 6624

	};
6625

6626
	// Fallback filters for non-power-of-2 textures
6627

6628
	function filterFallback ( f ) {
6629

6630
		if ( f === THREE.NearestFilter || f === THREE.NearestMipMapNearestFilter || f === THREE.NearestMipMapLinearFilter ) {
6631

6632
			return _gl.NEAREST;
6633 6634

		}
6635

6636 6637
		return _gl.LINEAR;

6638
	};
6639

6640 6641
	// Map three.js constants to WebGL constants

6642
	function paramThreeToGL ( p ) {
M
Mr.doob 已提交
6643

6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689
		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 已提交
6690

6691 6692 6693 6694 6695 6696 6697 6698 6699
		if ( _glExtensionCompressedTextureS3TC !== undefined ) {

			if ( p === THREE.RGB_S3TC_DXT1_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGB_S3TC_DXT1_EXT;
			if ( p === THREE.RGBA_S3TC_DXT1_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT1_EXT;
			if ( p === THREE.RGBA_S3TC_DXT3_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT3_EXT;
			if ( p === THREE.RGBA_S3TC_DXT5_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT5_EXT;

		}

6700
		return 0;
M
Mr.doob 已提交
6701

6702 6703
	};

6704
	// Allocations
6705

6706
	function allocateBones ( object ) {
6707

6708
		if ( _supportsBoneTextures && object && object.useVertexTexture ) {
6709 6710

			return 1024;
6711

6712
		} else {
6713

6714 6715 6716 6717 6718 6719 6720
			// 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)
6721

6722 6723
			var nVertexUniforms = _gl.getParameter( _gl.MAX_VERTEX_UNIFORM_VECTORS );
			var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );
6724

6725
			var maxBones = nVertexMatrices;
6726

6727
			if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
6728

6729
				maxBones = Math.min( object.bones.length, maxBones );
6730

6731
				if ( maxBones < object.bones.length ) {
6732

6733
					console.warn( "WebGLRenderer: too many bones - " + object.bones.length + ", this GPU supports just " + maxBones + " (try OpenGL instead of ANGLE)" );
6734

6735
				}
6736

6737
			}
6738

6739
			return maxBones;
6740

6741 6742 6743
		}

	};
6744

6745
	function allocateLights ( lights ) {
6746

A
alteredq 已提交
6747
		var l, ll, light, dirLights, pointLights, spotLights, hemiLights, maxDirLights, maxPointLights, maxSpotLights, maxHemiLights;
6748

A
alteredq 已提交
6749
		dirLights = pointLights = spotLights = hemiLights = maxDirLights = maxPointLights = maxSpotLights = maxHemiLights = 0;
A
alteredq 已提交
6750 6751

		for ( l = 0, ll = lights.length; l < ll; l ++ ) {
6752

6753
			light = lights[ l ];
6754

A
alteredq 已提交
6755 6756
			if ( light.onlyShadow ) continue;

6757 6758
			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
			if ( light instanceof THREE.PointLight ) pointLights ++;
A
alteredq 已提交
6759
			if ( light instanceof THREE.SpotLight ) spotLights ++;
A
alteredq 已提交
6760
			if ( light instanceof THREE.HemisphereLight ) hemiLights ++;
6761

6762
		}
6763

A
alteredq 已提交
6764
		if ( ( pointLights + spotLights + dirLights + hemiLights) <= _maxLights ) {
6765

6766 6767
			maxDirLights = dirLights;
			maxPointLights = pointLights;
A
alteredq 已提交
6768
			maxSpotLights = spotLights;
A
alteredq 已提交
6769
			maxHemiLights = hemiLights;
6770

6771
		} else {
6772

6773 6774
			maxDirLights = Math.ceil( _maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = _maxLights - maxDirLights;
A
alteredq 已提交
6775 6776 6777 6778 6779

			// these are not really correct

			maxSpotLights = maxPointLights;
			maxHemiLights = maxDirLights;
6780 6781 6782

		}

A
alteredq 已提交
6783
		return { 'directional' : maxDirLights, 'point' : maxPointLights, 'spot': maxSpotLights, 'hemi': maxHemiLights };
6784 6785

	};
M
Mr.doob 已提交
6786

6787
	function allocateShadows ( lights ) {
6788

M
Mr.doob 已提交
6789
		var l, ll, light, maxShadows = 0;
6790 6791 6792 6793 6794

		for ( l = 0, ll = lights.length; l < ll; l++ ) {

			light = lights[ l ];

A
alteredq 已提交
6795 6796
			if ( ! light.castShadow ) continue;

6797 6798
			if ( light instanceof THREE.SpotLight ) maxShadows ++;
			if ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) maxShadows ++;
6799 6800 6801 6802 6803 6804 6805

		}

		return maxShadows;

	};

6806
	// Initialization
M
Mr.doob 已提交
6807

6808 6809 6810 6811
	function initGL () {

		try {

6812
			if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { alpha: _alpha, premultipliedAlpha: _premultipliedAlpha, antialias: _antialias, stencil: _stencil, preserveDrawingBuffer: _preserveDrawingBuffer } ) ) ) {
6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823

				throw 'Error creating WebGL context.';

			}

		} catch ( error ) {

			console.error( error );

		}

6824
		_glExtensionTextureFloat = _gl.getExtension( 'OES_texture_float' );
A
alteredq 已提交
6825 6826 6827 6828 6829 6830
		_glExtensionStandardDerivatives = _gl.getExtension( 'OES_standard_derivatives' );

		_glExtensionTextureFilterAnisotropic = _gl.getExtension( 'EXT_texture_filter_anisotropic' ) ||
											   _gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) ||
											   _gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );

6831

6832 6833 6834 6835
		_glExtensionCompressedTextureS3TC = _gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) ||
											_gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) ||
											_gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );

6836
		if ( ! _glExtensionTextureFloat ) {
6837 6838 6839 6840 6841

			console.log( 'THREE.WebGLRenderer: Float textures not supported.' );

		}

A
alteredq 已提交
6842
		if ( ! _glExtensionStandardDerivatives ) {
6843

A
alteredq 已提交
6844
			console.log( 'THREE.WebGLRenderer: Standard derivatives not supported.' );
6845

A
alteredq 已提交
6846
		}
6847

A
alteredq 已提交
6848
		if ( ! _glExtensionTextureFilterAnisotropic ) {
6849

A
alteredq 已提交
6850
			console.log( 'THREE.WebGLRenderer: Anisotropic texture filtering not supported.' );
6851 6852 6853

		}

6854 6855 6856 6857 6858 6859
		if ( ! _glExtensionCompressedTextureS3TC ) {

			console.log( 'THREE.WebGLRenderer: S3TC compressed textures not supported.' );

		}

6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 6881 6882
	};

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

	};

6883 6884
	// default plugins (order is important)

A
alteredq 已提交
6885 6886 6887 6888 6889
	this.shadowMapPlugin = new THREE.ShadowMapPlugin();
	this.addPrePlugin( this.shadowMapPlugin );

	this.addPostPlugin( new THREE.SpritePlugin() );
	this.addPostPlugin( new THREE.LensFlarePlugin() );
6890

6891
};