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

10
	// constructor parameters
M
Mr.doob 已提交
11

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

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

M
Mr.doob 已提交
16
	_precision = parameters.precision !== undefined ? parameters.precision : 'mediump',
17
	_antialias = parameters.antialias !== undefined ? parameters.antialias : false,
18
	_stencil = parameters.stencil !== undefined ? parameters.stencil : true,
19 20
	_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,

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

24
	_maxLights = parameters.maxLights !== undefined ? parameters.maxLights : 4;
25

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

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

	// clearing
M
Mr.doob 已提交
32

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

38 39
	// scene graph

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

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

	// physically based shading

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

51 52 53
	// shadow map

	this.shadowMapEnabled = false;
54
	this.shadowMapAutoUpdate = true;
55
	this.shadowMapSoft = true;
A
alteredq 已提交
56
	this.shadowMapCullFrontFaces = true;
57

58
	// morphs
59

60
	this.maxMorphTargets = 8;
61

62 63 64 65
	// flags

	this.autoScaleCubemaps = true;

66 67
	// custom render plugins

A
alteredq 已提交
68 69
	this.renderPluginsPre = [];
	this.renderPluginsPost = [];
70

71
	// info
72

73
	this.info = {
74

75
		memory: {
76

77 78 79
			programs: 0,
			geometries: 0,
			textures: 0
80

81
		},
82

83
		render: {
84

85 86
			calls: 0,
			vertices: 0,
87 88
			faces: 0,
			points: 0
89 90 91

		}

92
	};
M
Mr.doob 已提交
93

94
	// internal properties
95

96
	var _this = this,
97

98
	_gl,
99

100
	_programs = [],
101

102
	// internal state cache
103

104 105 106 107 108
	_currentProgram = null,
	_currentFramebuffer = null,
	_currentMaterialId = -1,
	_currentGeometryGroupHash = null,
	_geometryGroupCounter = 0,
109

110
	// GL state cache
111

112 113 114 115 116 117 118 119 120
	_oldDoubleSided = null,
	_oldFlipSided = null,
	_oldBlending = null,
	_oldDepthTest = null,
	_oldDepthWrite = null,
	_oldPolygonOffset = null,
	_oldPolygonOffsetFactor = null,
	_oldPolygonOffsetUnits = null,
	_oldLineWidth = null,
121

122 123 124 125
	_viewportX = 0,
	_viewportY = 0,
	_viewportWidth = 0,
	_viewportHeight = 0,
A
alteredq 已提交
126 127
	_currentWidth = 0,
	_currentHeight = 0,
128

A
alteredq 已提交
129
	// frustum
M
Mr.doob 已提交
130

A
alteredq 已提交
131
	_frustum = new THREE.Frustum(),
132

133
	 // camera matrices cache
M
Mikael Emtinger 已提交
134

135
	_projScreenMatrix = new THREE.Matrix4(),
M
Mr.doob 已提交
136

137
	_vector3 = new THREE.Vector4(),
M
Mikael Emtinger 已提交
138

139
	// light arrays cache
M
Mikael Emtinger 已提交
140

141
	_lights = {
M
Mr.doob 已提交
142

143 144 145
		ambient: [ 0, 0, 0 ],
		directional: { length: 0, colors: new Array(), positions: new Array() },
		point: { length: 0, colors: new Array(), positions: new Array(), distances: new Array() }
M
Mr.doob 已提交
146

147
	};
M
Mr.doob 已提交
148

149
	// initialize
M
Mikael Emtinger 已提交
150

151
	_gl = initGL();
M
Mikael Emtinger 已提交
152

153
	setDefaultGLState();
M
Mikael Emtinger 已提交
154

155
	this.context = _gl;
M
Mikael Emtinger 已提交
156

157 158 159 160 161
	// GPU capabilities

	var _maxVertexTextures = _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ),
	_maxTextureSize = _gl.getParameter( _gl.TEXTURE_SIZE ),
	_maxCubemapSize = _gl.getParameter( _gl.MAX_CUBE_MAP_TEXTURE_SIZE );
M
Mr.doob 已提交
162

163
	// API
M
Mr.doob 已提交
164

165
	this.getContext = function () {
M
Mr.doob 已提交
166

167
		return _gl;
M
Mr.doob 已提交
168

169
	};
M
Mr.doob 已提交
170

171
	this.supportsVertexTextures = function () {
M
Mikael Emtinger 已提交
172

173
		return _maxVertexTextures > 0;
M
Mikael Emtinger 已提交
174

175
	};
M
Mikael Emtinger 已提交
176

N
Nicolas Garcia Belmonte 已提交
177 178 179 180
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
181

182 183 184
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
185

186
	this.setViewport = function ( x, y, width, height ) {
187

188 189
		_viewportX = x;
		_viewportY = y;
190

191 192
		_viewportWidth = width;
		_viewportHeight = height;
193

194
		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
195

N
Nicolas Garcia Belmonte 已提交
196
	};
197

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

200
		_gl.scissor( x, y, width, height );
201

202
	};
203

204
	this.enableScissorTest = function ( enable ) {
205

M
Mr.doob 已提交
206
		enable ? _gl.enable( _gl.SCISSOR_TEST ) : _gl.disable( _gl.SCISSOR_TEST );
207 208

	};
209

210 211
	// Clearing

212
	this.setClearColorHex = function ( hex, alpha ) {
213

214 215 216 217
		_clearColor.setHex( hex );
		_clearAlpha = alpha;

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

219
	};
A
alteredq 已提交
220

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

223 224 225 226
		_clearColor.copy( color );
		_clearAlpha = alpha;

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

	};
229

M
Mr.doob 已提交
230 231 232 233 234 235 236
	this.getClearColor = function () {

		return _clearColor;

	};

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

M
Mr.doob 已提交
238 239 240 241 242 243 244 245
		return _clearAlpha;

	};

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

		var bits = 0;

246 247 248
		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 已提交
249 250

		_gl.clear( bits );
N
Nicolas Garcia Belmonte 已提交
251 252 253

	};

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

A
alteredq 已提交
256
		this.setRenderTarget( renderTarget );
257
		this.clear( color, depth, stencil );
M
Mr.doob 已提交
258 259 260

	};

261 262
	// Plugins

A
alteredq 已提交
263
	this.addPostPlugin = function ( plugin ) {
264 265

		plugin.init( this );
A
alteredq 已提交
266
		this.renderPluginsPost.push( plugin );
267 268 269

	};

A
alteredq 已提交
270 271 272 273 274 275
	this.addPrePlugin = function ( plugin ) {

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

	};
276

277 278
	// Deallocation

279 280 281 282 283 284 285 286 287 288 289 290 291 292
	this.deallocateObject = function ( object ) {

		if ( ! object.__webglInit ) return;

		object.__webglInit = false;

		delete object._modelViewMatrix;

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

		if ( object instanceof THREE.Mesh ) {

293
			for ( var g in object.geometry.geometryGroups ) {
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321

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

324 325
	};

326
	// Rendering
327

328
	this.updateShadowMap = function ( scene, camera ) {
329

A
alteredq 已提交
330 331 332 333 334 335 336 337
		_currentProgram = null;
		_oldBlending = -1;
		_oldDepthTest = -1;
		_oldDepthWrite = -1;
		_currentGeometryGroupHash = -1;
		_currentMaterialId = -1;

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

339
	};
M
Mr.doob 已提交
340

341
	// Internal functions
342

343
	// Buffer allocation
344

345
	function createParticleBuffers ( geometry ) {
346

347 348
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
349

350
		_this.info.geometries ++;
351

352
	};
353

354
	function createLineBuffers ( geometry ) {
355

356 357
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
358

359
		_this.info.memory.geometries ++;
360

361
	};
362

363
	function createRibbonBuffers ( geometry ) {
364

365 366
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
367

368
		_this.info.memory.geometries ++;
M
Mr.doob 已提交
369

370
	};
371

372
	function createMeshBuffers ( geometryGroup ) {
373

374 375 376 377 378 379
		geometryGroup.__webglVertexBuffer = _gl.createBuffer();
		geometryGroup.__webglNormalBuffer = _gl.createBuffer();
		geometryGroup.__webglTangentBuffer = _gl.createBuffer();
		geometryGroup.__webglColorBuffer = _gl.createBuffer();
		geometryGroup.__webglUVBuffer = _gl.createBuffer();
		geometryGroup.__webglUV2Buffer = _gl.createBuffer();
380

381 382 383 384
		geometryGroup.__webglSkinVertexABuffer = _gl.createBuffer();
		geometryGroup.__webglSkinVertexBBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinIndicesBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinWeightsBuffer = _gl.createBuffer();
385

386 387
		geometryGroup.__webglFaceBuffer = _gl.createBuffer();
		geometryGroup.__webglLineBuffer = _gl.createBuffer();
388

389
		if ( geometryGroup.numMorphTargets ) {
390

391
			var m, ml;
392

393
			geometryGroup.__webglMorphTargetsBuffers = [];
394

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

397
				geometryGroup.__webglMorphTargetsBuffers.push( _gl.createBuffer() );
398

399
			}
400

401
		}
402

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

405
	};
406

407
	// Buffer deallocation
408

409
	function deleteParticleBuffers ( geometry ) {
410

411 412
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
413

414
		_this.info.memory.geometries --;
415

416
	};
417

418
	function deleteLineBuffers ( geometry ) {
419

420 421
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
422

M
Mr.doob 已提交
423 424
		_this.info.memory.geometries --;

425 426
	};

427
	function deleteRibbonBuffers ( geometry ) {
428 429 430 431

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

M
Mr.doob 已提交
432 433
		_this.info.memory.geometries --;

434 435
	};

436
	function deleteMeshBuffers ( geometryGroup ) {
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454

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

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

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

		if ( geometryGroup.numMorphTargets ) {

455
			for ( var m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
456 457 458 459 460 461 462

				_gl.deleteBuffer( geometryGroup.__webglMorphTargetsBuffers[ m ] );

			}

		}

463 464 465 466 467 468 469 470 471 472 473

		if ( geometryGroup.__webglCustomAttributesList ) {

			for ( var id in geometryGroup.__webglCustomAttributesList ) {

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

			}

		}

M
Mr.doob 已提交
474 475
		_this.info.memory.geometries --;

476 477
	};

478
	// Buffer initialization
479

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

482 483
		var nvertices = geometry.vertices.length;

484
		var material = object.material;
485

486
		if ( material.attributes ) {
487

488
			if ( geometry.__webglCustomAttributesList === undefined ) {
489

490
				geometry.__webglCustomAttributesList = [];
491

492
			}
493

494
			for ( var a in material.attributes ) {
495

496
				var attribute = material.attributes[ a ];
497

498
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
499

500
					attribute.__webglInitialized = true;
501

A
alteredq 已提交
502
					var size = 1;		// "f" and "i"
503

504 505 506 507
					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;
508

509
					attribute.size = size;
A
alteredq 已提交
510

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

513 514
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
515

516
					attribute.needsUpdate = true;
517

518
				}
519

520
				geometry.__webglCustomAttributesList.push( attribute );
521

522
			}
523

524
		}
525

526
	};
527

528
	function initParticleBuffers ( geometry, object ) {
A
alteredq 已提交
529 530 531 532 533 534

		var nvertices = geometry.vertices.length;

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

535 536 537
		geometry.__sortArray = [];

		geometry.__webglParticleCount = nvertices;
A
alteredq 已提交
538 539 540 541 542

		initCustomAttributes ( geometry, object );

	};

543
	function initLineBuffers ( geometry, object ) {
A
alteredq 已提交
544 545 546 547 548 549

		var nvertices = geometry.vertices.length;

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

550
		geometry.__webglLineCount = nvertices;
A
alteredq 已提交
551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566

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

569 570 571
		var geometry = object.geometry,
			faces3 = geometryGroup.faces3,
			faces4 = geometryGroup.faces4,
M
Mr.doob 已提交
572

573 574 575
			nvertices = faces3.length * 3 + faces4.length * 4,
			ntris     = faces3.length * 1 + faces4.length * 2,
			nlines    = faces3.length * 3 + faces4.length * 4,
576

577
			material = getBufferMaterial( object, geometryGroup ),
578

579 580 581
			uvType = bufferGuessUVType( material ),
			normalType = bufferGuessNormalType( material ),
			vertexColorType = bufferGuessVertexColorType( material );
A
alteredq 已提交
582

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

585
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
586

587
		if ( normalType ) {
M
Mr.doob 已提交
588

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

591
		}
592

593
		if ( geometry.hasTangents ) {
594

595
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
596

597
		}
598

599
		if ( vertexColorType ) {
600

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

603
		}
M
Mr.doob 已提交
604

605
		if ( uvType ) {
606

607
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
608

609 610 611 612 613
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

615 616 617 618 619 620 621 622 623 624 625 626 627 628 629
				geometryGroup.__uv2Array = new Float32Array( nvertices * 2 );

			}

		}

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

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

		}

630
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
631
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
632

633 634
		if ( geometryGroup.numMorphTargets ) {

M
Mr.doob 已提交
635
			geometryGroup.__morphTargetsArrays = [];
636

637
			for ( var m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
638

639 640
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );

641 642 643
			}

		}
644

645
		geometryGroup.__webglFaceCount = ntris * 3;
646
		geometryGroup.__webglLineCount = nlines * 2;
647

M
Mr.doob 已提交
648

649
		// custom attributes
M
Mr.doob 已提交
650

651
		if ( material.attributes ) {
652

653
			if ( geometryGroup.__webglCustomAttributesList === undefined ) {
654

655
				geometryGroup.__webglCustomAttributesList = [];
656

657
			}
658

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

661 662
				// Do a shallow copy of the attribute object so different geometryGroup chunks use different
				// attribute buffers which are correctly indexed in the setMeshBuffers function
663

664
				var originalAttribute = material.attributes[ a ];
665

666
				var attribute = {};
667

668
				for ( var property in originalAttribute ) {
M
Mr.doob 已提交
669

670
					attribute[ property ] = originalAttribute[ property ];
671

672
				}
673

674
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
675

676
					attribute.__webglInitialized = true;
677

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

680 681 682 683
					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;
684

685
					attribute.size = size;
A
alteredq 已提交
686

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

689 690
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
691

692 693
					originalAttribute.needsUpdate = true;
					attribute.__original = originalAttribute;
694 695 696

				}

697 698
				geometryGroup.__webglCustomAttributesList.push( attribute );

699
			}
M
Mr.doob 已提交
700

701
		}
702

703 704
		geometryGroup.__inittedArrays = true;

705
	};
M
Mr.doob 已提交
706

707
	function getBufferMaterial( object, geometryGroup ) {
708

709
		if ( object.material && ! ( object.material instanceof THREE.MeshFaceMaterial ) ) {
710

711
			return object.material;
712

713
		} else if ( geometryGroup.materialIndex >= 0 ) {
714

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

717
		}
718

719
	};
M
Mr.doob 已提交
720

721
	function materialNeedsSmoothNormals ( material ) {
722

723
		return material && material.shading !== undefined && material.shading === THREE.SmoothShading;
724

725
	};
M
Mr.doob 已提交
726

727
	function bufferGuessNormalType ( material ) {
728

729
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
730

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

733
			return false;
734

735
		}
736

737
		if ( materialNeedsSmoothNormals( material ) ) {
738

739
			return THREE.SmoothShading;
M
Mr.doob 已提交
740

741
		} else {
742

743
			return THREE.FlatShading;
744

745
		}
746

747
	};
748

749
	function bufferGuessVertexColorType ( material ) {
750

751
		if ( material.vertexColors ) {
752

753
			return material.vertexColors;
754

755
		}
M
Mr.doob 已提交
756

757
		return false;
M
Mr.doob 已提交
758

759
	};
M
Mr.doob 已提交
760

761
	function bufferGuessUVType ( material ) {
762

763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 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
		// material must use some texture to require uvs

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

			return true;

		}

		return false;

	};

	// Buffer setting

	function setParticleBuffers ( geometry, hint, object ) {

		var v, c, vertex, offset, index, color,

		vertices = geometry.vertices,
		vl = vertices.length,

		colors = geometry.colors,
		cl = colors.length,

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

		sortArray = geometry.__sortArray,

		dirtyVertices = geometry.__dirtyVertices,
		dirtyElements = geometry.__dirtyElements,
		dirtyColors = geometry.__dirtyColors,

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

		if ( object.sortParticles ) {

			_projScreenMatrix.multiplySelf( object.matrixWorld );

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

				vertex = vertices[ v ].position;

				_vector3.copy( vertex );
				_projScreenMatrix.multiplyVector3( _vector3 );

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

			}

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

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

				vertex = vertices[ sortArray[v][1] ].position;

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

					vertex = vertices[ v ].position;

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

		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors,

		customAttributes = geometry.__webglCustomAttributesList,

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

		if ( dirtyVertices ) {

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

				vertex = vertices[ v ].position;

				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,

		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors;

		if ( dirtyVertices ) {

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

				vertex = vertices[ v ].position;

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

		}

	};

1307
	function setMeshBuffers( geometryGroup, object, hint, dispose, material ) {
1308 1309 1310 1311 1312 1313 1314 1315

		if ( ! geometryGroup.__inittedArrays ) {

			// console.log( object );
			return;

		}

1316 1317 1318 1319 1320 1321
		var normalType = bufferGuessNormalType( material ),
		vertexColorType = bufferGuessVertexColorType( material ),
		uvType = bufferGuessUVType( material ),

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

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
		var f, fl, fi, face,
		vertexNormals, faceNormal, normal,
		vertexColors, faceColor,
		vertexTangents,
		uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4,
		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,

		vertexIndex = 0,

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

		value,

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

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

		morphTargetsArrays = geometryGroup.__morphTargetsArrays,

		customAttributes = geometryGroup.__webglCustomAttributesList,
		customAttribute,

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

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

		dirtyVertices = geometry.__dirtyVertices,
		dirtyElements = geometry.__dirtyElements,
		dirtyUvs = geometry.__dirtyUvs,
		dirtyNormals = geometry.__dirtyNormals,
		dirtyTangents = geometry.__dirtyTangents,
		dirtyColors = geometry.__dirtyColors,
		dirtyMorphTargets = geometry.__dirtyMorphTargets,

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

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

		obj_colors = geometry.colors,

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

		morphTargets = geometry.morphTargets;

		if ( dirtyVertices ) {

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

				face = obj_faces[ chunk_faces3[ f ] ];

				v1 = vertices[ face.a ].position;
				v2 = vertices[ face.b ].position;
				v3 = vertices[ face.c ].position;

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

1423
				offset += 9;
M
Mr.doob 已提交
1424

1425
			}
1426

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

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

A
alteredq 已提交
1431 1432 1433 1434
				v1 = vertices[ face.a ].position;
				v2 = vertices[ face.b ].position;
				v3 = vertices[ face.c ].position;
				v4 = vertices[ face.d ].position;
1435

A
alteredq 已提交
1436 1437 1438
				vertexArray[ offset ]     = v1.x;
				vertexArray[ offset + 1 ] = v1.y;
				vertexArray[ offset + 2 ] = v1.z;
1439

A
alteredq 已提交
1440 1441 1442
				vertexArray[ offset + 3 ] = v2.x;
				vertexArray[ offset + 4 ] = v2.y;
				vertexArray[ offset + 5 ] = v2.z;
1443

A
alteredq 已提交
1444 1445 1446
				vertexArray[ offset + 6 ] = v3.x;
				vertexArray[ offset + 7 ] = v3.y;
				vertexArray[ offset + 8 ] = v3.z;
1447

A
alteredq 已提交
1448 1449 1450
				vertexArray[ offset + 9 ]  = v4.x;
				vertexArray[ offset + 10 ] = v4.y;
				vertexArray[ offset + 11 ] = v4.z;
1451

A
alteredq 已提交
1452
				offset += 12;
1453

A
alteredq 已提交
1454
			}
1455

A
alteredq 已提交
1456 1457
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1458

A
alteredq 已提交
1459
		}
M
Mr.doob 已提交
1460

A
alteredq 已提交
1461
		if ( dirtyMorphTargets ) {
M
Mr.doob 已提交
1462

1463
			for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {
1464

1465
				offset_morphTarget = 0;
1466

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

					face = obj_faces[ chunk_faces3[ f ]	];
M
Mr.doob 已提交
1470

A
alteredq 已提交
1471 1472 1473
					v1 = morphTargets[ vk ].vertices[ face.a ].position;
					v2 = morphTargets[ vk ].vertices[ face.b ].position;
					v3 = morphTargets[ vk ].vertices[ face.c ].position;
M
Mr.doob 已提交
1474

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

A
alteredq 已提交
1477 1478 1479
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
M
Mr.doob 已提交
1480

A
alteredq 已提交
1481 1482 1483
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
M
Mr.doob 已提交
1484

A
alteredq 已提交
1485 1486 1487
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
M
Mr.doob 已提交
1488

1489
					offset_morphTarget += 9;
1490

1491
				}
1492

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

1495
					face = obj_faces[ chunk_faces4[ f ] ];
1496

1497 1498 1499
					v1 = morphTargets[ vk ].vertices[ face.a ].position;
					v2 = morphTargets[ vk ].vertices[ face.b ].position;
					v3 = morphTargets[ vk ].vertices[ face.c ].position;
A
alteredq 已提交
1500
					v4 = morphTargets[ vk ].vertices[ face.d ].position;
1501

1502
					vka = morphTargetsArrays[ vk ];
1503

1504 1505 1506
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
1507

1508 1509 1510
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
1511

1512 1513 1514
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
1515

A
alteredq 已提交
1516 1517 1518 1519
					vka[ offset_morphTarget + 9 ]  = v4.x;
					vka[ offset_morphTarget + 10 ] = v4.y;
					vka[ offset_morphTarget + 11 ] = v4.z;

1520
					offset_morphTarget += 12;
A
alteredq 已提交
1521

1522
				}
A
alteredq 已提交
1523 1524 1525

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

1527
			}
1528

A
alteredq 已提交
1529 1530 1531 1532 1533 1534 1535
		}

		if ( obj_skinWeights.length ) {

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

				face = obj_faces[ chunk_faces3[ f ]	];
1536

1537
				// weights
A
alteredq 已提交
1538

1539 1540 1541
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
A
alteredq 已提交
1542

1543 1544 1545 1546
				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 已提交
1547

1548 1549 1550 1551
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1552

1553 1554 1555 1556
				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 已提交
1557

1558
				// indices
A
alteredq 已提交
1559

1560 1561 1562
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
A
alteredq 已提交
1563

1564 1565 1566 1567
				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 已提交
1568

1569 1570 1571 1572
				skinIndexArray[ offset_skin + 4 ] = si2.x;
				skinIndexArray[ offset_skin + 5 ] = si2.y;
				skinIndexArray[ offset_skin + 6 ] = si2.z;
				skinIndexArray[ offset_skin + 7 ] = si2.w;
1573

1574 1575 1576 1577
				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 已提交
1578

1579
				// vertices A
A
alteredq 已提交
1580

1581 1582 1583
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
A
alteredq 已提交
1584

1585 1586 1587 1588
				skinVertexAArray[ offset_skin ]     = sa1.x;
				skinVertexAArray[ offset_skin + 1 ] = sa1.y;
				skinVertexAArray[ offset_skin + 2 ] = sa1.z;
				skinVertexAArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
A
alteredq 已提交
1589

1590 1591 1592 1593
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1594

1595 1596 1597 1598
				skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
				skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
				skinVertexAArray[ offset_skin + 10 ] = sa3.z;
				skinVertexAArray[ offset_skin + 11 ] = 1;
A
alteredq 已提交
1599

1600
				// vertices B
A
alteredq 已提交
1601

1602 1603 1604
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
A
alteredq 已提交
1605

1606 1607 1608 1609
				skinVertexBArray[ offset_skin ]     = sb1.x;
				skinVertexBArray[ offset_skin + 1 ] = sb1.y;
				skinVertexBArray[ offset_skin + 2 ] = sb1.z;
				skinVertexBArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
A
alteredq 已提交
1610

1611 1612 1613 1614
				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
				skinVertexBArray[ offset_skin + 7 ] = 1;
1615

1616 1617 1618 1619
				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
				skinVertexBArray[ offset_skin + 11 ] = 1;
1620

1621
				offset_skin += 12;
1622

1623
			}
1624

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

A
alteredq 已提交
1627
				face = obj_faces[ chunk_faces4[ f ] ];
1628

A
alteredq 已提交
1629
				// weights
1630

A
alteredq 已提交
1631 1632 1633 1634
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
				sw4 = obj_skinWeights[ face.d ];
1635

A
alteredq 已提交
1636 1637 1638 1639
				skinWeightArray[ offset_skin ]     = sw1.x;
				skinWeightArray[ offset_skin + 1 ] = sw1.y;
				skinWeightArray[ offset_skin + 2 ] = sw1.z;
				skinWeightArray[ offset_skin + 3 ] = sw1.w;
1640

A
alteredq 已提交
1641 1642 1643 1644
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1645

A
alteredq 已提交
1646 1647 1648 1649
				skinWeightArray[ offset_skin + 8 ]  = sw3.x;
				skinWeightArray[ offset_skin + 9 ]  = sw3.y;
				skinWeightArray[ offset_skin + 10 ] = sw3.z;
				skinWeightArray[ offset_skin + 11 ] = sw3.w;
1650

A
alteredq 已提交
1651 1652 1653 1654
				skinWeightArray[ offset_skin + 12 ] = sw4.x;
				skinWeightArray[ offset_skin + 13 ] = sw4.y;
				skinWeightArray[ offset_skin + 14 ] = sw4.z;
				skinWeightArray[ offset_skin + 15 ] = sw4.w;
1655

A
alteredq 已提交
1656
				// indices
1657

A
alteredq 已提交
1658 1659 1660 1661
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
				si4 = obj_skinIndices[ face.d ];
1662

A
alteredq 已提交
1663 1664 1665 1666
				skinIndexArray[ offset_skin ]     = si1.x;
				skinIndexArray[ offset_skin + 1 ] = si1.y;
				skinIndexArray[ offset_skin + 2 ] = si1.z;
				skinIndexArray[ offset_skin + 3 ] = si1.w;
1667

A
alteredq 已提交
1668 1669 1670 1671
				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 已提交
1672

A
alteredq 已提交
1673 1674 1675 1676
				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 已提交
1677

A
alteredq 已提交
1678 1679 1680 1681
				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 已提交
1682

A
alteredq 已提交
1683
				// vertices A
M
Mr.doob 已提交
1684

A
alteredq 已提交
1685 1686 1687 1688
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
				sa4 = obj_skinVerticesA[ face.d ];
1689

A
alteredq 已提交
1690 1691 1692 1693
				skinVertexAArray[ offset_skin ]     = sa1.x;
				skinVertexAArray[ offset_skin + 1 ] = sa1.y;
				skinVertexAArray[ offset_skin + 2 ] = sa1.z;
				skinVertexAArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
M
Mr.doob 已提交
1694

A
alteredq 已提交
1695 1696 1697 1698
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1699

A
alteredq 已提交
1700 1701 1702 1703
				skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
				skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
				skinVertexAArray[ offset_skin + 10 ] = sa3.z;
				skinVertexAArray[ offset_skin + 11 ] = 1;
1704

A
alteredq 已提交
1705 1706 1707 1708
				skinVertexAArray[ offset_skin + 12 ] = sa4.x;
				skinVertexAArray[ offset_skin + 13 ] = sa4.y;
				skinVertexAArray[ offset_skin + 14 ] = sa4.z;
				skinVertexAArray[ offset_skin + 15 ] = 1;
M
Mr.doob 已提交
1709

A
alteredq 已提交
1710
				// vertices B
M
Mr.doob 已提交
1711

A
alteredq 已提交
1712 1713 1714 1715
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
				sb4 = obj_skinVerticesB[ face.d ];
M
Mr.doob 已提交
1716

A
alteredq 已提交
1717 1718 1719 1720
				skinVertexBArray[ offset_skin ]     = sb1.x;
				skinVertexBArray[ offset_skin + 1 ] = sb1.y;
				skinVertexBArray[ offset_skin + 2 ] = sb1.z;
				skinVertexBArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
M
Mr.doob 已提交
1721

A
alteredq 已提交
1722 1723 1724 1725
				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
				skinVertexBArray[ offset_skin + 7 ] = 1;
1726

A
alteredq 已提交
1727 1728 1729 1730
				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
				skinVertexBArray[ offset_skin + 11 ] = 1;
1731

A
alteredq 已提交
1732 1733 1734 1735
				skinVertexBArray[ offset_skin + 12 ] = sb4.x;
				skinVertexBArray[ offset_skin + 13 ] = sb4.y;
				skinVertexBArray[ offset_skin + 14 ] = sb4.z;
				skinVertexBArray[ offset_skin + 15 ] = 1;
1736

A
alteredq 已提交
1737
				offset_skin += 16;
M
Mr.doob 已提交
1738

A
alteredq 已提交
1739
			}
M
Mr.doob 已提交
1740

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

A
alteredq 已提交
1743 1744
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );
M
Mr.doob 已提交
1745

A
alteredq 已提交
1746 1747 1748 1749 1750 1751 1752 1753
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );

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

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

1755
			}
1756

A
alteredq 已提交
1757
		}
M
Mr.doob 已提交
1758

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

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

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

A
alteredq 已提交
1765 1766
				vertexColors = face.vertexColors;
				faceColor = face.color;
1767

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

A
alteredq 已提交
1770 1771 1772
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
1773

A
alteredq 已提交
1774
				} else {
1775

A
alteredq 已提交
1776 1777 1778
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
1779

A
alteredq 已提交
1780
				}
1781

A
alteredq 已提交
1782 1783 1784
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
1785

A
alteredq 已提交
1786 1787 1788
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
1789

A
alteredq 已提交
1790 1791 1792
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
1793

A
alteredq 已提交
1794
				offset_color += 9;
M
Mr.doob 已提交
1795

A
alteredq 已提交
1796
			}
M
Mr.doob 已提交
1797

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

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

A
alteredq 已提交
1802 1803
				vertexColors = face.vertexColors;
				faceColor = face.color;
M
Mr.doob 已提交
1804

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

A
alteredq 已提交
1807 1808 1809 1810
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
					c4 = vertexColors[ 3 ];
1811

A
alteredq 已提交
1812
				} else {
M
Mr.doob 已提交
1813

A
alteredq 已提交
1814 1815 1816 1817
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
					c4 = faceColor;
M
Mr.doob 已提交
1818

A
alteredq 已提交
1819
				}
1820

A
alteredq 已提交
1821 1822 1823
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
1824

A
alteredq 已提交
1825 1826 1827
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
M
Mr.doob 已提交
1828

A
alteredq 已提交
1829 1830 1831
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
M
Mr.doob 已提交
1832

A
alteredq 已提交
1833 1834 1835
				colorArray[ offset_color + 9 ]  = c4.r;
				colorArray[ offset_color + 10 ] = c4.g;
				colorArray[ offset_color + 11 ] = c4.b;
M
Mr.doob 已提交
1836

A
alteredq 已提交
1837
				offset_color += 12;
1838

1839
			}
1840

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

A
alteredq 已提交
1843 1844
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
M
Mr.doob 已提交
1845

1846
			}
1847

A
alteredq 已提交
1848
		}
M
Mr.doob 已提交
1849

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

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

A
alteredq 已提交
1854
				face = obj_faces[ chunk_faces3[ f ]	];
1855

A
alteredq 已提交
1856
				vertexTangents = face.vertexTangents;
M
Mr.doob 已提交
1857

A
alteredq 已提交
1858 1859 1860
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
1861

A
alteredq 已提交
1862 1863 1864 1865
				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 已提交
1866

A
alteredq 已提交
1867 1868 1869 1870
				tangentArray[ offset_tangent + 4 ] = t2.x;
				tangentArray[ offset_tangent + 5 ] = t2.y;
				tangentArray[ offset_tangent + 6 ] = t2.z;
				tangentArray[ offset_tangent + 7 ] = t2.w;
1871

A
alteredq 已提交
1872 1873 1874 1875
				tangentArray[ offset_tangent + 8 ]  = t3.x;
				tangentArray[ offset_tangent + 9 ]  = t3.y;
				tangentArray[ offset_tangent + 10 ] = t3.z;
				tangentArray[ offset_tangent + 11 ] = t3.w;
1876

A
alteredq 已提交
1877
				offset_tangent += 12;
1878

1879
			}
1880

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

A
alteredq 已提交
1883
				face = obj_faces[ chunk_faces4[ f ] ];
1884

A
alteredq 已提交
1885
				vertexTangents = face.vertexTangents;
1886

A
alteredq 已提交
1887 1888 1889 1890
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
				t4 = vertexTangents[ 3 ];
1891

A
alteredq 已提交
1892 1893 1894 1895
				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 已提交
1896

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

A
alteredq 已提交
1902 1903 1904 1905
				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 已提交
1906

A
alteredq 已提交
1907 1908 1909 1910
				tangentArray[ offset_tangent + 12 ] = t4.x;
				tangentArray[ offset_tangent + 13 ] = t4.y;
				tangentArray[ offset_tangent + 14 ] = t4.z;
				tangentArray[ offset_tangent + 15 ] = t4.w;
1911

A
alteredq 已提交
1912
				offset_tangent += 16;
1913

A
alteredq 已提交
1914
			}
1915

A
alteredq 已提交
1916 1917
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
1918

A
alteredq 已提交
1919
		}
1920

A
alteredq 已提交
1921
		if ( dirtyNormals && normalType ) {
1922

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

A
alteredq 已提交
1925
				face = obj_faces[ chunk_faces3[ f ]	];
1926

A
alteredq 已提交
1927 1928
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
1929

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

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

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

A
alteredq 已提交
1936 1937 1938
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
1939

A
alteredq 已提交
1940
						offset_normal += 3;
1941

A
alteredq 已提交
1942
					}
1943

A
alteredq 已提交
1944
				} else {
M
Mr.doob 已提交
1945

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

A
alteredq 已提交
1948 1949 1950
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
1951

A
alteredq 已提交
1952
						offset_normal += 3;
M
Mr.doob 已提交
1953

A
alteredq 已提交
1954
					}
1955

A
alteredq 已提交
1956
				}
1957

A
alteredq 已提交
1958
			}
1959

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

A
alteredq 已提交
1962
				face = obj_faces[ chunk_faces4[ f ] ];
1963

A
alteredq 已提交
1964 1965
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
1966

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

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

A
alteredq 已提交
1971
						vn = vertexNormals[ i ];
1972

A
alteredq 已提交
1973 1974 1975
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
1976

A
alteredq 已提交
1977
						offset_normal += 3;
1978

A
alteredq 已提交
1979
					}
M
Mr.doob 已提交
1980

A
alteredq 已提交
1981
				} else {
1982

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

A
alteredq 已提交
1985 1986 1987
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1988

A
alteredq 已提交
1989
						offset_normal += 3;
M
Mr.doob 已提交
1990

A
alteredq 已提交
1991
					}
1992

A
alteredq 已提交
1993
				}
1994

A
alteredq 已提交
1995
			}
M
Mr.doob 已提交
1996

A
alteredq 已提交
1997 1998
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
1999

A
alteredq 已提交
2000
		}
M
Mr.doob 已提交
2001

A
alteredq 已提交
2002
		if ( dirtyUvs && obj_uvs && uvType ) {
2003

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

A
alteredq 已提交
2006
				fi = chunk_faces3[ f ];
2007

A
alteredq 已提交
2008 2009
				face = obj_faces[ fi ];
				uv = obj_uvs[ fi ];
2010

A
alteredq 已提交
2011
				if ( uv === undefined ) continue;
2012

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

A
alteredq 已提交
2015
					uvi = uv[ i ];
2016

A
alteredq 已提交
2017 2018
					uvArray[ offset_uv ]     = uvi.u;
					uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
2019

A
alteredq 已提交
2020
					offset_uv += 2;
M
Mr.doob 已提交
2021

A
alteredq 已提交
2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042
				}

			}

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

				fi = chunk_faces4[ f ];

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

				if ( uv === undefined ) continue;

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

					uvi = uv[ i ];

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

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

2044 2045
				}

2046
			}
2047

A
alteredq 已提交
2048
			if ( offset_uv > 0 ) {
2049

A
alteredq 已提交
2050 2051
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
2052

A
alteredq 已提交
2053
			}
2054

A
alteredq 已提交
2055
		}
2056

A
alteredq 已提交
2057
		if ( dirtyUvs && obj_uvs2 && uvType ) {
2058

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

A
alteredq 已提交
2061
				fi = chunk_faces3[ f ];
2062

A
alteredq 已提交
2063 2064
				face = obj_faces[ fi ];
				uv2 = obj_uvs2[ fi ];
2065

A
alteredq 已提交
2066 2067 2068 2069 2070 2071 2072 2073 2074 2075
				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;
2076

2077 2078
				}

A
alteredq 已提交
2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099
			}

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

				fi = chunk_faces4[ f ];

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

				if ( uv2 === undefined ) continue;

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

					uv2i = uv2[ i ];

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

					offset_uv2 += 2;

				}
2100

2101
			}
2102

A
alteredq 已提交
2103
			if ( offset_uv2 > 0 ) {
2104

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

A
alteredq 已提交
2108
			}
2109

A
alteredq 已提交
2110
		}
2111

A
alteredq 已提交
2112
		if ( dirtyElements ) {
2113

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

A
alteredq 已提交
2116
				face = obj_faces[ chunk_faces3[ f ]	];
2117

A
alteredq 已提交
2118 2119 2120
				faceArray[ offset_face ] 	 = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 2;
2121

A
alteredq 已提交
2122
				offset_face += 3;
2123

A
alteredq 已提交
2124 2125
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2126

A
alteredq 已提交
2127 2128
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 2;
2129

A
alteredq 已提交
2130 2131
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
2132

A
alteredq 已提交
2133
				offset_line += 6;
2134

A
alteredq 已提交
2135
				vertexIndex += 3;
2136

A
alteredq 已提交
2137
			}
2138

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

A
alteredq 已提交
2141
				face = obj_faces[ chunk_faces4[ f ] ];
2142

A
alteredq 已提交
2143 2144 2145
				faceArray[ offset_face ]     = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 3;
2146

A
alteredq 已提交
2147 2148 2149
				faceArray[ offset_face + 3 ] = vertexIndex + 1;
				faceArray[ offset_face + 4 ] = vertexIndex + 2;
				faceArray[ offset_face + 5 ] = vertexIndex + 3;
2150

A
alteredq 已提交
2151
				offset_face += 6;
2152

A
alteredq 已提交
2153 2154
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2155

A
alteredq 已提交
2156 2157
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 3;
2158

A
alteredq 已提交
2159 2160
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
2161

A
alteredq 已提交
2162 2163
				lineArray[ offset_line + 6 ] = vertexIndex + 2;
				lineArray[ offset_line + 7 ] = vertexIndex + 3;
2164

A
alteredq 已提交
2165
				offset_line += 8;
2166

A
alteredq 已提交
2167
				vertexIndex += 4;
2168

2169
			}
2170

A
alteredq 已提交
2171 2172
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
2173

A
alteredq 已提交
2174 2175
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
2176

A
alteredq 已提交
2177
		}
2178

A
alteredq 已提交
2179
		if ( customAttributes ) {
2180

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

2183
				customAttribute = customAttributes[ i ];
2184

2185
				if ( ! customAttribute.__original.needsUpdate ) continue;
2186

2187 2188
				offset_custom = 0;
				offset_customSrc = 0;
2189

2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222
				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 ++ ) {

2223
							value = customAttribute.value[ chunk_faces3[ f ] ];
2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234

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

2235
							value = customAttribute.value[ chunk_faces4[ f ] ];
2236 2237 2238 2239 2240 2241 2242 2243 2244

							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;

						}
2245

2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264
					}

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

2266 2267
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2268

2269
							offset_custom += 6;
A
alteredq 已提交
2270

2271
						}
A
alteredq 已提交
2272

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

2275
							face = obj_faces[ chunk_faces4[ f ] ];
A
alteredq 已提交
2276

2277 2278 2279 2280
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
A
alteredq 已提交
2281

2282 2283
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2284

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

2288 2289
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2290

2291 2292
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
A
alteredq 已提交
2293

2294
							offset_custom += 8;
A
alteredq 已提交
2295

2296
						}
A
alteredq 已提交
2297

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

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

2302
							value = customAttribute.value[ chunk_faces3[ f ] ];
A
alteredq 已提交
2303

2304 2305 2306
							v1 = value;
							v2 = value;
							v3 = value;
A
alteredq 已提交
2307

2308 2309
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2310

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

2314 2315
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2316

2317
							offset_custom += 6;
A
alteredq 已提交
2318

2319
						}
A
alteredq 已提交
2320

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

2323
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2324

2325 2326 2327 2328
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2329

2330 2331
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2332

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

2336 2337
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2338

2339 2340
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
2341

2342
							offset_custom += 8;
M
Mr.doob 已提交
2343

2344
						}
M
Mr.doob 已提交
2345

M
Mr.doob 已提交
2346
					}
M
Mr.doob 已提交
2347

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

2350
					var pp;
2351

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

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

2356
					} else {
M
Mr.doob 已提交
2357

2358
						pp = [ "x", "y", "z" ];
2359

2360
					}
2361

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

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

2366
							face = obj_faces[ chunk_faces3[ f ]	];
2367

2368 2369 2370
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
2371

2372 2373 2374
							customAttribute.array[ offset_custom ] 	   = v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
2375

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

2380 2381 2382
							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 已提交
2383

2384
							offset_custom += 9;
M
Mr.doob 已提交
2385

2386
						}
M
Mr.doob 已提交
2387

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

2390
							face = obj_faces[ chunk_faces4[ f ] ];
M
Mr.doob 已提交
2391

2392 2393 2394 2395
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
M
Mr.doob 已提交
2396

2397 2398 2399
							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 已提交
2400

2401 2402 2403
							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 已提交
2404

2405 2406 2407
							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 已提交
2408

2409 2410 2411
							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 已提交
2412

2413
							offset_custom += 12;
M
Mr.doob 已提交
2414

2415
						}
M
Mr.doob 已提交
2416

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

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

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

2423 2424 2425
							v1 = value;
							v2 = value;
							v3 = value;
M
Mr.doob 已提交
2426

2427 2428 2429
							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 已提交
2430

2431 2432 2433
							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 已提交
2434

2435 2436 2437
							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 已提交
2438

2439
							offset_custom += 9;
M
Mr.doob 已提交
2440

2441
						}
2442

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

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

2447 2448 2449 2450
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
2451

2452 2453 2454
							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
2455

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

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

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

2468
							offset_custom += 12;
2469

2470
						}
2471

A
alteredq 已提交
2472
					}
M
Mr.doob 已提交
2473

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

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

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

2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541
							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 ++ ) {

2542
							value = customAttribute.value[ chunk_faces3[ f ] ];
2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559

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

2563
							offset_custom += 12;
A
alteredq 已提交
2564

2565 2566
						}

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

2569
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2570

2571 2572 2573 2574
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2575

2576 2577 2578 2579
							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;
2580

2581 2582 2583 2584
							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;
2585

2586 2587 2588 2589
							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;
2590

2591 2592 2593 2594
							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;
2595

2596
							offset_custom += 16;
A
alteredq 已提交
2597

2598
						}
A
alteredq 已提交
2599 2600 2601 2602 2603

					}

				}

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

A
alteredq 已提交
2607 2608 2609 2610
			}

		}

2611
		if ( dispose ) {
2612

2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625
			delete geometryGroup.__inittedArrays;
			delete geometryGroup.__colorArray;
			delete geometryGroup.__normalArray;
			delete geometryGroup.__tangentArray;
			delete geometryGroup.__uvArray;
			delete geometryGroup.__uv2Array;
			delete geometryGroup.__faceArray;
			delete geometryGroup.__vertexArray;
			delete geometryGroup.__lineArray;
			delete geometryGroup.__skinVertexAArray;
			delete geometryGroup.__skinVertexBArray;
			delete geometryGroup.__skinIndexArray;
			delete geometryGroup.__skinWeightArray;
A
alteredq 已提交
2626

2627
		}
A
alteredq 已提交
2628

2629
	};
A
alteredq 已提交
2630

2631
	// Buffer rendering
A
alteredq 已提交
2632

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

2635 2636
		if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
A
alteredq 已提交
2637

2638
		if ( object.hasPos ) {
A
alteredq 已提交
2639

2640 2641 2642 2643
			_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 已提交
2644 2645 2646

		}

2647
		if ( object.hasNormal ) {
A
alteredq 已提交
2648

2649
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
A
alteredq 已提交
2650

2651
			if ( shading === THREE.FlatShading ) {
2652

2653 2654 2655 2656
				var nx, ny, nz,
					nax, nbx, ncx, nay, nby, ncy, naz, nbz, ncz,
					normalArray,
					i, il = object.count * 3;
2657

2658
				for( i = 0; i < il; i += 9 ) {
2659

2660
					normalArray = object.normalArray;
2661

2662 2663 2664
					nax  = normalArray[ i ];
					nay  = normalArray[ i + 1 ];
					naz  = normalArray[ i + 2 ];
2665

2666 2667 2668
					nbx  = normalArray[ i + 3 ];
					nby  = normalArray[ i + 4 ];
					nbz  = normalArray[ i + 5 ];
2669

2670 2671 2672
					ncx  = normalArray[ i + 6 ];
					ncy  = normalArray[ i + 7 ];
					ncz  = normalArray[ i + 8 ];
2673

2674 2675 2676
					nx = ( nax + nbx + ncx ) / 3;
					ny = ( nay + nby + ncy ) / 3;
					nz = ( naz + nbz + ncz ) / 3;
2677

2678 2679 2680
					normalArray[ i ] 	 = nx;
					normalArray[ i + 1 ] = ny;
					normalArray[ i + 2 ] = nz;
2681

2682 2683 2684
					normalArray[ i + 3 ] = nx;
					normalArray[ i + 4 ] = ny;
					normalArray[ i + 5 ] = nz;
2685

2686 2687 2688
					normalArray[ i + 6 ] = nx;
					normalArray[ i + 7 ] = ny;
					normalArray[ i + 8 ] = nz;
2689

2690
				}
2691

2692
			}
2693

2694 2695 2696
			_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 );
2697

2698
		}
2699

2700
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );
2701

2702
		object.count = 0;
2703

2704
	};
2705

2706 2707 2708 2709
	this.renderBufferDirect = function ( camera, lights, fog, material, geometryGroup, object ) {

		if ( material.opacity === 0 ) return;

2710
		var program, attributes, linewidth, primitives, a, attribute;
2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732

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

		attributes = program.attributes;

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

		if ( geometryGroupHash !== _currentGeometryGroupHash ) {

			_currentGeometryGroupHash = geometryGroupHash;
			updateBuffers = true;

		}

		// render mesh

		if ( object instanceof THREE.Mesh ) {

			var offsets = geometryGroup.offsets;

2733
			for ( var i = 0, il = offsets.length; i < il; ++ i ) {
2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797

				if ( updateBuffers ) {

					// vertices

					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.vertexPositionBuffer );
					_gl.vertexAttribPointer( attributes.position, geometryGroup.vertexPositionBuffer.itemSize, _gl.FLOAT, false, 0, offsets[ i ].index * 4 * 3 );

					// normals

					if ( attributes.normal >= 0 && geometryGroup.vertexNormalBuffer ) {

						_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.vertexNormalBuffer );
						_gl.vertexAttribPointer( attributes.normal, geometryGroup.vertexNormalBuffer.itemSize, _gl.FLOAT, false, 0, offsets[ i ].index * 4 * 3 );

					}

					// uvs

					if ( attributes.uv >= 0 && geometryGroup.vertexUvBuffer ) {

						if ( geometryGroup.vertexUvBuffer ) {

							_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.vertexUvBuffer );
							_gl.vertexAttribPointer(  attributes.uv, geometryGroup.vertexUvBuffer.itemSize, _gl.FLOAT, false, 0, offsets[ i ].index * 4 * 2 );

							_gl.enableVertexAttribArray( attributes.uv );

						} else {

							_gl.disableVertexAttribArray( attributes.uv );

						}

					}

					// colors

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

						_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.vertexColorBuffer );
						_gl.vertexAttribPointer( attributes.color, geometryGroup.vertexColorBuffer.itemSize, _gl.FLOAT, false, 0, offsets[ i ].index * 4 * 4 );


					}

					_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.vertexIndexBuffer );

				}

				// render indexed triangles

				_gl.drawElements( _gl.TRIANGLES, offsets[ i ].count, _gl.UNSIGNED_SHORT, offsets[ i ].start * 2 ); // 2 = Uint16

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

			}

		}

	};

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

2800
		if ( material.opacity === 0 ) return;
2801

2802
		var program, attributes, linewidth, primitives, a, attribute, i, il;
2803

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

2806
		attributes = program.attributes;
2807

2808 2809 2810
		var updateBuffers = false,
			wireframeBit = material.wireframe ? 1 : 0,
			geometryGroupHash = ( geometryGroup.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit;
2811

2812
		if ( geometryGroupHash !== _currentGeometryGroupHash ) {
A
alteredq 已提交
2813

2814 2815
			_currentGeometryGroupHash = geometryGroupHash;
			updateBuffers = true;
2816

2817
		}
2818

2819
		// vertices
2820

2821
		if ( !material.morphTargets && attributes.position >= 0 ) {
2822

2823
			if ( updateBuffers ) {
2824

2825 2826
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
				_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
2827

2828
			}
2829

2830
		} else {
2831

2832
			if ( object.morphTargetBase ) {
2833

2834
				setupMorphTargets( material, geometryGroup, object );
2835

2836
			}
2837

2838
		}
2839

2840

2841
		if ( updateBuffers ) {
2842

2843
			// custom attributes
2844

2845
			// Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
2846

2847
			if ( geometryGroup.__webglCustomAttributesList ) {
2848

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

2851
					attribute = geometryGroup.__webglCustomAttributesList[ i ];
2852

2853
					if( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
2854

2855 2856
						_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
						_gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 );
2857

2858
					}
2859

2860
				}
2861

2862
			}
2863 2864


2865
			// colors
2866

2867
			if ( attributes.color >= 0 ) {
2868

2869 2870
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
2871

2872
			}
2873

2874
			// normals
2875

2876
			if ( attributes.normal >= 0 ) {
2877

2878 2879
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
				_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
2880

2881
			}
2882

2883
			// tangents
2884

2885
			if ( attributes.tangent >= 0 ) {
2886

2887 2888
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
				_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
2889

2890
			}
2891

2892
			// uvs
2893

2894
			if ( attributes.uv >= 0 ) {
2895

2896
				if ( geometryGroup.__webglUVBuffer ) {
2897

2898 2899
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
					_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
2900

2901
					_gl.enableVertexAttribArray( attributes.uv );
2902

2903
				} else {
2904

2905
					_gl.disableVertexAttribArray( attributes.uv );
2906 2907 2908 2909 2910

				}

			}

2911
			if ( attributes.uv2 >= 0 ) {
2912

2913
				if ( geometryGroup.__webglUV2Buffer ) {
2914

2915 2916
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
					_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
2917

2918
					_gl.enableVertexAttribArray( attributes.uv2 );
2919

2920
				} else {
2921

2922
					_gl.disableVertexAttribArray( attributes.uv2 );
2923 2924

				}
2925 2926

			}
2927

2928 2929 2930
			if ( material.skinning &&
				 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
				 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
A
alteredq 已提交
2931

2932 2933
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
2934

2935 2936
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
				_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
2937

2938 2939
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
				_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
2940

2941 2942
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
				_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
2943

A
alteredq 已提交
2944
			}
2945

2946
		}
2947

2948
		// render mesh
2949

2950
		if ( object instanceof THREE.Mesh ) {
2951

2952
			// wireframe
2953

2954
			if ( material.wireframe ) {
2955

2956
				setLineWidth( material.wireframeLinewidth );
2957

2958 2959
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
2960

2961
			// triangles
2962

2963
			} else {
2964

2965 2966
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
2967

2968
			}
2969

2970 2971 2972
			_this.info.render.calls ++;
			_this.info.render.vertices += geometryGroup.__webglFaceCount;
			_this.info.render.faces += geometryGroup.__webglFaceCount / 3;
2973

2974
		// render lines
2975

2976
		} else if ( object instanceof THREE.Line ) {
2977

2978
			primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
2979

2980
			setLineWidth( material.linewidth );
2981

2982
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
2983

2984
			_this.info.render.calls ++;
2985

2986
		// render particles
2987

2988
		} else if ( object instanceof THREE.ParticleSystem ) {
2989

2990
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
2991

2992
			_this.info.render.calls ++;
2993
			_this.info.render.points += geometryGroup.__webglParticleCount;
2994

2995
		// render ribbon
2996

2997
		} else if ( object instanceof THREE.Ribbon ) {
2998

2999
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
3000

3001
			_this.info.render.calls ++;
3002

3003
		}
3004

3005
	};
3006

3007
	function setupMorphTargets ( material, geometryGroup, object ) {
3008

3009
		// set base
3010

3011
		var attributes = material.program.attributes;
3012

3013
		if ( object.morphTargetBase !== - 1 ) {
3014

3015 3016
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3017

3018
		} else if ( attributes.position >= 0 ) {
3019

3020 3021
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3022

3023
		}
3024

3025
		if ( object.morphTargetForcedOrder.length ) {
3026

3027
			// set forced order
3028

3029 3030 3031 3032 3033
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;

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

3035 3036 3037 3038 3039 3040
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ order[ m ] ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );

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

				m ++;
3041 3042
			}

3043 3044 3045 3046 3047 3048 3049 3050 3051 3052
		} else {

			// find most influencing

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

3054
			if ( object.morphTargetBase !== - 1 ) {
3055

3056
				used[ object.morphTargetBase ] = true;
3057

3058
			}
3059

3060
			while ( m < material.numSupportedMorphTargets ) {
3061

3062
				for ( i = 0; i < il; i ++ ) {
3063

3064
					if ( !used[ i ] && influences[ i ] > candidateInfluence ) {
3065

3066 3067
						candidate = i;
						candidateInfluence = influences[ candidate ];
3068

3069
					}
3070

3071
				}
3072

3073 3074
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
3075

3076
				object.__webglMorphTargetInfluences[ m ] = candidateInfluence;
3077

3078 3079 3080
				used[ candidate ] = 1;
				candidateInfluence = -1;
				m ++;
3081 3082 3083 3084 3085

			}

		}

3086
		// load updated influences uniform
3087

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

3090
			_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
3091

3092
		}
3093

3094
	};
3095 3096


3097
	function painterSort ( a, b ) {
3098

3099
		return b.z - a.z;
3100

3101
	};
3102

3103
	// Rendering
3104

3105
	this.render = function ( scene, camera, renderTarget, forceClear ) {
3106

3107 3108 3109 3110 3111 3112 3113 3114
		var i, il,

		program, material,
		webglObject, object,
		renderList,

		lights = scene.lights,
		fog = scene.fog;
M
Mr.doob 已提交
3115

3116
		_currentMaterialId = -1;
3117

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

3120
		if ( camera.parent === undefined ) {
3121

3122 3123
			console.warn( 'DEPRECATED: Camera hasn\'t been added to a Scene. Adding it...' );
			scene.add( camera );
3124

3125
		}
3126

3127
		if ( this.autoUpdateScene ) scene.updateMatrixWorld();
3128

A
alteredq 已提交
3129 3130
		// custom render plugins (pre pass)

A
alteredq 已提交
3131
		renderPlugins( this.renderPluginsPre, scene, camera );
A
alteredq 已提交
3132 3133 3134 3135

		_this.info.render.calls = 0;
		_this.info.render.vertices = 0;
		_this.info.render.faces = 0;
3136
		_this.info.render.points = 0;
A
alteredq 已提交
3137

3138
		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
A
alteredq 已提交
3139 3140 3141 3142 3143 3144

		if ( ! camera._viewMatrixArray ) camera._viewMatrixArray = new Float32Array( 16 );
		camera.matrixWorldInverse.flattenToArray( camera._viewMatrixArray );

		if ( ! camera._projectionMatrixArray ) camera._projectionMatrixArray = new Float32Array( 16 );
		camera.projectionMatrix.flattenToArray( camera._projectionMatrixArray );
3145

3146
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
A
alteredq 已提交
3147
		_frustum.setFromMatrix( _projScreenMatrix );
3148

A
alteredq 已提交
3149
		this.setRenderTarget( renderTarget );
3150

3151
		if ( this.autoClear || forceClear ) {
3152

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

3155
		}
M
Mr.doob 已提交
3156

3157
		// set matrices for regular objects (frustum culled)
3158

3159
		renderList = scene.__webglObjects;
3160

3161
		for ( i = 0, il = renderList.length; i < il; i ++ ) {
3162

3163
			webglObject = renderList[ i ];
3164
			object = webglObject.object;
3165

A
alteredq 已提交
3166 3167
			webglObject.render = false;

3168
			if ( object.visible ) {
3169

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

3172
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
3173

A
alteredq 已提交
3174
					setupMatrices( object, camera );
3175

3176
					unrollBufferMaterial( webglObject );
3177

3178
					webglObject.render = true;
3179

3180
					if ( this.sortObjects ) {
3181

3182
						if ( object.renderDepth ) {
3183

3184
							webglObject.z = object.renderDepth;
M
Mr.doob 已提交
3185

3186
						} else {
M
Mr.doob 已提交
3187

3188 3189
							_vector3.copy( object.position );
							_projScreenMatrix.multiplyVector3( _vector3 );
3190

3191
							webglObject.z = _vector3.z;
3192

3193
						}
M
Mr.doob 已提交
3194

3195
					}
M
Mr.doob 已提交
3196

3197
				}
3198 3199

			}
3200 3201 3202

		}

3203
		if ( this.sortObjects ) {
M
Mr.doob 已提交
3204

3205
			renderList.sort( painterSort );
3206

3207
		}
3208

3209
		// set matrices for immediate objects
3210

3211
		renderList = scene.__webglObjectsImmediate;
3212

3213 3214 3215
		for ( i = 0, il = renderList.length; i < il; i ++ ) {

			webglObject = renderList[ i ];
3216
			object = webglObject.object;
3217

3218
			if ( object.visible ) {
3219

3220
				if( object.matrixAutoUpdate ) {
3221

3222
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3223

3224
				}
M
Mr.doob 已提交
3225

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

3228
				unrollImmediateBufferMaterial( webglObject );
M
Mr.doob 已提交
3229

3230
			}
M
Mr.doob 已提交
3231

3232
		}
3233

3234
		if ( scene.overrideMaterial ) {
3235

3236
			this.setBlending( scene.overrideMaterial.blending );
A
alteredq 已提交
3237
			this.setDepthTest( scene.overrideMaterial.depthTest );
3238
			this.setDepthWrite( scene.overrideMaterial.depthWrite );
3239
			setPolygonOffset( scene.overrideMaterial.polygonOffset, scene.overrideMaterial.polygonOffsetFactor, scene.overrideMaterial.polygonOffsetUnits );
3240

3241 3242
			renderObjects( scene.__webglObjects, false, "", camera, lights, fog, true, scene.overrideMaterial );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "", camera, lights, fog, false, scene.overrideMaterial );
M
Mr.doob 已提交
3243

3244
		} else {
3245

3246
			// opaque pass (front-to-back order)
3247

3248
			this.setBlending( THREE.NormalBlending );
3249

3250 3251
			renderObjects( scene.__webglObjects, true, "opaque", camera, lights, fog, false );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "opaque", camera, lights, fog, false );
3252

3253
			// transparent pass (back-to-front order)
3254

3255 3256
			renderObjects( scene.__webglObjects, false, "transparent", camera, lights, fog, true );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "transparent", camera, lights, fog, true );
3257

3258
		}
3259

A
alteredq 已提交
3260
		// custom render plugins (post pass)
3261

A
alteredq 已提交
3262
		renderPlugins( this.renderPluginsPost, scene, camera );
3263 3264


3265
		// Generate mipmap if we're using any kind of mipmap filtering
3266

3267
		if ( renderTarget && renderTarget.generateMipmaps && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {
3268

3269
			updateRenderTargetMipmap( renderTarget );
3270

3271
		}
3272

3273 3274 3275
		// Ensure depth buffer writing is enabled so it can be cleared on next render

		this.setDepthTest( true );
3276
		this.setDepthWrite( true );
3277

3278
		// _gl.finish();
3279

3280
	};
3281

A
alteredq 已提交
3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294
	function renderPlugins( plugins, scene, camera ) {

		if ( ! plugins.length ) return;

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

			_currentProgram = null;
			_oldBlending = -1;
			_oldDepthTest = -1;
			_oldDepthWrite = -1;
			_currentGeometryGroupHash = -1;
			_currentMaterialId = -1;

A
alteredq 已提交
3295
			plugins[ i ].render( scene, camera, _currentWidth, _currentHeight );
A
alteredq 已提交
3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307

			_currentProgram = null;
			_oldBlending = -1;
			_oldDepthTest = -1;
			_oldDepthWrite = -1;
			_currentGeometryGroupHash = -1;
			_currentMaterialId = -1;

		}

	};

3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343
	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;

3344
					if ( useBlending ) _this.setBlending( material.blending );
3345

A
alteredq 已提交
3346
					_this.setDepthTest( material.depthTest );
3347
					_this.setDepthWrite( material.depthWrite );
3348 3349 3350 3351
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

A
alteredq 已提交
3352
				_this.setObjectFaces( object );
3353 3354 3355 3356 3357 3358 3359 3360 3361 3362

				if ( buffer instanceof THREE.BufferGeometry ) {

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

				} else {

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

				}
3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390

			}

		}

	};

	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;

A
alteredq 已提交
3391
					if ( useBlending ) _this.setBlending( material.blending );
3392

A
alteredq 已提交
3393
					_this.setDepthTest( material.depthTest );
3394
					_this.setDepthWrite( material.depthWrite );
3395 3396 3397 3398
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

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

A
alteredq 已提交
3401
			}
3402

A
alteredq 已提交
3403
		}
3404

A
alteredq 已提交
3405
	};
3406

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

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

A
alteredq 已提交
3411
		_currentGeometryGroupHash = -1;
3412

A
alteredq 已提交
3413 3414 3415 3416 3417 3418 3419 3420 3421
		_this.setObjectFaces( object );

		if ( object.immediateRenderCallback ) {

			object.immediateRenderCallback( program, _gl, _frustum );

		} else {

			object.render( function( object ) { _this.renderBufferImmediate( object, program, material.shading ); } );
3422 3423 3424 3425 3426

		}

	};

3427
	function unrollImmediateBufferMaterial ( globject ) {
3428

3429 3430
		var object = globject.object,
			material = object.material;
3431

3432
		if ( material.transparent ) {
3433

3434 3435
			globject.transparent = material;
			globject.opaque = null;
3436

3437
		} else {
3438

3439 3440
			globject.opaque = material;
			globject.transparent = null;
3441

3442
		}
A
alteredq 已提交
3443

3444
	};
A
alteredq 已提交
3445

3446
	function unrollBufferMaterial ( globject ) {
A
alteredq 已提交
3447

3448 3449 3450
		var object = globject.object,
			buffer = globject.buffer,
			material, materialIndex, meshMaterial;
3451

3452
		meshMaterial = object.material;
3453

3454
		if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
M
Mr.doob 已提交
3455

3456
			materialIndex = buffer.materialIndex;
3457

3458
			if ( materialIndex >= 0 ) {
3459

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

3462
				if ( material.transparent ) {
M
Mr.doob 已提交
3463

3464 3465
					globject.transparent = material;
					globject.opaque = null;
3466

3467
				} else {
3468

3469 3470
					globject.opaque = material;
					globject.transparent = null;
3471

3472
				}
3473

3474
			}
3475

3476
		} else {
3477

3478
			material = meshMaterial;
3479

3480
			if ( material ) {
3481

3482
				if ( material.transparent ) {
M
Mr.doob 已提交
3483

3484 3485
					globject.transparent = material;
					globject.opaque = null;
A
alteredq 已提交
3486

3487
				} else {
3488

3489 3490
					globject.opaque = material;
					globject.transparent = null;
3491

3492
				}
3493

3494
			}
3495

3496
		}
3497

3498
	};
3499

3500
	// Geometry splitting
3501

3502
	function sortFacesByMaterial ( geometry ) {
3503

3504 3505 3506
		var f, fl, face, materialIndex, vertices,
			materialHash, groupHash,
			hash_map = {};
3507

3508
		var numMorphTargets = geometry.morphTargets.length;
3509

3510
		geometry.geometryGroups = {};
3511

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

3514 3515
			face = geometry.faces[ f ];
			materialIndex = face.materialIndex;
3516

3517
			materialHash = ( materialIndex !== undefined ) ? materialIndex : -1;
3518

3519
			if ( hash_map[ materialHash ] === undefined ) {
3520

3521
				hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 };
3522 3523 3524

			}

3525
			groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
3526

3527
			if ( geometry.geometryGroups[ groupHash ] === undefined ) {
3528

3529
				geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets };
3530

3531
			}
A
alteredq 已提交
3532

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

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

3537 3538
				hash_map[ materialHash ].counter += 1;
				groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
A
alteredq 已提交
3539

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

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

3544
				}
3545

3546
			}
3547

3548
			if ( face instanceof THREE.Face3 ) {
3549

3550
				geometry.geometryGroups[ groupHash ].faces3.push( f );
3551

3552
			} else {
3553

3554
				geometry.geometryGroups[ groupHash ].faces4.push( f );
3555

A
alteredq 已提交
3556
			}
3557

3558
			geometry.geometryGroups[ groupHash ].vertices += vertices;
3559

3560
		}
3561

3562
		geometry.geometryGroupsList = [];
3563

3564
		for ( var g in geometry.geometryGroups ) {
3565

3566
			geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;
3567

3568
			geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );
3569

3570
		}
3571

3572
	};
3573

3574 3575 3576 3577 3578 3579 3580 3581 3582
	// Objects refresh

	this.initWebGLObjects = function ( scene ) {

		if ( !scene.__webglObjects ) {

			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
			scene.__webglSprites = [];
3583
			scene.__webglFlares = [];
3584 3585

		}
3586

3587
		while ( scene.__objectsAdded.length ) {
3588

3589 3590
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
3591

3592
		}
A
alteredq 已提交
3593

3594
		while ( scene.__objectsRemoved.length ) {
3595

3596 3597
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
3598

3599
		}
3600

3601
		// update must be called after objects adding / removal
3602

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

3605
			updateObject( scene.__webglObjects[ o ].object );
M
Mr.doob 已提交
3606 3607 3608 3609 3610

		}

	};

3611
	// Objects adding
M
Mr.doob 已提交
3612

3613
	function addObject ( object, scene ) {
A
alteredq 已提交
3614

3615
		var g, geometry, geometryGroup;
3616

3617
		if ( ! object.__webglInit ) {
M
Mr.doob 已提交
3618

3619
			object.__webglInit = true;
M
Mr.doob 已提交
3620

3621
			object._modelViewMatrix = new THREE.Matrix4();
M
Mr.doob 已提交
3622

3623 3624 3625
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
M
Mr.doob 已提交
3626

3627
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3628

3629
			if ( object instanceof THREE.Mesh ) {
M
Mr.doob 已提交
3630

3631
				geometry = object.geometry;
M
Mr.doob 已提交
3632

3633
				if ( geometry instanceof THREE.Geometry ) {
M
Mr.doob 已提交
3634

3635
					if ( geometry.geometryGroups === undefined ) {
M
Mr.doob 已提交
3636

3637
						sortFacesByMaterial( geometry );
M
Mr.doob 已提交
3638

3639 3640 3641
					}

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

3643
					for ( g in geometry.geometryGroups ) {
M
Mr.doob 已提交
3644

3645
						geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
3646

3647
						// initialise VBO on the first access
M
Mr.doob 已提交
3648

3649
						if ( ! geometryGroup.__webglVertexBuffer ) {
3650

3651 3652
							createMeshBuffers( geometryGroup );
							initMeshBuffers( geometryGroup, object );
M
Mr.doob 已提交
3653

3654 3655 3656 3657 3658 3659 3660 3661 3662
							geometry.__dirtyVertices = true;
							geometry.__dirtyMorphTargets = true;
							geometry.__dirtyElements = true;
							geometry.__dirtyUvs = true;
							geometry.__dirtyNormals = true;
							geometry.__dirtyTangents = true;
							geometry.__dirtyColors = true;

						}
M
Mr.doob 已提交
3663

3664
					}
M
Mr.doob 已提交
3665

3666
				}
M
Mr.doob 已提交
3667

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

3670
				geometry = object.geometry;
M
Mr.doob 已提交
3671

3672
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
3673

3674 3675
					createRibbonBuffers( geometry );
					initRibbonBuffers( geometry );
M
Mr.doob 已提交
3676

3677 3678
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
3679

3680
				}
M
Mr.doob 已提交
3681

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

3684
				geometry = object.geometry;
M
Mr.doob 已提交
3685

3686
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
3687

3688 3689
					createLineBuffers( geometry );
					initLineBuffers( geometry, object );
M
Mr.doob 已提交
3690

3691 3692
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
3693

3694
				}
3695

3696
			} else if ( object instanceof THREE.ParticleSystem ) {
3697

3698
				geometry = object.geometry;
3699

3700
				if ( ! geometry.__webglVertexBuffer ) {
3701

3702 3703
					createParticleBuffers( geometry );
					initParticleBuffers( geometry, object );
3704

3705 3706
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
3707

3708
				}
3709

3710
			}
3711

3712
		}
3713

3714
		if ( ! object.__webglActive ) {
3715

3716
			if ( object instanceof THREE.Mesh ) {
3717

3718
				geometry = object.geometry;
3719

3720 3721 3722 3723 3724 3725 3726 3727 3728
				if ( geometry instanceof THREE.BufferGeometry ) {

					addBuffer( scene.__webglObjects, geometry, object );

				} else {

					for ( g in geometry.geometryGroups ) {

						geometryGroup = geometry.geometryGroups[ g ];
3729

3730
						addBuffer( scene.__webglObjects, geometryGroup, object );
3731

3732
					}
3733

3734
				}
3735

3736 3737 3738
			} else if ( object instanceof THREE.Ribbon ||
						object instanceof THREE.Line ||
						object instanceof THREE.ParticleSystem ) {
3739

3740 3741
				geometry = object.geometry;
				addBuffer( scene.__webglObjects, geometry, object );
3742

3743
			} else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes || object.immediateRenderCallback ) {
3744

3745
				addBufferImmediate( scene.__webglObjectsImmediate, object );
3746

3747
			} else if ( object instanceof THREE.Sprite ) {
3748

3749
				scene.__webglSprites.push( object );
3750

3751 3752 3753 3754
			} else if ( object instanceof THREE.LensFlare ) {

				scene.__webglFlares.push( object );

3755 3756
			}

3757
			object.__webglActive = true;
3758

3759
		}
3760

3761
	};
3762

3763
	function addBuffer ( objlist, buffer, object ) {
3764

3765 3766 3767 3768 3769 3770 3771 3772
		objlist.push(
			{
				buffer: buffer,
				object: object,
				opaque: null,
				transparent: null
			}
		);
3773

3774
	};
3775

3776
	function addBufferImmediate ( objlist, object ) {
3777

3778 3779 3780 3781 3782
		objlist.push(
			{
				object: object,
				opaque: null,
				transparent: null
3783
			}
3784
		);
3785

3786
	};
3787

3788
	// Objects updates
3789

3790
	function updateObject ( object ) {
3791

3792 3793
		var geometry = object.geometry,
			geometryGroup, customAttributesDirty, material;
3794

3795
		if ( object instanceof THREE.Mesh ) {
3796

3797 3798
			if ( geometry instanceof THREE.BufferGeometry ) {

3799
				/*
3800 3801 3802
				if ( geometry.__dirtyVertices || geometry.__dirtyElements ||
					 geometry.__dirtyUvs || geometry.__dirtyNormals ||
					 geometry.__dirtyColors  ) {
3803

3804 3805
					// TODO
					// set buffers from typed arrays
3806

3807
				}
3808
				*/
3809

3810 3811 3812 3813 3814
				geometry.__dirtyVertices = false;
				geometry.__dirtyElements = false;
				geometry.__dirtyUvs = false;
				geometry.__dirtyNormals = false;
				geometry.__dirtyColors = false;
3815

3816
			} else {
3817

3818
				// check all geometry groups
3819

3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834
				for( var i = 0, il = geometry.geometryGroupsList.length; i < il; i ++ ) {

					geometryGroup = geometry.geometryGroupsList[ i ];

					material = getBufferMaterial( object, geometryGroup );

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

					if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
						 geometry.__dirtyUvs || geometry.__dirtyNormals ||
						 geometry.__dirtyColors || geometry.__dirtyTangents || customAttributesDirty ) {

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

					}
3835

3836
				}
M
Mr.doob 已提交
3837

3838 3839 3840 3841 3842 3843 3844
				geometry.__dirtyVertices = false;
				geometry.__dirtyMorphTargets = false;
				geometry.__dirtyElements = false;
				geometry.__dirtyUvs = false;
				geometry.__dirtyNormals = false;
				geometry.__dirtyColors = false;
				geometry.__dirtyTangents = false;
3845

3846
				material.attributes && clearCustomAttributes( material );
3847

3848
			}
3849

3850
		} else if ( object instanceof THREE.Ribbon ) {
3851

3852
			if ( geometry.__dirtyVertices || geometry.__dirtyColors ) {
3853

3854
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
3855

3856
			}
3857

3858 3859
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
3860

3861
		} else if ( object instanceof THREE.Line ) {
3862

3863
			material = getBufferMaterial( object, geometryGroup );
A
alteredq 已提交
3864

3865
			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
A
alteredq 已提交
3866

3867
			if ( geometry.__dirtyVertices ||  geometry.__dirtyColors || customAttributesDirty ) {
A
alteredq 已提交
3868

3869
				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
3870

3871
			}
3872

3873 3874
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
3875

3876
			material.attributes && clearCustomAttributes( material );
3877

3878
		} else if ( object instanceof THREE.ParticleSystem ) {
3879

3880
			material = getBufferMaterial( object, geometryGroup );
3881

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

3884
			if ( geometry.__dirtyVertices || geometry.__dirtyColors || object.sortParticles || customAttributesDirty ) {
3885

3886
				setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
3887

3888
			}
3889

3890 3891
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
3892

3893
			material.attributes && clearCustomAttributes( material );
3894

3895
		}
3896

3897
	};
3898

3899
	// Objects updates - custom attributes check
3900

3901
	function areCustomAttributesDirty ( material ) {
3902

3903
		for ( var a in material.attributes ) {
3904

3905
			if ( material.attributes[ a ].needsUpdate ) return true;
3906

3907
		}
3908

3909
		return false;
3910

3911
	};
3912

3913 3914 3915
	function clearCustomAttributes ( material ) {

		for ( var a in material.attributes ) {
3916

3917
			material.attributes[ a ].needsUpdate = false;
3918

3919
		}
3920

3921
	};
3922

3923
	// Objects removal
3924

3925
	function removeObject ( object, scene ) {
3926

3927 3928 3929 3930
		if ( object instanceof THREE.Mesh  ||
			 object instanceof THREE.ParticleSystem ||
			 object instanceof THREE.Ribbon ||
			 object instanceof THREE.Line ) {
3931

3932
			removeInstances( scene.__webglObjects, object );
3933

3934
		} else if ( object instanceof THREE.Sprite ) {
3935

3936
			removeInstancesDirect( scene.__webglSprites, object );
3937

3938 3939 3940 3941
		} else if ( object instanceof THREE.LensFlare ) {

			removeInstancesDirect( scene.__webglFlares, object );

3942
		} else if ( object instanceof THREE.MarchingCubes || object.immediateRenderCallback ) {
3943

3944
			removeInstances( scene.__webglObjectsImmediate, object );
3945

3946
		}
3947

3948
		object.__webglActive = false;
3949

3950
	};
3951

3952
	function removeInstances ( objlist, object ) {
3953

3954
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
3955

3956
			if ( objlist[ o ].object === object ) {
3957

3958
				objlist.splice( o, 1 );
3959

3960
			}
3961

3962
		}
3963

3964
	};
3965

3966
	function removeInstancesDirect ( objlist, object ) {
3967

3968
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
3969

3970
			if ( objlist[ o ] === object ) {
3971

3972
				objlist.splice( o, 1 );
3973

3974
			}
3975

3976
		}
3977

3978
	};
3979

3980
	// Materials
3981

3982
	this.initMaterial = function ( material, lights, fog, object ) {
3983

3984
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
3985

3986
		if ( material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
3987

3988
			shaderID = 'depth';
3989

3990
		} else if ( material instanceof THREE.MeshNormalMaterial ) {
3991

3992
			shaderID = 'normal';
M
Mr.doob 已提交
3993

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

3996
			shaderID = 'basic';
M
Mr.doob 已提交
3997

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

4000
			shaderID = 'lambert';
M
Mr.doob 已提交
4001

4002
		} else if ( material instanceof THREE.MeshPhongMaterial ) {
4003

4004
			shaderID = 'phong';
4005

4006
		} else if ( material instanceof THREE.LineBasicMaterial ) {
4007

4008
			shaderID = 'basic';
4009

4010
		} else if ( material instanceof THREE.ParticleBasicMaterial ) {
4011

4012
			shaderID = 'particle_basic';
4013 4014 4015

		}

4016
		if ( shaderID ) {
4017

4018
			setMaterialShaders( material, THREE.ShaderLib[ shaderID ] );
4019

4020
		}
4021

4022 4023
		// heuristics to create shader parameters according to lights in the scene
		// (not to blow over maxLights budget)
4024

4025
		maxLightCount = allocateLights( lights );
4026

4027
		maxShadows = allocateShadows( lights );
4028

4029
		maxBones = allocateBones( object );
4030

4031
		parameters = {
4032

4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046
			map: !!material.map, envMap: !!material.envMap, lightMap: !!material.lightMap,
			vertexColors: material.vertexColors,
			fog: fog, useFog: material.fog,
			sizeAttenuation: material.sizeAttenuation,
			skinning: material.skinning,
			morphTargets: material.morphTargets,
			maxMorphTargets: this.maxMorphTargets,
			maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
			maxBones: maxBones,
			shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
			shadowMapSoft: this.shadowMapSoft,
			maxShadows: maxShadows,
			alphaTest: material.alphaTest,
			metal: material.metal,
4047 4048
			perPixel: material.perPixel,
			wrapAround: material.wrapAround
4049

4050
		};
M
Mr.doob 已提交
4051

4052
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
4053

4054
		var attributes = material.program.attributes;
4055

4056 4057 4058 4059
		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 );
4060

4061 4062 4063
		if ( material.skinning &&
			 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
M
Mr.doob 已提交
4064

4065 4066 4067 4068
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
M
Mr.doob 已提交
4069 4070

		}
4071

4072
		if ( material.attributes ) {
A
alteredq 已提交
4073

4074
			for ( a in material.attributes ) {
M
Mr.doob 已提交
4075

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

4078
			}
M
Mr.doob 已提交
4079

4080
		}
M
Mr.doob 已提交
4081

4082
		if ( material.morphTargets ) {
M
Mr.doob 已提交
4083

4084
			material.numSupportedMorphTargets = 0;
4085

4086
			var id, base = "morphTarget";
4087

4088
			for ( i = 0; i < this.maxMorphTargets; i ++ ) {
4089

4090
				id = base + i;
M
Mr.doob 已提交
4091

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

4094 4095
					_gl.enableVertexAttribArray( attributes[ id ] );
					material.numSupportedMorphTargets ++;
4096

4097
				}
4098

4099
			}
4100

4101
		}
4102

4103
		material.uniformsList = [];
4104

4105
		for ( u in material.uniforms ) {
4106

4107
			material.uniformsList.push( [ material.uniforms[ u ], u ] );
4108

4109
		}
M
Mr.doob 已提交
4110

4111
	};
M
Mr.doob 已提交
4112

4113
	function setMaterialShaders ( material, shaders ) {
M
Mr.doob 已提交
4114

4115 4116 4117
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
M
Mr.doob 已提交
4118

4119
	};
M
Mr.doob 已提交
4120

4121
	function setProgram ( camera, lights, fog, material, object ) {
4122

4123
		if ( ! material.program ) {
4124

4125
			_this.initMaterial( material, lights, fog, object );
4126

4127
		}
4128

4129
		if ( material.morphTargets ) {
4130

4131
			if ( ! object.__webglMorphTargetInfluences ) {
4132

4133
				object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );
4134

4135
				for ( var i = 0, il = _this.maxMorphTargets; i < il; i ++ ) {
4136

4137
					object.__webglMorphTargetInfluences[ i ] = 0;
4138

4139
				}
4140

4141
			}
4142

4143
		}
4144

4145
		var refreshMaterial = false;
4146

4147 4148 4149
		var program = material.program,
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
4150

4151
		if ( program !== _currentProgram ) {
4152

4153 4154
			_gl.useProgram( program );
			_currentProgram = program;
4155

4156
			refreshMaterial = true;
4157

4158
		}
4159

4160
		if ( material.id !== _currentMaterialId ) {
4161

4162 4163
			_currentMaterialId = material.id;
			refreshMaterial = true;
4164

4165
		}
4166

4167
		if ( refreshMaterial ) {
4168

A
alteredq 已提交
4169
			_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, camera._projectionMatrixArray );
A
alteredq 已提交
4170

4171
			// refresh uniforms common to several materials
4172

4173
			if ( fog && material.fog ) {
4174

4175
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
4176

4177
			}
M
Mr.doob 已提交
4178

4179 4180 4181
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material.lights ) {
4182

4183 4184
				setupLights( program, lights );
				refreshUniformsLights( m_uniforms, _lights );
4185

4186
			}
M
Mr.doob 已提交
4187

4188 4189 4190
			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
4191

4192
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
4193 4194 4195

			}

4196
			// refresh single material specific uniforms
M
Mr.doob 已提交
4197

4198
			if ( material instanceof THREE.LineBasicMaterial ) {
4199

4200
				refreshUniformsLine( m_uniforms, material );
M
Mr.doob 已提交
4201

4202
			} else if ( material instanceof THREE.ParticleBasicMaterial ) {
M
Mr.doob 已提交
4203

4204
				refreshUniformsParticle( m_uniforms, material );
M
Mr.doob 已提交
4205

4206
			} else if ( material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
4207

4208
				refreshUniformsPhong( m_uniforms, material );
M
Mr.doob 已提交
4209

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

4212
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
4213

4214
			} else if ( material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
4215

4216 4217 4218
				m_uniforms.mNear.value = camera.near;
				m_uniforms.mFar.value = camera.far;
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4219

4220
			} else if ( material instanceof THREE.MeshNormalMaterial ) {
M
Mr.doob 已提交
4221

4222
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4223

4224
			}
M
Mr.doob 已提交
4225

4226
			if ( object.receiveShadow && ! material._shadowPass ) {
M
Mr.doob 已提交
4227

4228
				refreshUniformsShadow( m_uniforms, lights );
M
Mr.doob 已提交
4229

4230
			}
M
Mr.doob 已提交
4231

4232
			// load common uniforms
M
Mr.doob 已提交
4233

4234
			loadUniformsGeneric( program, material.uniformsList );
M
Mr.doob 已提交
4235

4236 4237
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)
4238

4239 4240 4241
			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
				 material.envMap ) {
4242

4243
				if( p_uniforms.cameraPosition !== null ) {
4244

4245
					_gl.uniform3f( p_uniforms.cameraPosition, camera.position.x, camera.position.y, camera.position.z );
4246

4247
				}
4248 4249 4250

			}

4251 4252 4253 4254
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {
4255

4256
				if( p_uniforms.viewMatrix !== null ) {
4257

A
alteredq 已提交
4258
					_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, camera._viewMatrixArray );
4259

4260
				}
4261

4262
			}
M
Mr.doob 已提交
4263

4264
			if ( material.skinning ) {
4265

A
alteredq 已提交
4266
				loadUniformsSkinning( p_uniforms, object, camera );
4267

4268
			}
4269

4270
		}
M
Mr.doob 已提交
4271

4272
		loadUniformsMatrices( p_uniforms, object );
M
Mr.doob 已提交
4273

4274 4275 4276 4277
		if ( material instanceof THREE.ShaderMaterial ||
			 material.envMap ||
			 material.skinning ||
			 object.receiveShadow ) {
M
Mr.doob 已提交
4278

4279
			if ( p_uniforms.objectMatrix !== null ) {
M
Mr.doob 已提交
4280

4281
				_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
M
Mr.doob 已提交
4282

4283
			}
4284

4285
		}
4286

4287
		return program;
4288

4289
	};
4290

4291
	// Uniforms (refresh uniforms objects)
A
alteredq 已提交
4292

4293
	function refreshUniformsCommon ( uniforms, material ) {
4294

4295
		uniforms.opacity.value = material.opacity;
4296

4297
		if ( _this.gammaInput ) {
4298

4299
			uniforms.diffuse.value.copyGammaToLinear( material.color );
4300

4301
		} else {
4302

4303
			uniforms.diffuse.value = material.color;
4304

4305
		}
4306

4307
		uniforms.map.texture = material.map;
4308

4309
		if ( material.map ) {
4310

4311
			uniforms.offsetRepeat.value.set( material.map.offset.x, material.map.offset.y, material.map.repeat.x, material.map.repeat.y );
M
Mr.doob 已提交
4312

4313
		}
M
Mr.doob 已提交
4314

4315
		uniforms.lightMap.texture = material.lightMap;
4316

4317 4318
		uniforms.envMap.texture = material.envMap;
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
4319

4320
		if ( _this.gammaInput ) {
4321

4322 4323
			//uniforms.reflectivity.value = material.reflectivity * material.reflectivity;
			uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
4324

4325
		} else {
4326

4327
			uniforms.reflectivity.value = material.reflectivity;
4328

4329
		}
4330

4331 4332 4333
		uniforms.refractionRatio.value = material.refractionRatio;
		uniforms.combine.value = material.combine;
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
M
Mr.doob 已提交
4334

4335
	};
M
Mr.doob 已提交
4336

4337
	function refreshUniformsLine ( uniforms, material ) {
M
Mr.doob 已提交
4338

4339 4340
		uniforms.diffuse.value = material.color;
		uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4341

4342
	};
M
Mr.doob 已提交
4343

4344
	function refreshUniformsParticle ( uniforms, material ) {
4345

4346 4347 4348 4349
		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.
4350

4351
		uniforms.map.texture = material.map;
4352

4353
	};
4354

4355
	function refreshUniformsFog ( uniforms, fog ) {
4356

4357
		uniforms.fogColor.value = fog.color;
4358

4359
		if ( fog instanceof THREE.Fog ) {
4360

4361 4362
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
4363

4364
		} else if ( fog instanceof THREE.FogExp2 ) {
M
Mikael Emtinger 已提交
4365

4366
			uniforms.fogDensity.value = fog.density;
M
Mikael Emtinger 已提交
4367

4368
		}
M
Mikael Emtinger 已提交
4369

4370
	};
M
Mikael Emtinger 已提交
4371

4372
	function refreshUniformsPhong ( uniforms, material ) {
M
Mikael Emtinger 已提交
4373

4374
		uniforms.shininess.value = material.shininess;
4375

4376
		if ( _this.gammaInput ) {
M
Mikael Emtinger 已提交
4377

4378 4379
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
			uniforms.specular.value.copyGammaToLinear( material.specular );
4380

4381
		} else {
4382

4383 4384
			uniforms.ambient.value = material.ambient;
			uniforms.specular.value = material.specular;
4385

4386
		}
4387

4388 4389 4390 4391 4392 4393
		if ( material.wrapAround ) {

			uniforms.wrapRGB.value.copy( material.wrapRGB );

		}

4394
	};
4395

4396
	function refreshUniformsLambert ( uniforms, material ) {
4397

4398
		if ( _this.gammaInput ) {
4399

4400
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
M
Mr.doob 已提交
4401

4402
		} else {
4403

4404
			uniforms.ambient.value = material.ambient;
4405

4406
		}
4407

4408 4409 4410 4411 4412 4413
		if ( material.wrapAround ) {

			uniforms.wrapRGB.value.copy( material.wrapRGB );

		}

4414
	};
4415

4416
	function refreshUniformsLights ( uniforms, lights ) {
4417

4418
		uniforms.ambientLightColor.value = lights.ambient;
4419

4420 4421
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
4422

4423 4424 4425
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
		uniforms.pointLightDistance.value = lights.point.distances;
4426

4427
	};
4428

4429
	function refreshUniformsShadow ( uniforms, lights ) {
M
Mr.doob 已提交
4430

4431
		if ( uniforms.shadowMatrix ) {
4432

4433
			var j = 0;
4434

4435
			for ( var i = 0, il = lights.length; i < il; i ++ ) {
4436

4437
				var light = lights[ i ];
4438

A
alteredq 已提交
4439 4440 4441
				if ( ! light.castShadow ) continue;

				if ( light instanceof THREE.SpotLight || light instanceof THREE.DirectionalLight ) {
4442 4443 4444

					uniforms.shadowMap.texture[ j ] = light.shadowMap;
					uniforms.shadowMapSize.value[ j ] = light.shadowMapSize;
4445

4446 4447 4448 4449 4450 4451 4452 4453 4454 4455
					uniforms.shadowMatrix.value[ j ] = light.shadowMatrix;

					uniforms.shadowDarkness.value[ j ] = light.shadowDarkness;
					uniforms.shadowBias.value[ j ] = light.shadowBias;

					j ++;

				}

			}
4456

4457 4458
		}

4459
	};
4460

4461
	// Uniforms (load to GPU)
4462

A
alteredq 已提交
4463
	function loadUniformsSkinning ( uniforms, object, camera ) {
4464

A
alteredq 已提交
4465
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, camera._viewMatrixArray );
4466
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
4467

4468
	};
4469

4470

4471
	function loadUniformsMatrices ( uniforms, object ) {
4472

4473
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
4474

4475
		if ( uniforms.normalMatrix ) {
4476

4477
			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );
4478

4479
		}
4480

4481
	};
4482

4483
	function loadUniformsGeneric ( program, uniforms ) {
4484

4485
		var uniform, value, type, location, texture, i, il, j, jl, offset;
4486

4487
		for( j = 0, jl = uniforms.length; j < jl; j ++ ) {
4488

4489 4490
			location = program.uniforms[ uniforms[ j ][ 1 ] ];
			if ( !location ) continue;
4491

4492
			uniform = uniforms[ j ][ 0 ];
4493

4494 4495
			type = uniform.type;
			value = uniform.value;
4496

4497
			// single integer
4498

4499
			if( type === "i" ) {
4500

4501
				_gl.uniform1i( location, value );
4502

4503
			// single float
4504

4505
			} else if( type === "f" ) {
4506

4507
				_gl.uniform1f( location, value );
4508

4509
			// single THREE.Vector2
4510

4511
			} else if( type === "v2" ) {
4512

4513
				_gl.uniform2f( location, value.x, value.y );
4514

4515
			// single THREE.Vector3
4516

4517
			} else if( type === "v3" ) {
4518

4519
				_gl.uniform3f( location, value.x, value.y, value.z );
4520

4521
			// single THREE.Vector4
4522

4523
			} else if( type === "v4" ) {
4524

4525
				_gl.uniform4f( location, value.x, value.y, value.z, value.w );
4526

4527
			// single THREE.Color
4528

4529
			} else if( type === "c" ) {
4530

4531
				_gl.uniform3f( location, value.r, value.g, value.b );
4532

4533
			// flat array of floats (JS or typed array)
4534

4535
			} else if( type === "fv1" ) {
4536

4537
				_gl.uniform1fv( location, value );
4538

4539
			// flat array of floats with 3 x N size (JS or typed array)
4540

4541
			} else if( type === "fv" ) {
4542

4543
				_gl.uniform3fv( location, value );
4544

4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565
			// array of THREE.Vector2

			} else if( type === "v2v" ) {

				if ( ! uniform._array ) {

					uniform._array = new Float32Array( 2 * value.length );

				}

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

					offset = i * 2;

					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;

				}

				_gl.uniform2fv( location, uniform._array );

4566
			// array of THREE.Vector3
4567

4568
			} else if( type === "v3v" ) {
4569

4570
				if ( ! uniform._array ) {
4571

4572
					uniform._array = new Float32Array( 3 * value.length );
M
Mr.doob 已提交
4573

4574
				}
A
alteredq 已提交
4575

4576
				for ( i = 0, il = value.length; i < il; i ++ ) {
A
alteredq 已提交
4577

4578
					offset = i * 3;
4579

4580 4581 4582
					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;
					uniform._array[ offset + 2 ] = value[ i ].z;
4583

4584
				}
4585

4586
				_gl.uniform3fv( location, uniform._array );
4587

4588
			// single THREE.Matrix4
4589

4590
			} else if( type === "m4" ) {
M
Mr.doob 已提交
4591

4592
				if ( ! uniform._array ) {
A
alteredq 已提交
4593

4594
					uniform._array = new Float32Array( 16 );
4595

4596
				}
4597

4598 4599
				value.flattenToArray( uniform._array );
				_gl.uniformMatrix4fv( location, false, uniform._array );
4600

4601
			// array of THREE.Matrix4
4602

4603
			} else if( type === "m4v" ) {
A
alteredq 已提交
4604

4605 4606 4607
				if ( ! uniform._array ) {

					uniform._array = new Float32Array( 16 * value.length );
A
alteredq 已提交
4608

M
Mr.doob 已提交
4609
				}
M
Mr.doob 已提交
4610

4611
				for ( i = 0, il = value.length; i < il; i ++ ) {
M
Mr.doob 已提交
4612

4613
					value[ i ].flattenToArrayOffset( uniform._array, i * 16 );
M
Mr.doob 已提交
4614

4615
				}
A
alteredq 已提交
4616

4617
				_gl.uniformMatrix4fv( location, false, uniform._array );
M
Mr.doob 已提交
4618

4619

4620
			// single THREE.Texture (2d or cube)
M
Mr.doob 已提交
4621

4622
			} else if( type === "t" ) {
A
alteredq 已提交
4623

4624
				_gl.uniform1i( location, value );
4625

4626
				texture = uniform.texture;
A
alteredq 已提交
4627

4628
				if ( !texture ) continue;
A
alteredq 已提交
4629

4630
				if ( texture.image instanceof Array && texture.image.length === 6 ) {
A
alteredq 已提交
4631

4632
					setCubeTexture( texture, value );
A
alteredq 已提交
4633

4634
				} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
M
Mr.doob 已提交
4635

4636 4637 4638 4639
					setCubeTextureDynamic( texture, value );

				} else {

4640
					_this.setTexture( texture, value );
4641

M
Mr.doob 已提交
4642
				}
M
Mr.doob 已提交
4643

4644
			// array of THREE.Texture (2d)
M
Mr.doob 已提交
4645

4646
			} else if( type === "tv" ) {
M
Mr.doob 已提交
4647

4648
				if ( ! uniform._array ) {
M
Mr.doob 已提交
4649

4650
					uniform._array = [];
A
alteredq 已提交
4651

4652 4653 4654 4655 4656
					for( i = 0, il = uniform.texture.length; i < il; i ++ ) {

						uniform._array[ i ] = value + i;

					}
A
alteredq 已提交
4657

M
Mr.doob 已提交
4658
				}
A
alteredq 已提交
4659

4660
				_gl.uniform1iv( location, uniform._array );
A
alteredq 已提交
4661

4662
				for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
4663

4664
					texture = uniform.texture[ i ];
4665

4666
					if ( !texture ) continue;
M
Mr.doob 已提交
4667

4668
					_this.setTexture( texture, uniform._array[ i ] );
M
Mr.doob 已提交
4669

M
Mr.doob 已提交
4670
				}
M
Mr.doob 已提交
4671

M
Mr.doob 已提交
4672
			}
M
Mr.doob 已提交
4673

M
Mr.doob 已提交
4674
		}
M
Mr.doob 已提交
4675

4676
	};
M
Mr.doob 已提交
4677

A
alteredq 已提交
4678
	function setupMatrices ( object, camera ) {
M
Mr.doob 已提交
4679

4680
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
M
Mr.doob 已提交
4681

4682
		var inverseMatrix = THREE.Matrix4.makeInvert3x3( object._modelViewMatrix );
4683

4684
		if ( inverseMatrix ) {
4685

4686
			inverseMatrix.transposeIntoArray( object._normalMatrixArray );
M
Mr.doob 已提交
4687

4688
		}
M
Mr.doob 已提交
4689

A
alteredq 已提交
4690
	};
M
Mr.doob 已提交
4691

4692
	function setupLights ( program, lights ) {
M
Mr.doob 已提交
4693

4694 4695 4696
		var l, ll, light, n,
		r = 0, g = 0, b = 0,
		color, position, intensity, distance,
M
Mr.doob 已提交
4697

4698
		zlights = _lights,
A
alteredq 已提交
4699

4700 4701
		dcolors = zlights.directional.colors,
		dpositions = zlights.directional.positions,
A
alteredq 已提交
4702

4703 4704 4705
		pcolors = zlights.point.colors,
		ppositions = zlights.point.positions,
		pdistances = zlights.point.distances,
4706

4707 4708
		dlength = 0,
		plength = 0,
4709

4710 4711
		doffset = 0,
		poffset = 0;
4712

4713
		for ( l = 0, ll = lights.length; l < ll; l ++ ) {
4714

4715
			light = lights[ l ];
A
alteredq 已提交
4716

A
alteredq 已提交
4717 4718 4719
			if ( light.onlyShadow ) continue;

			color = light.color;
4720 4721
			intensity = light.intensity;
			distance = light.distance;
A
alteredq 已提交
4722

4723
			if ( light instanceof THREE.AmbientLight ) {
4724

4725
				if ( _this.gammaInput ) {
4726

4727 4728 4729
					r += color.r * color.r;
					g += color.g * color.g;
					b += color.b * color.b;
4730

4731
				} else {
4732

4733 4734 4735
					r += color.r;
					g += color.g;
					b += color.b;
4736

4737
				}
4738

4739
			} else if ( light instanceof THREE.DirectionalLight ) {
4740

4741
				doffset = dlength * 3;
4742

4743
				if ( _this.gammaInput ) {
4744

4745 4746 4747
					dcolors[ doffset ]     = color.r * color.r * intensity * intensity;
					dcolors[ doffset + 1 ] = color.g * color.g * intensity * intensity;
					dcolors[ doffset + 2 ] = color.b * color.b * intensity * intensity;
4748

4749
				} else {
4750

4751 4752 4753
					dcolors[ doffset ]     = color.r * intensity;
					dcolors[ doffset + 1 ] = color.g * intensity;
					dcolors[ doffset + 2 ] = color.b * intensity;
A
alteredq 已提交
4754

4755
				}
A
alteredq 已提交
4756

A
alteredq 已提交
4757 4758 4759 4760 4761 4762 4763
				position = light.matrixWorld.getPosition();

				n = 1 / position.length();

				dpositions[ doffset ]     = position.x * n;
				dpositions[ doffset + 1 ] = position.y * n;
				dpositions[ doffset + 2 ] = position.z * n;
A
alteredq 已提交
4764

4765
				dlength += 1;
A
alteredq 已提交
4766

A
alteredq 已提交
4767
			} else if ( light instanceof THREE.SpotLight ) { // hack, not a proper spotlight
A
alteredq 已提交
4768

4769
				doffset = dlength * 3;
A
alteredq 已提交
4770

4771
				if ( _this.gammaInput ) {
4772

4773 4774 4775
					dcolors[ doffset ]     = color.r * color.r * intensity * intensity;
					dcolors[ doffset + 1 ] = color.g * color.g * intensity * intensity;
					dcolors[ doffset + 2 ] = color.b * color.b * intensity * intensity;
4776

4777
				} else {
A
alteredq 已提交
4778

4779 4780 4781
					dcolors[ doffset ]     = color.r * intensity;
					dcolors[ doffset + 1 ] = color.g * intensity;
					dcolors[ doffset + 2 ] = color.b * intensity;
A
alteredq 已提交
4782 4783 4784

				}

A
alteredq 已提交
4785 4786
				position = light.matrixWorld.getPosition();

4787
				n = 1 / position.length();
A
alteredq 已提交
4788

4789 4790 4791
				dpositions[ doffset ]     = position.x * n;
				dpositions[ doffset + 1 ] = position.y * n;
				dpositions[ doffset + 2 ] = position.z * n;
M
Mr.doob 已提交
4792

4793
				dlength += 1;
4794

4795
			} else if( light instanceof THREE.PointLight ) {
M
Mr.doob 已提交
4796

4797
				poffset = plength * 3;
M
Mr.doob 已提交
4798

4799
				if ( _this.gammaInput ) {
4800

4801 4802 4803
					pcolors[ poffset ]     = color.r * color.r * intensity * intensity;
					pcolors[ poffset + 1 ] = color.g * color.g * intensity * intensity;
					pcolors[ poffset + 2 ] = color.b * color.b * intensity * intensity;
A
alteredq 已提交
4804

4805
				} else {
A
alteredq 已提交
4806

4807 4808 4809
					pcolors[ poffset ]     = color.r * intensity;
					pcolors[ poffset + 1 ] = color.g * intensity;
					pcolors[ poffset + 2 ] = color.b * intensity;
A
alteredq 已提交
4810

4811
				}
A
alteredq 已提交
4812

A
alteredq 已提交
4813 4814
				position = light.matrixWorld.getPosition();

4815 4816 4817
				ppositions[ poffset ]     = position.x;
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
A
alteredq 已提交
4818

4819
				pdistances[ plength ] = distance;
A
alteredq 已提交
4820

4821
				plength += 1;
4822

4823
			}
4824

4825
		}
A
alteredq 已提交
4826

4827 4828
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
A
alteredq 已提交
4829

4830 4831
		for ( l = dlength * 3, ll = dcolors.length; l < ll; l ++ ) dcolors[ l ] = 0.0;
		for ( l = plength * 3, ll = pcolors.length; l < ll; l ++ ) pcolors[ l ] = 0.0;
A
alteredq 已提交
4832

4833 4834
		zlights.point.length = plength;
		zlights.directional.length = dlength;
A
alteredq 已提交
4835

4836 4837 4838
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
4839

4840
	};
M
Mr.doob 已提交
4841

4842
	// GL state setting
M
Mr.doob 已提交
4843

4844
	this.setFaceCulling = function ( cullFace, frontFace ) {
M
Mr.doob 已提交
4845

4846
		if ( cullFace ) {
M
Mr.doob 已提交
4847

4848
			if ( !frontFace || frontFace === "ccw" ) {
4849

4850
				_gl.frontFace( _gl.CCW );
4851

4852
			} else {
4853

4854
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
4855

4856
			}
M
Mr.doob 已提交
4857

4858
			if( cullFace === "back" ) {
4859

4860
				_gl.cullFace( _gl.BACK );
4861

4862
			} else if( cullFace === "front" ) {
4863

4864
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
4865

4866
			} else {
4867

4868
				_gl.cullFace( _gl.FRONT_AND_BACK );
4869

4870
			}
4871

4872
			_gl.enable( _gl.CULL_FACE );
4873

4874
		} else {
4875

4876
			_gl.disable( _gl.CULL_FACE );
4877 4878 4879 4880 4881

		}

	};

A
alteredq 已提交
4882
	this.setObjectFaces = function ( object ) {
4883

4884
		if ( _oldDoubleSided !== object.doubleSided ) {
M
Mr.doob 已提交
4885

4886
			if( object.doubleSided ) {
M
Mr.doob 已提交
4887

4888
				_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
4889

4890
			} else {
4891

4892
				_gl.enable( _gl.CULL_FACE );
4893

4894
			}
4895

4896
			_oldDoubleSided = object.doubleSided;
4897

4898
		}
4899

4900
		if ( _oldFlipSided !== object.flipSided ) {
4901

4902
			if( object.flipSided ) {
4903

4904
				_gl.frontFace( _gl.CW );
4905

4906
			} else {
4907

4908
				_gl.frontFace( _gl.CCW );
4909

4910
			}
4911

4912
			_oldFlipSided = object.flipSided;
4913

4914
		}
4915

4916
	};
4917

A
alteredq 已提交
4918
	this.setDepthTest = function ( depthTest ) {
4919

4920
		if ( _oldDepthTest !== depthTest ) {
4921

4922
			if ( depthTest ) {
4923

4924
				_gl.enable( _gl.DEPTH_TEST );
4925

4926
			} else {
4927

4928
				_gl.disable( _gl.DEPTH_TEST );
4929 4930 4931

			}

4932
			_oldDepthTest = depthTest;
4933

4934
		}
4935

4936
	};
4937

4938
	this.setDepthWrite = function ( depthWrite ) {
A
alteredq 已提交
4939

4940
		if ( _oldDepthWrite !== depthWrite ) {
A
alteredq 已提交
4941

4942 4943
			_gl.depthMask( depthWrite );
			_oldDepthWrite = depthWrite;
A
alteredq 已提交
4944 4945 4946 4947 4948

		}

	};

4949
	function setLineWidth ( width ) {
4950

4951
		if ( width !== _oldLineWidth ) {
4952

4953 4954 4955
			_gl.lineWidth( width );

			_oldLineWidth = width;
4956 4957 4958

		}

4959
	};
4960

4961
	function setPolygonOffset ( polygonoffset, factor, units ) {
4962

4963
		if ( _oldPolygonOffset !== polygonoffset ) {
M
Mr.doob 已提交
4964

4965
			if ( polygonoffset ) {
4966

4967
				_gl.enable( _gl.POLYGON_OFFSET_FILL );
4968

4969
			} else {
4970

4971
				_gl.disable( _gl.POLYGON_OFFSET_FILL );
4972

4973
			}
4974

4975
			_oldPolygonOffset = polygonoffset;
4976

4977
		}
4978

4979
		if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
4980

4981
			_gl.polygonOffset( factor, units );
M
Mr.doob 已提交
4982

4983 4984
			_oldPolygonOffsetFactor = factor;
			_oldPolygonOffsetUnits = units;
M
Mr.doob 已提交
4985

4986
		}
M
Mr.doob 已提交
4987

4988
	};
M
Mr.doob 已提交
4989

4990
	this.setBlending = function ( blending ) {
M
Mr.doob 已提交
4991

4992
		if ( blending !== _oldBlending ) {
M
Mr.doob 已提交
4993

4994
			switch ( blending ) {
M
Mr.doob 已提交
4995

4996
				case THREE.AdditiveBlending:
M
Mr.doob 已提交
4997

4998 4999
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
M
Mr.doob 已提交
5000

5001
					break;
M
Mr.doob 已提交
5002

5003
				case THREE.SubtractiveBlending:
M
Mr.doob 已提交
5004

5005
					// TODO: Find blendFuncSeparate() combination
M
Mr.doob 已提交
5006

5007 5008
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
M
Mr.doob 已提交
5009

5010
					break;
M
Mr.doob 已提交
5011

5012
				case THREE.MultiplyBlending:
M
Mr.doob 已提交
5013

5014
					// TODO: Find blendFuncSeparate() combination
M
Mr.doob 已提交
5015

5016 5017
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
M
Mr.doob 已提交
5018

5019
					break;
5020

5021
				default:
N
Nicolas Garcia Belmonte 已提交
5022

5023 5024
					_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 );
5025

5026
					break;
5027

5028
			}
5029

5030
			_oldBlending = blending;
5031

5032
		}
5033 5034

	};
5035

5036 5037 5038
	// Shaders

	function buildProgram ( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
5039

5040
		var p, pl, program, code;
5041
		var chunks = [];
5042 5043 5044

		// Generate code

5045 5046 5047 5048 5049 5050 5051 5052 5053 5054
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

			chunks.push( fragmentShader );
			chunks.push( vertexShader );

		}
5055 5056 5057

		for ( p in parameters ) {

5058 5059
			chunks.push( p );
			chunks.push( parameters[ p ] );
5060 5061 5062

		}

5063 5064
		code = chunks.join();

5065 5066 5067 5068
		// Check if code has been already compiled

		for ( p = 0, pl = _programs.length; p < pl; p ++ ) {

5069
			if ( _programs[ p ].code === code ) {
5070 5071

				// console.log( "Code already compiled." /*: \n\n" + code*/ );
5072

5073 5074 5075 5076 5077
				return _programs[ p ].program;

			}

		}
5078

5079
		//console.log( "building new program " );
5080 5081 5082

		//

5083
		program = _gl.createProgram();
M
Mr.doob 已提交
5084

5085
		var prefix_vertex = [
M
Mr.doob 已提交
5086

5087
			( _maxVertexTextures > 0 ) ? "#define VERTEX_TEXTURES" : "",
5088

5089 5090 5091 5092
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

5093 5094 5095
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

5096 5097
			"#define MAX_SHADOWS " + parameters.maxShadows,

5098 5099
			"#define MAX_BONES " + parameters.maxBones,

5100
			parameters.map ? "#define USE_MAP" : "",
5101 5102 5103
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5104
			parameters.skinning ? "#define USE_SKINNING" : "",
5105
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
A
alteredq 已提交
5106
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
5107
			parameters.wrapAround ? "#define WRAP_AROUND" : "",
5108

5109
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5110
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
5111

5112 5113
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
5114 5115 5116
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
5117 5118
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
5119
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
5120 5121 5122

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
5123 5124 5125
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
5126
			"attribute vec2 uv2;",
5127

5128
			"#ifdef USE_COLOR",
5129

5130
				"attribute vec3 color;",
5131

5132 5133
			"#endif",

5134
			"#ifdef USE_MORPHTARGETS",
5135

5136 5137 5138 5139 5140 5141 5142 5143
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
				"attribute vec3 morphTarget4;",
				"attribute vec3 morphTarget5;",
				"attribute vec3 morphTarget6;",
				"attribute vec3 morphTarget7;",
5144

5145 5146 5147
			"#endif",

			"#ifdef USE_SKINNING",
5148

5149 5150 5151 5152
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
5153

5154
			"#endif",
5155

M
Mr.doob 已提交
5156
			""
A
alteredq 已提交
5157

M
Mr.doob 已提交
5158
		].join("\n");
5159

M
Mr.doob 已提交
5160 5161
		var prefix_fragment = [

5162
			"precision " + _precision + " float;",
M
Mr.doob 已提交
5163 5164 5165 5166

			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

5167 5168
			"#define MAX_SHADOWS " + parameters.maxShadows,

5169 5170
			parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",

5171 5172 5173 5174
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

M
Mr.doob 已提交
5175 5176
			( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
			( parameters.useFog && parameters.fog instanceof THREE.FogExp2 ) ? "#define FOG_EXP2" : "",
M
Mr.doob 已提交
5177 5178 5179 5180 5181

			parameters.map ? "#define USE_MAP" : "",
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5182

5183 5184
			parameters.metal ? "#define METAL" : "",
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
5185
			parameters.wrapAround ? "#define WRAP_AROUND" : "",
5186

5187
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5188
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
M
Mr.doob 已提交
5189 5190 5191 5192 5193 5194 5195

			"uniform mat4 viewMatrix;",
			"uniform vec3 cameraPosition;",
			""

		].join("\n");

5196 5197
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
5198

M
Mr.doob 已提交
5199
		_gl.linkProgram( program );
N
Nicolas Garcia Belmonte 已提交
5200

M
Mr.doob 已提交
5201
		if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
N
Nicolas Garcia Belmonte 已提交
5202

5203
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
5204

N
Nicolas Garcia Belmonte 已提交
5205
		}
5206

5207 5208
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
5209

M
Mr.doob 已提交
5210
		program.uniforms = {};
5211
		program.attributes = {};
M
Mr.doob 已提交
5212

5213 5214 5215 5216
		var identifiers, u, a, i;

		// cache uniform locations

5217
		identifiers = [
5218

5219 5220
			'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
			'cameraInverseMatrix', 'boneGlobalMatrices', 'morphTargetInfluences'
M
Mr.doob 已提交
5221

5222
		];
M
Mr.doob 已提交
5223

5224
		for ( u in uniforms ) {
M
Mr.doob 已提交
5225

5226
			identifiers.push( u );
M
Mr.doob 已提交
5227

5228
		}
M
Mr.doob 已提交
5229

5230
		cacheUniformLocations( program, identifiers );
M
Mr.doob 已提交
5231

5232
		// cache attributes locations
M
Mr.doob 已提交
5233

5234
		identifiers = [
A
alteredq 已提交
5235

5236 5237
			"position", "normal", "uv", "uv2", "tangent", "color",
			"skinVertexA", "skinVertexB", "skinIndex", "skinWeight"
A
alteredq 已提交
5238

5239
		];
M
Mr.doob 已提交
5240

5241
		for ( i = 0; i < parameters.maxMorphTargets; i ++ ) {
M
Mr.doob 已提交
5242

5243
			identifiers.push( "morphTarget" + i );
M
Mr.doob 已提交
5244

5245
		}
5246

5247
		for ( a in attributes ) {
5248

5249
			identifiers.push( a );
5250

5251
		}
5252

5253
		cacheAttributeLocations( program, identifiers );
5254

5255
		program.id = _programs.length;
5256

5257
		_programs.push( { program: program, code: code } );
5258

5259
		_this.info.memory.programs = _programs.length;
5260

5261
		return program;
5262

5263
	};
5264

5265
	// Shader parameters cache
5266

5267
	function cacheUniformLocations ( program, identifiers ) {
5268

5269
		var i, l, id;
5270

5271
		for( i = 0, l = identifiers.length; i < l; i ++ ) {
5272

5273 5274
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
5275

5276
		}
M
Mr.doob 已提交
5277

5278
	};
M
Mr.doob 已提交
5279

5280
	function cacheAttributeLocations ( program, identifiers ) {
A
alteredq 已提交
5281

5282
		var i, l, id;
A
alteredq 已提交
5283

5284
		for( i = 0, l = identifiers.length; i < l; i ++ ) {
A
alteredq 已提交
5285

5286 5287
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
A
alteredq 已提交
5288

5289
		}
5290

5291
	};
A
alteredq 已提交
5292

5293
	function getShader ( type, string ) {
A
alteredq 已提交
5294

5295
		var shader;
5296

5297
		if ( type === "fragment" ) {
A
alteredq 已提交
5298

5299
			shader = _gl.createShader( _gl.FRAGMENT_SHADER );
A
alteredq 已提交
5300

5301
		} else if ( type === "vertex" ) {
A
alteredq 已提交
5302

5303
			shader = _gl.createShader( _gl.VERTEX_SHADER );
A
alteredq 已提交
5304

5305
		}
A
alteredq 已提交
5306

5307 5308
		_gl.shaderSource( shader, string );
		_gl.compileShader( shader );
5309

5310
		if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {
5311

5312 5313 5314
			console.error( _gl.getShaderInfoLog( shader ) );
			console.error( string );
			return null;
5315

A
alteredq 已提交
5316 5317
		}

5318 5319
		return shader;

A
alteredq 已提交
5320
	};
5321

5322 5323
	// Textures

5324 5325 5326 5327 5328 5329 5330

	function isPowerOfTwo ( value ) {

		return ( value & ( value - 1 ) ) === 0;

	};

5331
	function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {
5332

5333
		if ( isImagePowerOfTwo ) {
M
Mr.doob 已提交
5334

5335 5336
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
5337

5338 5339
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
5340

5341
		} else {
M
Mr.doob 已提交
5342

5343 5344
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
5345

5346 5347
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
5348

5349
		}
M
Mr.doob 已提交
5350

5351
	};
5352

5353
	this.setTexture = function ( texture, slot ) {
5354

5355
		if ( texture.needsUpdate ) {
A
alteredq 已提交
5356

5357
			if ( ! texture.__webglInit ) {
M
Mr.doob 已提交
5358

5359
				texture.__webglInit = true;
5360
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5361

M
Mr.doob 已提交
5362 5363
				_this.info.memory.textures ++;

5364
			}
M
Mr.doob 已提交
5365

5366
			_gl.activeTexture( _gl.TEXTURE0 + slot );
5367 5368
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );

5369 5370
			var image = texture.image,
			isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
5371 5372
			glFormat = paramThreeToGL( texture.format ),
			glType = paramThreeToGL( texture.type );
5373

5374 5375
			setTextureParameters( _gl.TEXTURE_2D, texture, isImagePowerOfTwo );

5376
			if ( texture instanceof THREE.DataTexture ) {
5377

5378
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );
M
Mr.doob 已提交
5379

A
alteredq 已提交
5380
			} else {
M
Mr.doob 已提交
5381

5382
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, texture.image );
M
Mr.doob 已提交
5383 5384 5385

			}

5386
			if ( texture.generateMipmaps && isImagePowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
M
Mr.doob 已提交
5387

A
alteredq 已提交
5388
			texture.needsUpdate = false;
5389

5390 5391
			if ( texture.onUpdated ) texture.onUpdated();

5392
		} else {
5393

5394 5395
			_gl.activeTexture( _gl.TEXTURE0 + slot );
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
5396 5397

		}
M
Mr.doob 已提交
5398

5399
	};
M
Mr.doob 已提交
5400

5401 5402 5403 5404 5405 5406 5407 5408 5409 5410
	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.
5411

5412 5413 5414 5415 5416 5417 5418
		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;
5419

5420
		var ctx = canvas.getContext( "2d" );
5421 5422
		ctx.drawImage( image, 0, 0, image.width, image.height, 0, 0, newWidth, newHeight );

5423 5424 5425 5426
		return canvas;

	}

5427
	function setCubeTexture ( texture, slot ) {
5428

5429
		if ( texture.image.length === 6 ) {
5430 5431 5432

			if ( texture.needsUpdate ) {

A
alteredq 已提交
5433
				if ( ! texture.image.__webglTextureCube ) {
5434 5435

					texture.image.__webglTextureCube = _gl.createTexture();
5436

A
alteredq 已提交
5437
				}
5438

A
alteredq 已提交
5439 5440
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5441

5442
				var cubeImage = [];
5443

A
alteredq 已提交
5444
				for ( var i = 0; i < 6; i ++ ) {
5445

5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457
					if ( _this.autoScaleCubemaps ) {

						cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize );

					} else {

						cubeImage[ i ] = texture.image[ i ];

					}

				}

5458 5459
				var image = cubeImage[ 0 ],
				isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
5460 5461
				glFormat = paramThreeToGL( texture.format ),
				glType = paramThreeToGL( texture.type );
5462

5463 5464
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo );

A
alteredq 已提交
5465
				for ( var i = 0; i < 6; i ++ ) {
5466

5467
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
5468

A
alteredq 已提交
5469
				}
5470

5471
				if ( texture.generateMipmaps && isImagePowerOfTwo )	_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
5472

A
alteredq 已提交
5473
				texture.needsUpdate = false;
5474

5475 5476
				if ( texture.onUpdated ) texture.onUpdated();

A
alteredq 已提交
5477
			} else {
5478

A
alteredq 已提交
5479 5480
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5481

A
alteredq 已提交
5482
			}
5483

A
alteredq 已提交
5484
		}
5485

A
alteredq 已提交
5486
	};
5487

5488
	function setCubeTextureDynamic ( texture, slot ) {
5489

A
alteredq 已提交
5490 5491
		_gl.activeTexture( _gl.TEXTURE0 + slot );
		_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
5492 5493 5494

	};

5495 5496 5497
	// Render targets

	function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
5498

5499 5500
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
A
alteredq 已提交
5501

5502
	};
M
Mr.doob 已提交
5503

5504
	function setupRenderBuffer ( renderbuffer, renderTarget  ) {
M
Mikael Emtinger 已提交
5505

5506
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
5507

5508
		if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
M
Mr.doob 已提交
5509

5510 5511
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5512

5513 5514
		/* For some reason this is not working. Defaulting to RGBA4.
		} else if( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
A
alteredq 已提交
5515

5516 5517 5518 5519
			_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 已提交
5520

5521 5522
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5523

5524
		} else {
A
alteredq 已提交
5525

5526
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
A
alteredq 已提交
5527

5528
		}
A
alteredq 已提交
5529

5530
	};
A
alteredq 已提交
5531

A
alteredq 已提交
5532
	this.setRenderTarget = function ( renderTarget ) {
A
alteredq 已提交
5533

5534
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
A
alteredq 已提交
5535

5536
		if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
A
alteredq 已提交
5537

5538 5539
			if( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
			if( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
A
alteredq 已提交
5540

5541
			renderTarget.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5542

5543
			// Setup texture, create render and frame buffers
5544

5545 5546
			var isTargetPowerOfTwo = isPowerOfTwo( renderTarget.width ) && isPowerOfTwo( renderTarget.height ),
				glFormat = paramThreeToGL( renderTarget.format ),
5547 5548
				glType = paramThreeToGL( renderTarget.type );

5549
			if ( isCube ) {
M
Mr.doob 已提交
5550

5551 5552
				renderTarget.__webglFramebuffer = [];
				renderTarget.__webglRenderbuffer = [];
M
Mikael Emtinger 已提交
5553

5554
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
5555
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, isTargetPowerOfTwo );
A
alteredq 已提交
5556

5557
				for ( var i = 0; i < 6; i ++ ) {
A
alteredq 已提交
5558

5559 5560
					renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
					renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
A
alteredq 已提交
5561

5562
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
A
alteredq 已提交
5563

5564 5565
					setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
					setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
A
alteredq 已提交
5566

5567
				}
5568

5569
			} else {
5570

5571 5572
				renderTarget.__webglFramebuffer = _gl.createFramebuffer();
				renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
5573

5574
				_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
5575
				setTextureParameters( _gl.TEXTURE_2D, renderTarget, isTargetPowerOfTwo );
5576

5577
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
5578

5579 5580
				setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
				setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
5581

M
Mikael Emtinger 已提交
5582
			}
5583

5584
			// Release everything
M
Mr.doob 已提交
5585

A
alteredq 已提交
5586 5587 5588 5589 5590 5591 5592 5593 5594 5595
			if ( isCube ) {

				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

			} else {

				_gl.bindTexture( _gl.TEXTURE_2D, null );

			}

5596 5597
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
5598

5599 5600
		}

5601
		var framebuffer, width, height, vx, vy;
M
Mr.doob 已提交
5602

5603
		if ( renderTarget ) {
M
Mr.doob 已提交
5604

A
alteredq 已提交
5605 5606
			if ( isCube ) {

5607
				framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
A
alteredq 已提交
5608 5609 5610

			} else {

5611
				framebuffer = renderTarget.__webglFramebuffer;
A
alteredq 已提交
5612 5613 5614

			}

5615 5616
			width = renderTarget.width;
			height = renderTarget.height;
M
Mr.doob 已提交
5617

5618 5619 5620
			vx = 0;
			vy = 0;

5621
		} else {
M
Mr.doob 已提交
5622

5623
			framebuffer = null;
5624

5625 5626
			width = _viewportWidth;
			height = _viewportHeight;
5627

5628 5629
			vx = _viewportX;
			vy = _viewportY;
M
Mr.doob 已提交
5630

5631
		}
M
Mr.doob 已提交
5632

5633
		if ( framebuffer !== _currentFramebuffer ) {
M
Mr.doob 已提交
5634

5635
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
5636
			_gl.viewport( vx, vy, width, height );
M
Mr.doob 已提交
5637

5638
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
5639

5640
		}
5641

A
alteredq 已提交
5642 5643 5644
		_currentWidth = width;
		_currentHeight = height;

5645
	};
M
Mr.doob 已提交
5646

5647
	function updateRenderTargetMipmap ( renderTarget ) {
M
Mr.doob 已提交
5648

A
alteredq 已提交
5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661
		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 已提交
5662 5663

	};
5664

5665
	// Fallback filters for non-power-of-2 textures
5666

5667
	function filterFallback ( f ) {
5668

5669 5670 5671 5672 5673 5674 5675 5676
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mr.doob 已提交
5677
			case THREE.LinearMipMapLinearFilter:
M
Mikael Emtinger 已提交
5678
			default:
5679

M
Mikael Emtinger 已提交
5680
				return _gl.LINEAR; break;
5681 5682

		}
5683

5684
	};
5685

5686 5687
	// Map three.js constants to WebGL constants

5688
	function paramThreeToGL ( p ) {
M
Mr.doob 已提交
5689

5690
		switch ( p ) {
M
Mr.doob 已提交
5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703

			case THREE.RepeatWrapping: return _gl.REPEAT; break;
			case THREE.ClampToEdgeWrapping: return _gl.CLAMP_TO_EDGE; break;
			case THREE.MirroredRepeatWrapping: return _gl.MIRRORED_REPEAT; break;

			case THREE.NearestFilter: return _gl.NEAREST; break;
			case THREE.NearestMipMapNearestFilter: return _gl.NEAREST_MIPMAP_NEAREST; break;
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST_MIPMAP_LINEAR; break;

			case THREE.LinearFilter: return _gl.LINEAR; break;
			case THREE.LinearMipMapNearestFilter: return _gl.LINEAR_MIPMAP_NEAREST; break;
			case THREE.LinearMipMapLinearFilter: return _gl.LINEAR_MIPMAP_LINEAR; break;

5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717
			case THREE.ByteType: return _gl.BYTE; break;
			case THREE.UnsignedByteType: return _gl.UNSIGNED_BYTE; break;
			case THREE.ShortType: return _gl.SHORT; break;
			case THREE.UnsignedShortType: return _gl.UNSIGNED_SHORT; break;
			case THREE.IntType: return _gl.INT; break;
			case THREE.UnsignedShortType: return _gl.UNSIGNED_INT; break;
			case THREE.FloatType: return _gl.FLOAT; break;

			case THREE.AlphaFormat: return _gl.ALPHA; break;
			case THREE.RGBFormat: return _gl.RGB; break;
			case THREE.RGBAFormat: return _gl.RGBA; break;
			case THREE.LuminanceFormat: return _gl.LUMINANCE; break;
			case THREE.LuminanceAlphaFormat: return _gl.LUMINANCE_ALPHA; break;

5718
		}
M
Mr.doob 已提交
5719

5720
		return 0;
M
Mr.doob 已提交
5721

5722 5723
	};

5724
	// Allocations
5725

5726
	function allocateBones ( object ) {
5727

5728 5729 5730 5731 5732 5733 5734
		// 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)
5735

5736
		var maxBones = 50;
5737

5738
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
5739

5740 5741 5742 5743 5744
			maxBones = object.bones.length;

		}

		return maxBones;
5745

5746
	};
5747

5748
	function allocateLights ( lights ) {
5749

5750 5751
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
5752

5753
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
5754

5755
			light = lights[ l ];
5756

A
alteredq 已提交
5757 5758 5759
			if ( light.onlyShadow ) continue;

			if ( light instanceof THREE.SpotLight ) dirLights ++; // hack, not a proper spotlight
5760 5761
			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
			if ( light instanceof THREE.PointLight ) pointLights ++;
5762

5763
		}
5764

5765
		if ( ( pointLights + dirLights ) <= _maxLights ) {
5766

5767 5768
			maxDirLights = dirLights;
			maxPointLights = pointLights;
5769

5770
		} else {
5771

5772 5773
			maxDirLights = Math.ceil( _maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = _maxLights - maxDirLights;
5774 5775 5776

		}

5777
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
5778 5779

	};
M
Mr.doob 已提交
5780

5781
	function allocateShadows ( lights ) {
5782

M
Mr.doob 已提交
5783
		var l, ll, light, maxShadows = 0;
5784 5785 5786 5787 5788

		for ( l = 0, ll = lights.length; l < ll; l++ ) {

			light = lights[ l ];

A
alteredq 已提交
5789 5790 5791
			if ( ! light.castShadow ) continue;

			if ( light instanceof THREE.SpotLight || light instanceof THREE.DirectionalLight ) maxShadows ++;
5792 5793 5794 5795 5796 5797 5798

		}

		return maxShadows;

	};

5799
	// Initialization
M
Mr.doob 已提交
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 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851
	function initGL () {

		var gl;

		try {

			if ( ! ( gl = _canvas.getContext( 'experimental-webgl', { antialias: _antialias, stencil: _stencil, preserveDrawingBuffer: _preserveDrawingBuffer } ) ) ) {

				throw 'Error creating WebGL context.';

			}

			console.log(
				navigator.userAgent + " | " +
				gl.getParameter( gl.VERSION ) + " | " +
				gl.getParameter( gl.VENDOR ) + " | " +
				gl.getParameter( gl.RENDERER ) + " | " +
				gl.getParameter( gl.SHADING_LANGUAGE_VERSION )
			);

		} catch ( error ) {

			console.error( error );

		}

		return gl;

	};

	function setDefaultGLState () {

		_gl.clearColor( 0, 0, 0, 1 );
		_gl.clearDepth( 1 );
		_gl.clearStencil( 0 );

		_gl.enable( _gl.DEPTH_TEST );
		_gl.depthFunc( _gl.LEQUAL );

		_gl.frontFace( _gl.CCW );
		_gl.cullFace( _gl.BACK );
		_gl.enable( _gl.CULL_FACE );

		_gl.enable( _gl.BLEND );
		_gl.blendEquation( _gl.FUNC_ADD );
		_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA );

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

	};

5852 5853
	// default plugins (order is important)

A
alteredq 已提交
5854 5855 5856 5857 5858
	this.shadowMapPlugin = new THREE.ShadowMapPlugin();
	this.addPrePlugin( this.shadowMapPlugin );

	this.addPostPlugin( new THREE.SpritePlugin() );
	this.addPostPlugin( new THREE.LensFlarePlugin() );
5859

5860
};