WebGLRenderer.js 142.3 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
	var parameters = parameters || {},
M
Mr.doob 已提交
13

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

16
	_precision = parameters.precision !== undefined ? parameters.precision : 'highp',
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 54 55 56 57 58 59 60 61
	// shadow map

	this.shadowMapBias = 0.0039;
	this.shadowMapDarkness = 0.5;
	this.shadowMapWidth = 512;
	this.shadowMapHeight = 512;

	this.shadowCameraNear = 1;
	this.shadowCameraFar = 5000;
	this.shadowCameraFov = 50;

62
	this.shadowMap = [];
63

64
	this.shadowMapEnabled = false;
65
	this.shadowMapAutoUpdate = true;
66
	this.shadowMapSoft = true;
67

68
	// morphs
69

70
	this.maxMorphTargets = 8;
71

72
	// info
73

74
	this.info = {
75

76
		memory: {
77

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

82
		},
83

84
		render: {
85

86 87 88
			calls: 0,
			vertices: 0,
			faces: 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,
126

127
	// frustum cache
M
Mr.doob 已提交
128

129 130 131 132 133 134 135 136
	_frustum = [
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4()
	 ],
137

138
	 // camera matrices cache
M
Mikael Emtinger 已提交
139

140 141 142
	_projScreenMatrix = new THREE.Matrix4(),
	_projectionMatrixArray = new Float32Array( 16 ),
	_viewMatrixArray = new Float32Array( 16 ),
M
Mr.doob 已提交
143

144
	_vector3 = new THREE.Vector4(),
M
Mikael Emtinger 已提交
145

146
	// light arrays cache
M
Mikael Emtinger 已提交
147

148
	_lights = {
M
Mr.doob 已提交
149

150 151 152
		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 已提交
153

154
	};
M
Mr.doob 已提交
155

156
	// shadow maps
M
Mr.doob 已提交
157

158 159
	var _cameraLight, _shadowMatrix = [];
	var _depthMaterial, _depthMaterialMorph;
M
Mikael Emtinger 已提交
160

161
	// sprites
M
Mr.doob 已提交
162

163 164
	var _sprite = {};
	var _spriteAttributesEnabled = false;
M
Mikael Emtinger 已提交
165

166
	// initialize
M
Mikael Emtinger 已提交
167

168
	_gl = initGL();
M
Mikael Emtinger 已提交
169

170
	setDefaultGLState();
M
Mikael Emtinger 已提交
171

172 173
	initSprites();
	initShadowmaps();
M
Mikael Emtinger 已提交
174

175
	this.context = _gl;
M
Mikael Emtinger 已提交
176

177
	var _supportsVertexTextures = ( maxVertexTextures() > 0 );
M
Mr.doob 已提交
178

179
	// API
M
Mr.doob 已提交
180

181
	this.getContext = function () {
M
Mr.doob 已提交
182

183
		return _gl;
M
Mr.doob 已提交
184

185
	};
M
Mr.doob 已提交
186

187
	this.supportsVertexTextures = function () {
M
Mikael Emtinger 已提交
188

189
		return _supportsVertexTextures;
M
Mikael Emtinger 已提交
190

191
	};
M
Mikael Emtinger 已提交
192

N
Nicolas Garcia Belmonte 已提交
193 194 195 196
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
197

198 199 200
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
201

202
	this.setViewport = function ( x, y, width, height ) {
203

204 205
		_viewportX = x;
		_viewportY = y;
206

207 208
		_viewportWidth = width;
		_viewportHeight = height;
209

210
		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
211

N
Nicolas Garcia Belmonte 已提交
212
	};
213

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

216
		_gl.scissor( x, y, width, height );
217

218
	};
219

220
	this.enableScissorTest = function ( enable ) {
221

M
Mr.doob 已提交
222
		enable ? _gl.enable( _gl.SCISSOR_TEST ) : _gl.disable( _gl.SCISSOR_TEST );
223 224

	};
225

226 227
	// Clearing

228
	this.setClearColorHex = function ( hex, alpha ) {
229

230 231 232 233
		_clearColor.setHex( hex );
		_clearAlpha = alpha;

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

235
	};
A
alteredq 已提交
236

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

239 240 241 242
		_clearColor.copy( color );
		_clearAlpha = alpha;

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

	};
245

M
Mr.doob 已提交
246 247 248 249 250 251 252
	this.getClearColor = function () {

		return _clearColor;

	};

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

M
Mr.doob 已提交
254 255 256 257 258 259 260 261
		return _clearAlpha;

	};

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

		var bits = 0;

262 263 264
		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 已提交
265 266

		_gl.clear( bits );
N
Nicolas Garcia Belmonte 已提交
267 268 269

	};

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

272 273
		setRenderTarget( renderTarget );
		this.clear( color, depth, stencil );
M
Mr.doob 已提交
274 275 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

330
		renderShadowMap( scene, camera );
M
Mr.doob 已提交
331

332
	};
M
Mr.doob 已提交
333

334
	// Internal functions
335

336
	// Buffer allocation
337

338
	function createParticleBuffers ( geometry ) {
339

340 341
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
342

343
		_this.info.geometries ++;
344

345
	};
346

347
	function createLineBuffers ( geometry ) {
348

349 350
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
351

352
		_this.info.memory.geometries ++;
353

354
	};
355

356
	function createRibbonBuffers ( geometry ) {
357

358 359
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
360

361
		_this.info.memory.geometries ++;
M
Mr.doob 已提交
362

363
	};
364

365
	function createMeshBuffers ( geometryGroup ) {
366

367 368 369 370 371 372
		geometryGroup.__webglVertexBuffer = _gl.createBuffer();
		geometryGroup.__webglNormalBuffer = _gl.createBuffer();
		geometryGroup.__webglTangentBuffer = _gl.createBuffer();
		geometryGroup.__webglColorBuffer = _gl.createBuffer();
		geometryGroup.__webglUVBuffer = _gl.createBuffer();
		geometryGroup.__webglUV2Buffer = _gl.createBuffer();
373

374 375 376 377
		geometryGroup.__webglSkinVertexABuffer = _gl.createBuffer();
		geometryGroup.__webglSkinVertexBBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinIndicesBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinWeightsBuffer = _gl.createBuffer();
378

379 380
		geometryGroup.__webglFaceBuffer = _gl.createBuffer();
		geometryGroup.__webglLineBuffer = _gl.createBuffer();
381

382
		if ( geometryGroup.numMorphTargets ) {
383

384
			var m, ml;
385

386
			geometryGroup.__webglMorphTargetsBuffers = [];
387

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

390
				geometryGroup.__webglMorphTargetsBuffers.push( _gl.createBuffer() );
391

392
			}
393

394
		}
395

396
		_this.info.memory.geometries ++;
397

398
	};
399

400
	// Buffer deallocation
401

402
	function deleteParticleBuffers ( geometry ) {
403

404 405
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
406

407
		_this.info.memory.geometries --;
408

409
	};
410

411
	function deleteLineBuffers ( geometry ) {
412

413 414
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
415

M
Mr.doob 已提交
416 417
		_this.info.memory.geometries --;

418 419
	};

420
	function deleteRibbonBuffers ( geometry ) {
421 422 423 424

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

M
Mr.doob 已提交
425 426
		_this.info.memory.geometries --;

427 428
	};

429
	function deleteMeshBuffers ( geometryGroup ) {
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447

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

448
			for ( var m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
449 450 451 452 453 454 455

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

			}

		}

456 457 458 459 460 461 462 463 464 465 466

		if ( geometryGroup.__webglCustomAttributesList ) {

			for ( var id in geometryGroup.__webglCustomAttributesList ) {

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

			}

		}

M
Mr.doob 已提交
467 468
		_this.info.memory.geometries --;

469 470
	};

471
	// Buffer initialization
472

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

475 476
		var nvertices = geometry.vertices.length;

477
		var material = object.material;
478

479
		if ( material.attributes ) {
480

481
			if ( geometry.__webglCustomAttributesList === undefined ) {
482

483
				geometry.__webglCustomAttributesList = [];
484

485
			}
486

487
			for ( var a in material.attributes ) {
488

489
				var attribute = material.attributes[ a ];
490

491
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
492

493
					attribute.__webglInitialized = true;
494

A
alteredq 已提交
495
					var size = 1;		// "f" and "i"
496

497 498 499 500
					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;
501

502
					attribute.size = size;
A
alteredq 已提交
503

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

506 507
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
508

509
					attribute.needsUpdate = true;
510

511
				}
512

513
				geometry.__webglCustomAttributesList.push( attribute );
514

515
			}
516

517
		}
518

519
	};
520

521
	function initParticleBuffers ( geometry, object ) {
A
alteredq 已提交
522 523 524 525 526 527

		var nvertices = geometry.vertices.length;

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

528 529 530
		geometry.__sortArray = [];

		geometry.__webglParticleCount = nvertices;
A
alteredq 已提交
531 532 533 534 535

		initCustomAttributes ( geometry, object );

	};

536
	function initLineBuffers ( geometry, object ) {
A
alteredq 已提交
537 538 539 540 541 542

		var nvertices = geometry.vertices.length;

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

543
		geometry.__webglLineCount = nvertices;
A
alteredq 已提交
544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559

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

562 563 564
		var geometry = object.geometry,
			faces3 = geometryGroup.faces3,
			faces4 = geometryGroup.faces4,
M
Mr.doob 已提交
565

566 567 568
			nvertices = faces3.length * 3 + faces4.length * 4,
			ntris     = faces3.length * 1 + faces4.length * 2,
			nlines    = faces3.length * 3 + faces4.length * 4,
569

570
			material = getBufferMaterial( object, geometryGroup ),
571

572 573 574
			uvType = bufferGuessUVType( material ),
			normalType = bufferGuessNormalType( material ),
			vertexColorType = bufferGuessVertexColorType( material );
A
alteredq 已提交
575

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

578
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
579

580
		if ( normalType ) {
M
Mr.doob 已提交
581

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

584
		}
585

586
		if ( geometry.hasTangents ) {
587

588
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
589

590
		}
591

592
		if ( vertexColorType ) {
593

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

596
		}
M
Mr.doob 已提交
597

598
		if ( uvType ) {
599

600
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
601

602 603 604 605 606
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

608 609 610 611 612 613 614 615 616 617 618 619 620 621 622
				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 );

		}

623
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
624
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
625

626 627
		if ( geometryGroup.numMorphTargets ) {

M
Mr.doob 已提交
628
			geometryGroup.__morphTargetsArrays = [];
629

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

632 633
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );

634 635 636
			}

		}
637

638
		geometryGroup.__needsSmoothNormals = ( normalType === THREE.SmoothShading );
639

640 641 642 643
		geometryGroup.__uvType = uvType;
		geometryGroup.__vertexColorType = vertexColorType;
		geometryGroup.__normalType = normalType;

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

M
Mr.doob 已提交
647

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

650
		if ( material.attributes ) {
651

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

654
				geometryGroup.__webglCustomAttributesList = [];
655

656
			}
657

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

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

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

665
				var attribute = {};
666

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

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

671
				}
672

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

675
					attribute.__webglInitialized = true;
676

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

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

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

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

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

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

				}

696 697
				geometryGroup.__webglCustomAttributesList.push( attribute );

698
			}
M
Mr.doob 已提交
699

700
		}
701

702 703
		geometryGroup.__inittedArrays = true;

704
	};
M
Mr.doob 已提交
705

706
	function getBufferMaterial( object, geometryGroup ) {
707

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

710
			return object.material;
711

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

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

716
		}
717

718
	};
M
Mr.doob 已提交
719

720
	function materialNeedsSmoothNormals ( material ) {
721

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

724
	};
M
Mr.doob 已提交
725

726
	function bufferGuessNormalType ( material ) {
727

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

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

732
			return false;
733

734
		}
735

736
		if ( materialNeedsSmoothNormals( material ) ) {
737

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

740
		} else {
741

742
			return THREE.FlatShading;
743

744
		}
745

746
	};
747

748
	function bufferGuessVertexColorType ( material ) {
749

750
		if ( material.vertexColors ) {
751

752
			return material.vertexColors;
753

754
		}
M
Mr.doob 已提交
755

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

758
	};
M
Mr.doob 已提交
759

760
	function bufferGuessUVType ( material ) {
761

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

		}

	};

	function setMeshBuffers( geometryGroup, object, hint, dispose ) {

		if ( ! geometryGroup.__inittedArrays ) {

			// console.log( object );
			return;

		}

		var f, fl, fi, face,
		vertexNormals, faceNormal, normal,
		vertexColors, faceColor,
		vertexTangents,
		uvType, vertexColorType, normalType,
		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,

		needsSmoothNormals = geometryGroup.__needsSmoothNormals,

		vertexColorType = geometryGroup.__vertexColorType,
		uvType = geometryGroup.__uvType,
		normalType = geometryGroup.__normalType,

		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

2633
	function renderBufferImmediate ( 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
	function renderBuffer ( camera, lights, fog, material, geometryGroup, object ) {
2707

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

2710
		var program, attributes, linewidth, primitives, a, attribute, i, il;
2711

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

2714
		attributes = program.attributes;
2715

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

2720
		if ( geometryGroupHash !== _currentGeometryGroupHash ) {
A
alteredq 已提交
2721

2722 2723
			_currentGeometryGroupHash = geometryGroupHash;
			updateBuffers = true;
2724

2725
		}
2726

2727
		// vertices
2728

2729
		if ( !material.morphTargets && attributes.position >= 0 ) {
2730

2731
			if ( updateBuffers ) {
2732

2733 2734
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
				_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
2735

2736
			}
2737

2738
		} else {
2739

2740
			if ( object.morphTargetBase ) {
2741

2742
				setupMorphTargets( material, geometryGroup, object );
2743

2744
			}
2745

2746
		}
2747

2748

2749
		if ( updateBuffers ) {
2750

2751
			// custom attributes
2752

2753
			// Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
2754

2755
			if ( geometryGroup.__webglCustomAttributesList ) {
2756

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

2759
					attribute = geometryGroup.__webglCustomAttributesList[ i ];
2760

2761
					if( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
2762

2763 2764
						_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
						_gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 );
2765

2766
					}
2767

2768
				}
2769

2770
			}
2771 2772


2773
			// colors
2774

2775
			if ( attributes.color >= 0 ) {
2776

2777 2778
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
2779

2780
			}
2781

2782
			// normals
2783

2784
			if ( attributes.normal >= 0 ) {
2785

2786 2787
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
				_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
2788

2789
			}
2790

2791
			// tangents
2792

2793
			if ( attributes.tangent >= 0 ) {
2794

2795 2796
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
				_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
2797

2798
			}
2799

2800
			// uvs
2801

2802
			if ( attributes.uv >= 0 ) {
2803

2804
				if ( geometryGroup.__webglUVBuffer ) {
2805

2806 2807
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
					_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
2808

2809
					_gl.enableVertexAttribArray( attributes.uv );
2810

2811
				} else {
2812

2813
					_gl.disableVertexAttribArray( attributes.uv );
2814 2815 2816 2817 2818

				}

			}

2819
			if ( attributes.uv2 >= 0 ) {
2820

2821
				if ( geometryGroup.__webglUV2Buffer ) {
2822

2823 2824
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
					_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
2825

2826
					_gl.enableVertexAttribArray( attributes.uv2 );
2827

2828
				} else {
2829

2830
					_gl.disableVertexAttribArray( attributes.uv2 );
2831 2832

				}
2833 2834

			}
2835

2836 2837 2838
			if ( material.skinning &&
				 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
				 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
A
alteredq 已提交
2839

2840 2841
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
2842

2843 2844
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
				_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
2845

2846 2847
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
				_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
2848

2849 2850
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
				_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
2851

A
alteredq 已提交
2852
			}
2853

2854
		}
2855

2856
		// render mesh
2857

2858
		if ( object instanceof THREE.Mesh ) {
2859

2860
			// wireframe
2861

2862
			if ( material.wireframe ) {
2863

2864
				setLineWidth( material.wireframeLinewidth );
2865

2866 2867
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
2868

2869
			// triangles
2870

2871
			} else {
2872

2873 2874
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
2875

2876
			}
2877

2878 2879 2880
			_this.info.render.calls ++;
			_this.info.render.vertices += geometryGroup.__webglFaceCount;
			_this.info.render.faces += geometryGroup.__webglFaceCount / 3;
2881

2882
		// render lines
2883

2884
		} else if ( object instanceof THREE.Line ) {
2885

2886
			primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
2887

2888
			setLineWidth( material.linewidth );
2889

2890
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
2891

2892
			_this.info.render.calls ++;
2893

2894
		// render particles
2895

2896
		} else if ( object instanceof THREE.ParticleSystem ) {
2897

2898
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
2899

2900
			_this.info.render.calls ++;
2901

2902
		// render ribbon
2903

2904
		} else if ( object instanceof THREE.Ribbon ) {
2905

2906
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
2907

2908
			_this.info.render.calls ++;
2909

2910
		}
2911

2912
	};
2913

2914
	function setupMorphTargets ( material, geometryGroup, object ) {
2915

2916
		// set base
2917

2918
		var attributes = material.program.attributes;
2919

2920
		if ( object.morphTargetBase !== - 1 ) {
2921

2922 2923
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
2924

2925
		} else if ( attributes.position >= 0 ) {
2926

2927 2928
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
2929

2930
		}
2931

2932
		if ( object.morphTargetForcedOrder.length ) {
2933

2934
			// set forced order
2935

2936 2937 2938 2939 2940
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;

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

2942 2943 2944 2945 2946 2947
				_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 ++;
2948 2949
			}

2950 2951 2952 2953 2954 2955 2956 2957 2958 2959
		} else {

			// find most influencing

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

2961
			if ( object.morphTargetBase !== - 1 ) {
2962

2963
				used[ object.morphTargetBase ] = true;
2964

2965
			}
2966

2967
			while ( m < material.numSupportedMorphTargets ) {
2968

2969
				for ( i = 0; i < il; i ++ ) {
2970

2971
					if ( !used[ i ] && influences[ i ] > candidateInfluence ) {
2972

2973 2974
						candidate = i;
						candidateInfluence = influences[ candidate ];
2975

2976
					}
2977

2978
				}
2979

2980 2981
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
2982

2983
				object.__webglMorphTargetInfluences[ m ] = candidateInfluence;
2984

2985 2986 2987
				used[ candidate ] = 1;
				candidateInfluence = -1;
				m ++;
2988 2989 2990 2991 2992

			}

		}

2993
		// load updated influences uniform
2994

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

2997
			_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
2998

2999
		}
3000

3001
	}
3002

3003
	// Frustum
M
Mr.doob 已提交
3004

3005
	function computeFrustum ( m ) {
M
Mr.doob 已提交
3006

3007 3008 3009 3010 3011 3012
		_frustum[ 0 ].set( m.n41 - m.n11, m.n42 - m.n12, m.n43 - m.n13, m.n44 - m.n14 );
		_frustum[ 1 ].set( m.n41 + m.n11, m.n42 + m.n12, m.n43 + m.n13, m.n44 + m.n14 );
		_frustum[ 2 ].set( m.n41 + m.n21, m.n42 + m.n22, m.n43 + m.n23, m.n44 + m.n24 );
		_frustum[ 3 ].set( m.n41 - m.n21, m.n42 - m.n22, m.n43 - m.n23, m.n44 - m.n24 );
		_frustum[ 4 ].set( m.n41 - m.n31, m.n42 - m.n32, m.n43 - m.n33, m.n44 - m.n34 );
		_frustum[ 5 ].set( m.n41 + m.n31, m.n42 + m.n32, m.n43 + m.n33, m.n44 + m.n34 );
3013

3014
		var i, plane;
3015

3016
		for ( i = 0; i < 6; i ++ ) {
3017

3018 3019
			plane = _frustum[ i ];
			plane.divideScalar( Math.sqrt( plane.x * plane.x + plane.y * plane.y + plane.z * plane.z ) );
3020 3021 3022

		}

3023
	};
M
Mr.doob 已提交
3024

3025
	function isInFrustum ( object ) {
3026

3027 3028
		var distance, matrix = object.matrixWorld,
		radius = - object.geometry.boundingSphere.radius * Math.max( object.scale.x, Math.max( object.scale.y, object.scale.z ) );
3029

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

3032 3033
			distance = _frustum[ i ].x * matrix.n14 + _frustum[ i ].y * matrix.n24 + _frustum[ i ].z * matrix.n34 + _frustum[ i ].w;
			if ( distance <= radius ) return false;
3034

3035
		}
3036

3037
		return true;
3038

3039
	};
3040 3041


3042
	function painterSort ( a, b ) {
3043

3044
		return b.z - a.z;
3045

3046
	};
3047

3048
	// Rendering
3049

3050
	this.render = function ( scene, camera, renderTarget, forceClear ) {
3051

3052 3053 3054 3055 3056 3057 3058 3059
		var i, il,

		program, material,
		webglObject, object,
		renderList,

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

3061
		_currentMaterialId = -1;
3062

3063
		if ( this.autoUpdateObjects ) this.initWebGLObjects( scene );
3064

3065
		if ( this.shadowMapEnabled && this.shadowMapAutoUpdate ) renderShadowMap( scene, camera );
3066

3067 3068 3069
		_this.info.render.calls = 0;
		_this.info.render.vertices = 0;
		_this.info.render.faces = 0;
3070

3071
		if ( camera.parent === undefined ) {
3072

3073 3074
			console.warn( 'DEPRECATED: Camera hasn\'t been added to a Scene. Adding it...' );
			scene.add( camera );
3075

3076
		}
3077

3078
		if ( this.autoUpdateScene ) scene.updateMatrixWorld();
3079

3080 3081 3082
		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
		camera.matrixWorldInverse.flattenToArray( _viewMatrixArray );
		camera.projectionMatrix.flattenToArray( _projectionMatrixArray );
3083

3084 3085
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
		computeFrustum( _projScreenMatrix );
3086

3087
		setRenderTarget( renderTarget );
3088

3089
		if ( this.autoClear || forceClear ) {
3090

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

3093
		}
M
Mr.doob 已提交
3094

3095
		// set matrices for regular objects (frustum culled)
3096

3097
		renderList = scene.__webglObjects;
3098

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

3101
			webglObject = renderList[ i ];
3102
			object = webglObject.object;
3103

A
alteredq 已提交
3104 3105
			webglObject.render = false;

3106
			if ( object.visible ) {
3107

3108
				if ( ! ( object instanceof THREE.Mesh ) || ! ( object.frustumCulled ) || isInFrustum( object ) ) {
M
Mr.doob 已提交
3109

3110
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
3111

3112
					setupMatrices( object, camera, true );
3113

3114
					unrollBufferMaterial( webglObject );
3115

3116
					webglObject.render = true;
3117

3118
					if ( this.sortObjects ) {
3119

3120
						if ( object.renderDepth ) {
3121

3122
							webglObject.z = object.renderDepth;
M
Mr.doob 已提交
3123

3124
						} else {
M
Mr.doob 已提交
3125

3126 3127
							_vector3.copy( object.position );
							_projScreenMatrix.multiplyVector3( _vector3 );
3128

3129
							webglObject.z = _vector3.z;
3130

3131
						}
M
Mr.doob 已提交
3132

3133
					}
M
Mr.doob 已提交
3134

3135
				}
3136 3137

			}
3138 3139 3140

		}

3141
		if ( this.sortObjects ) {
M
Mr.doob 已提交
3142

3143
			renderList.sort( painterSort );
3144

3145
		}
3146

3147
		// set matrices for immediate objects
3148

3149
		renderList = scene.__webglObjectsImmediate;
3150

3151 3152 3153
		for ( i = 0, il = renderList.length; i < il; i ++ ) {

			webglObject = renderList[ i ];
3154
			object = webglObject.object;
3155

3156
			if ( object.visible ) {
3157

3158
				if( object.matrixAutoUpdate ) {
3159

3160
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3161

3162
				}
M
Mr.doob 已提交
3163

3164
				setupMatrices( object, camera, true );
M
Mr.doob 已提交
3165

3166
				unrollImmediateBufferMaterial( webglObject );
M
Mr.doob 已提交
3167

3168
			}
M
Mr.doob 已提交
3169

3170
		}
3171

3172
		if ( scene.overrideMaterial ) {
3173

3174
			setBlending( scene.overrideMaterial.blending );
3175 3176 3177
			setDepthTest( scene.overrideMaterial.depthTest );
			setDepthWrite( scene.overrideMaterial.depthWrite );
			setPolygonOffset( scene.overrideMaterial.polygonOffset, scene.overrideMaterial.polygonOffsetFactor, scene.overrideMaterial.polygonOffsetUnits );
3178

3179 3180
			renderObjects( scene.__webglObjects, false, "", camera, lights, fog, true, scene.overrideMaterial );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "", camera, lights, fog, false, scene.overrideMaterial );
M
Mr.doob 已提交
3181

3182
		} else {
3183

3184
			// opaque pass (front-to-back order)
3185

3186
			setBlending( THREE.NormalBlending );
3187

3188 3189
			renderObjects( scene.__webglObjects, true, "opaque", camera, lights, fog, false );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "opaque", camera, lights, fog, false );
3190

3191
			// transparent pass (back-to-front order)
3192

3193 3194
			renderObjects( scene.__webglObjects, false, "transparent", camera, lights, fog, true );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "transparent", camera, lights, fog, true );
3195

3196
		}
3197

3198
		// render 2d
M
Mr.doob 已提交
3199

3200
		if ( scene.__webglSprites.length ) {
M
Mr.doob 已提交
3201

3202
			renderSprites( scene, camera );
M
Mr.doob 已提交
3203

3204
		}
3205

3206
		// Generate mipmap if we're using any kind of mipmap filtering
3207

3208
		if ( renderTarget && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {
3209

3210
			updateRenderTargetMipmap( renderTarget );
3211

3212
		}
3213

3214
		//_gl.finish();
3215

3216
	};
3217

3218
	function renderShadowMap ( scene, camera ) {
3219

A
alteredq 已提交
3220 3221 3222 3223 3224 3225 3226 3227 3228 3229
		var i, il, j, jl,

		shadowMap, shadowMatrix,
		program, buffer, material,
		webglObject, object, light,

		shadowIndex = 0,

		lights = scene.lights,
		fog = null;
3230

3231
		if ( ! _cameraLight ) {
3232

3233
			_cameraLight = new THREE.PerspectiveCamera( _this.shadowCameraFov, _this.shadowMapWidth / _this.shadowMapHeight, _this.shadowCameraNear, _this.shadowCameraFar );
3234

3235
		}
3236

3237
		for ( i = 0, il = lights.length; i < il; i ++ ) {
3238

3239
			light = lights[ i ];
M
Mr.doob 已提交
3240

A
alteredq 已提交
3241
			if ( light.castShadow && light instanceof THREE.SpotLight ) {
M
Mr.doob 已提交
3242

3243
				_currentMaterialId = -1;
3244

A
alteredq 已提交
3245
				if ( ! _this.shadowMap[ shadowIndex ] ) {
3246

3247 3248
					var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };

A
alteredq 已提交
3249 3250
					_this.shadowMap[ shadowIndex ] = new THREE.WebGLRenderTarget( _this.shadowMapWidth, _this.shadowMapHeight, pars );
					_shadowMatrix[ shadowIndex ] = new THREE.Matrix4();
M
Mr.doob 已提交
3251

M
Mr.doob 已提交
3252
				}
M
Mr.doob 已提交
3253

A
alteredq 已提交
3254 3255
				shadowMap = _this.shadowMap[ shadowIndex ];
				shadowMatrix = _shadowMatrix[ shadowIndex ];
3256

3257 3258
				_cameraLight.position.copy( light.position );
				_cameraLight.lookAt( light.target.position );
3259

3260
				if ( _cameraLight.parent == null ) {
3261

3262 3263
					console.warn( "Camera is not on the Scene. Adding it..." );
					scene.add( _cameraLight );
M
Mr.doob 已提交
3264

M
Mr.doob 已提交
3265 3266
				}

3267
				if ( this.autoUpdateScene ) scene.updateMatrixWorld();
M
Mr.doob 已提交
3268

3269
				_cameraLight.matrixWorldInverse.getInverse( _cameraLight.matrixWorld );
M
Mr.doob 已提交
3270

3271
				// compute shadow matrix
M
Mr.doob 已提交
3272

3273 3274 3275 3276
				shadowMatrix.set( 0.5, 0.0, 0.0, 0.5,
								  0.0, 0.5, 0.0, 0.5,
								  0.0, 0.0, 0.5, 0.5,
								  0.0, 0.0, 0.0, 1.0 );
3277

3278 3279
				shadowMatrix.multiplySelf( _cameraLight.projectionMatrix );
				shadowMatrix.multiplySelf( _cameraLight.matrixWorldInverse );
3280

3281
				// render shadow map
M
Mr.doob 已提交
3282

3283 3284
				_cameraLight.matrixWorldInverse.flattenToArray( _viewMatrixArray );
				_cameraLight.projectionMatrix.flattenToArray( _projectionMatrixArray );
M
Mr.doob 已提交
3285

3286 3287
				_projScreenMatrix.multiply( _cameraLight.projectionMatrix, _cameraLight.matrixWorldInverse );
				computeFrustum( _projScreenMatrix );
M
Mr.doob 已提交
3288

3289
				setRenderTarget( shadowMap );
3290

3291 3292
				// using arbitrary clear color in depth pass
				// creates variance in shadows
3293

3294 3295
				_gl.clearColor( 1, 1, 1, 1 );
				//_gl.clearColor( 0, 0, 0, 1 );
3296

3297
				_this.clear();
3298

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

3301
				// set matrices & frustum culling
3302

A
alteredq 已提交
3303
				jl = scene.__webglObjects.length;
A
alteredq 已提交
3304

A
alteredq 已提交
3305
				for ( j = 0; j < jl; j ++ ) {
3306

A
alteredq 已提交
3307
					webglObject = scene.__webglObjects[ j ];
3308
					object = webglObject.object;
M
Mr.doob 已提交
3309

A
alteredq 已提交
3310 3311
					webglObject.render = false;

3312
					if ( object.visible && object.castShadow ) {
M
Mr.doob 已提交
3313

3314
						if ( ! ( object instanceof THREE.Mesh ) || ! ( object.frustumCulled ) || isInFrustum( object ) ) {
M
Mr.doob 已提交
3315

3316
							object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3317

3318
							setupMatrices( object, _cameraLight, false );
M
Mr.doob 已提交
3319

3320
							webglObject.render = true;
M
Mr.doob 已提交
3321

3322
						}
M
Mr.doob 已提交
3323

3324
					}
3325

3326
				}
3327

A
alteredq 已提交
3328 3329
				// render regular objects

3330 3331
				setDepthTest( true );
				setBlending( THREE.NormalBlending ); // maybe blending should be just disabled?
3332

3333
				//_gl.cullFace( _gl.FRONT );
3334

A
alteredq 已提交
3335
				for ( j = 0; j < jl; j ++ ) {
3336

A
alteredq 已提交
3337
					webglObject = scene.__webglObjects[ j ];
3338

3339
					if ( webglObject.render ) {
3340

3341 3342
						object = webglObject.object;
						buffer = webglObject.buffer;
M
Mr.doob 已提交
3343

3344
						setObjectFaces( object );
M
Mr.doob 已提交
3345

3346
						if ( object.customDepthMaterial ) {
M
Mr.doob 已提交
3347

3348
							material = object.customDepthMaterial;
M
Mr.doob 已提交
3349

3350
						} else if ( object.geometry.morphTargets.length ) {
M
Mr.doob 已提交
3351

3352
							material = _depthMaterialMorph;
M
Mr.doob 已提交
3353

3354
						} else {
M
Mr.doob 已提交
3355

3356
							material = _depthMaterial;
M
Mr.doob 已提交
3357

3358
						}
M
Mr.doob 已提交
3359

3360
						renderBuffer( _cameraLight, lights, fog, material, buffer, object );
3361

3362
					}
3363

3364
				}
A
alteredq 已提交
3365

A
alteredq 已提交
3366 3367 3368
				// set matrices and render immediate objects

				jl = scene.__webglObjectsImmediate.length;
A
alteredq 已提交
3369

A
alteredq 已提交
3370 3371 3372
				for ( j = 0; j < jl; j ++ ) {

					webglObject = scene.__webglObjectsImmediate[ j ];
3373
					object = webglObject.object;
A
alteredq 已提交
3374

3375
					if ( object.visible && object.castShadow ) {
M
Mr.doob 已提交
3376

3377
						if( object.matrixAutoUpdate ) {
3378

3379
							object.matrixWorld.flattenToArray( object._objectMatrixArray );
3380

3381
						}
3382

3383
						_currentGeometryGroupHash = -1;
3384

3385
						setupMatrices( object, _cameraLight, false );
3386

3387
						setObjectFaces( object );
3388

3389
						program = setProgram( _cameraLight, lights, fog, _depthMaterial, object );
3390

3391
						if ( object.immediateRenderCallback ) {
M
Mr.doob 已提交
3392

3393
							object.immediateRenderCallback( program, _gl, _frustum );
M
Mr.doob 已提交
3394

3395
						} else {
3396

3397
							object.render( function( object ) { renderBufferImmediate( object, program, _depthMaterial.shading ); } );
3398

3399
						}
3400

3401
					}
3402

M
Mr.doob 已提交
3403
				}
M
Mr.doob 已提交
3404

3405
				//_gl.cullFace( _gl.BACK );
3406

A
alteredq 已提交
3407
				shadowIndex ++;
3408

3409
			}
3410

3411
		}
3412

3413
	};
3414

3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519
	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;

					if ( useBlending ) setBlending( material.blending );

					setDepthTest( material.depthTest );
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

				setObjectFaces( object );

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

			}

		}

	};

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

				_currentGeometryGroupHash = -1;

				if ( overrideMaterial ) {

					material = overrideMaterial;

				} else {

					material = webglObject[ materialType ];

					if ( ! material ) continue;

					if ( useBlending ) setBlending( material.blending );

					setDepthTest( material.depthTest );
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

				setObjectFaces( object );

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

				if ( object.immediateRenderCallback ) {

					object.immediateRenderCallback( program, _gl, _frustum );

				} else {

					object.render( function( object ) { renderBufferImmediate( object, program, material.shading ); } );

				}

			}

		}

	};

3520
	function unrollImmediateBufferMaterial ( globject ) {
3521

3522 3523
		var object = globject.object,
			material = object.material;
3524

3525
		if ( material.transparent ) {
3526

3527 3528
			globject.transparent = material;
			globject.opaque = null;
3529

3530
		} else {
3531

3532 3533
			globject.opaque = material;
			globject.transparent = null;
3534

3535
		}
A
alteredq 已提交
3536

3537
	};
A
alteredq 已提交
3538

3539
	function unrollBufferMaterial ( globject ) {
A
alteredq 已提交
3540

3541 3542 3543
		var object = globject.object,
			buffer = globject.buffer,
			material, materialIndex, meshMaterial;
3544

3545
		meshMaterial = object.material;
3546

3547
		if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
M
Mr.doob 已提交
3548

3549
			materialIndex = buffer.materialIndex;
3550

3551
			if ( materialIndex >= 0 ) {
3552

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

3555
				if ( material.transparent ) {
M
Mr.doob 已提交
3556

3557 3558
					globject.transparent = material;
					globject.opaque = null;
3559

3560
				} else {
3561

3562 3563
					globject.opaque = material;
					globject.transparent = null;
3564

3565
				}
3566

3567
			}
3568

3569
		} else {
3570

3571
			material = meshMaterial;
3572

3573
			if ( material ) {
3574

3575
				if ( material.transparent ) {
M
Mr.doob 已提交
3576

3577 3578
					globject.transparent = material;
					globject.opaque = null;
A
alteredq 已提交
3579

3580
				} else {
3581

3582 3583
					globject.opaque = material;
					globject.transparent = null;
3584

3585
				}
3586

3587
			}
3588

3589
		}
3590

3591
	};
3592

3593
	function renderSprites ( scene, camera ) {
3594

3595 3596 3597 3598 3599 3600 3601 3602 3603
		var o, ol, object;
		var attributes = _sprite.attributes;
		var uniforms = _sprite.uniforms;
		var invAspect = _viewportHeight / _viewportWidth;
		var size, scale = [];
		var screenPosition;
		var halfViewportWidth = _viewportWidth * 0.5;
		var halfViewportHeight = _viewportHeight * 0.5;
		var mergeWith3D = true;
3604

3605
		// setup gl
3606

3607 3608 3609 3610 3611
		_gl.useProgram( _sprite.program );
		_currentProgram = _sprite.program;
		_oldBlending = -1;
		_oldDepthTest = -1;
		_currentGeometryGroupHash = -1;
3612

3613
		if ( !_spriteAttributesEnabled ) {
3614

3615 3616
			_gl.enableVertexAttribArray( _sprite.attributes.position );
			_gl.enableVertexAttribArray( _sprite.attributes.uv );
3617

3618
			_spriteAttributesEnabled = true;
3619

3620
		}
3621

3622 3623 3624
		_gl.disable( _gl.CULL_FACE );
		_gl.enable( _gl.BLEND );
		_gl.depthMask( true );
3625

3626 3627 3628
		_gl.bindBuffer( _gl.ARRAY_BUFFER, _sprite.vertexBuffer );
		_gl.vertexAttribPointer( attributes.position, 2, _gl.FLOAT, false, 2 * 8, 0 );
		_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 2 * 8, 8 );
3629

3630
		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _sprite.elementBuffer );
3631

3632
		_gl.uniformMatrix4fv( uniforms.projectionMatrix, false, _projectionMatrixArray );
3633

3634 3635
		_gl.activeTexture( _gl.TEXTURE0 );
		_gl.uniform1i( uniforms.map, 0 );
3636

3637
		// update positions and sort
3638

3639
		for( o = 0, ol = scene.__webglSprites.length; o < ol; o ++ ) {
M
Mikael Emtinger 已提交
3640

3641
			object = scene.__webglSprites[ o ];
3642

3643
			if ( !object.visible || object.opacity === 0 ) continue;
3644

3645
			if( !object.useScreenCoordinates ) {
3646

3647 3648
				object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
				object.z = -object._modelViewMatrix.n34;
M
Mikael Emtinger 已提交
3649

3650 3651 3652
			} else {

				object.z = -object.position.z;
3653 3654

			}
3655

3656
		}
3657

3658
		scene.__webglSprites.sort( painterSort );
3659

3660
		// render all sprites
3661

3662
		for ( o = 0, ol = scene.__webglSprites.length; o < ol; o ++ ) {
3663

3664
			object = scene.__webglSprites[ o ];
3665

3666
			if ( !object.visible || object.opacity === 0 ) continue;
3667

3668
			if ( object.map && object.map.image && object.map.image.width ) {
3669

3670
				if ( object.useScreenCoordinates ) {
3671

3672 3673 3674 3675
					_gl.uniform1i( uniforms.useScreenCoordinates, 1 );
					_gl.uniform3f( uniforms.screenPosition, ( object.position.x - halfViewportWidth  ) / halfViewportWidth,
															( halfViewportHeight - object.position.y ) / halfViewportHeight,
															  Math.max( 0, Math.min( 1, object.position.z )));
3676

3677
				} else {
3678

3679 3680 3681
					_gl.uniform1i( uniforms.useScreenCoordinates, 0 );
					_gl.uniform1i( uniforms.affectedByDistance, object.affectedByDistance ? 1 : 0 );
					_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
3682

M
Mikael Emtinger 已提交
3683
				}
3684

3685
				size = object.map.image.width / ( object.scaleByViewport ? _viewportHeight : 1 );
3686

3687 3688
				scale[ 0 ] = size * invAspect * object.scale.x;
				scale[ 1 ] = size * object.scale.y;
3689

3690 3691 3692
				_gl.uniform2f( uniforms.uvScale, object.uvScale.x, object.uvScale.y );
				_gl.uniform2f( uniforms.uvOffset, object.uvOffset.x, object.uvOffset.y );
				_gl.uniform2f( uniforms.alignment, object.alignment.x, object.alignment.y );
M
Mikael Emtinger 已提交
3693

3694 3695
				_gl.uniform1f( uniforms.opacity, object.opacity );
				_gl.uniform3f( uniforms.color, object.color.r, object.color.g, object.color.b );
3696

3697 3698
				_gl.uniform1f( uniforms.rotation, object.rotation );
				_gl.uniform2fv( uniforms.scale, scale );
M
Mr.doob 已提交
3699

3700
				if ( object.mergeWith3D && !mergeWith3D ) {
M
Mr.doob 已提交
3701

3702 3703
					_gl.enable( _gl.DEPTH_TEST );
					mergeWith3D = true;
3704

3705
				} else if ( !object.mergeWith3D && mergeWith3D ) {
M
Mikael Emtinger 已提交
3706

3707 3708
					_gl.disable( _gl.DEPTH_TEST );
					mergeWith3D = false;
M
Mikael Emtinger 已提交
3709

3710
				}
3711

3712 3713
				setBlending( object.blending );
				setTexture( object.map, 0 );
3714

3715
				_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
3716

3717
			}
3718

A
alteredq 已提交
3719
		}
3720 3721


3722
		// restore gl
3723

3724 3725 3726
		_gl.enable( _gl.CULL_FACE );
		_gl.enable( _gl.DEPTH_TEST );
		_gl.depthMask( _oldDepthWrite );
3727

3728
	}
3729

3730
	// Geometry splitting
3731

3732
	function sortFacesByMaterial ( geometry ) {
3733

3734 3735 3736
		var f, fl, face, materialIndex, vertices,
			materialHash, groupHash,
			hash_map = {};
3737

3738
		var numMorphTargets = geometry.morphTargets.length;
3739

3740
		geometry.geometryGroups = {};
3741

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

3744 3745
			face = geometry.faces[ f ];
			materialIndex = face.materialIndex;
3746

3747
			materialHash = ( materialIndex !== undefined ) ? materialIndex : -1;
3748

3749
			if ( hash_map[ materialHash ] === undefined ) {
3750

3751
				hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 };
3752 3753 3754

			}

3755
			groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
3756

3757
			if ( geometry.geometryGroups[ groupHash ] === undefined ) {
3758

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

3761
			}
A
alteredq 已提交
3762

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

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

3767 3768
				hash_map[ materialHash ].counter += 1;
				groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
A
alteredq 已提交
3769

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

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

3774
				}
3775

3776
			}
3777

3778
			if ( face instanceof THREE.Face3 ) {
3779

3780
				geometry.geometryGroups[ groupHash ].faces3.push( f );
3781

3782
			} else {
3783

3784
				geometry.geometryGroups[ groupHash ].faces4.push( f );
3785

A
alteredq 已提交
3786
			}
3787

3788
			geometry.geometryGroups[ groupHash ].vertices += vertices;
3789

3790
		}
3791

3792
		geometry.geometryGroupsList = [];
3793

3794
		for ( var g in geometry.geometryGroups ) {
3795

3796
			geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;
3797

3798
			geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );
3799

3800
		}
3801

3802
	};
3803

3804 3805 3806 3807 3808 3809 3810 3811 3812
	// Objects refresh

	this.initWebGLObjects = function ( scene ) {

		if ( !scene.__webglObjects ) {

			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
			scene.__webglSprites = [];
3813 3814

		}
3815

3816
		while ( scene.__objectsAdded.length ) {
3817

3818 3819
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
3820

3821
		}
A
alteredq 已提交
3822

3823
		while ( scene.__objectsRemoved.length ) {
3824

3825 3826
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
3827

3828
		}
3829

3830
		// update must be called after objects adding / removal
3831

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

3834
			updateObject( scene.__webglObjects[ o ].object );
M
Mr.doob 已提交
3835 3836 3837 3838 3839

		}

	};

3840
	// Objects adding
M
Mr.doob 已提交
3841

3842
	function addObject ( object, scene ) {
A
alteredq 已提交
3843

3844
		var g, geometry, geometryGroup;
3845

3846
		if ( ! object.__webglInit ) {
M
Mr.doob 已提交
3847

3848
			object.__webglInit = true;
M
Mr.doob 已提交
3849

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

3852 3853 3854
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
M
Mr.doob 已提交
3855

3856
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3857

3858
			if ( object instanceof THREE.Mesh ) {
M
Mr.doob 已提交
3859

3860
				geometry = object.geometry;
M
Mr.doob 已提交
3861

3862
				if ( geometry.geometryGroups === undefined ) {
M
Mr.doob 已提交
3863

3864
					sortFacesByMaterial( geometry );
M
Mr.doob 已提交
3865

3866
				}
M
Mr.doob 已提交
3867

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

3870
				for ( g in geometry.geometryGroups ) {
M
Mr.doob 已提交
3871

3872
					geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
3873

3874
					// initialise VBO on the first access
M
Mr.doob 已提交
3875

3876
					if ( ! geometryGroup.__webglVertexBuffer ) {
3877

3878 3879
						createMeshBuffers( geometryGroup );
						initMeshBuffers( geometryGroup, object );
M
Mr.doob 已提交
3880

3881 3882 3883 3884 3885 3886 3887
						geometry.__dirtyVertices = true;
						geometry.__dirtyMorphTargets = true;
						geometry.__dirtyElements = true;
						geometry.__dirtyUvs = true;
						geometry.__dirtyNormals = true;
						geometry.__dirtyTangents = true;
						geometry.__dirtyColors = true;
M
Mr.doob 已提交
3888

3889
					}
M
Mr.doob 已提交
3890

3891
				}
M
Mr.doob 已提交
3892

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

3895
				geometry = object.geometry;
M
Mr.doob 已提交
3896

3897
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
3898

3899 3900
					createRibbonBuffers( geometry );
					initRibbonBuffers( geometry );
M
Mr.doob 已提交
3901

3902 3903
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
3904

3905
				}
M
Mr.doob 已提交
3906

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

3909
				geometry = object.geometry;
M
Mr.doob 已提交
3910

3911
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
3912

3913 3914
					createLineBuffers( geometry );
					initLineBuffers( geometry, object );
M
Mr.doob 已提交
3915

3916 3917
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
3918

3919
				}
3920

3921
			} else if ( object instanceof THREE.ParticleSystem ) {
3922

3923
				geometry = object.geometry;
3924

3925
				if ( ! geometry.__webglVertexBuffer ) {
3926

3927 3928
					createParticleBuffers( geometry );
					initParticleBuffers( geometry, object );
3929

3930 3931
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
3932

3933
				}
3934

3935
			}
3936

3937
		}
3938

3939
		if ( ! object.__webglActive ) {
3940

3941
			if ( object instanceof THREE.Mesh ) {
3942

3943
				geometry = object.geometry;
3944

3945
				for ( g in geometry.geometryGroups ) {
3946

3947
					geometryGroup = geometry.geometryGroups[ g ];
3948

3949
					addBuffer( scene.__webglObjects, geometryGroup, object );
3950

3951
				}
3952

3953 3954 3955
			} else if ( object instanceof THREE.Ribbon ||
						object instanceof THREE.Line ||
						object instanceof THREE.ParticleSystem ) {
3956

3957 3958
				geometry = object.geometry;
				addBuffer( scene.__webglObjects, geometry, object );
3959

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

3962
				addBufferImmediate( scene.__webglObjectsImmediate, object );
3963

3964
			} else if ( object instanceof THREE.Sprite ) {
3965

3966
				scene.__webglSprites.push( object );
3967

3968 3969
			}

3970
			object.__webglActive = true;
3971

3972
		}
3973

3974
	};
3975

3976
	function addBuffer ( objlist, buffer, object ) {
3977

3978 3979 3980 3981 3982 3983 3984 3985
		objlist.push(
			{
				buffer: buffer,
				object: object,
				opaque: null,
				transparent: null
			}
		);
3986

3987
	};
3988

3989
	function addBufferImmediate ( objlist, object ) {
3990

3991 3992 3993 3994 3995
		objlist.push(
			{
				object: object,
				opaque: null,
				transparent: null
3996
			}
3997
		);
3998

3999
	};
4000

4001
	// Objects updates
4002

4003
	function updateObject ( object ) {
4004

4005 4006
		var geometry = object.geometry,
			geometryGroup, customAttributesDirty, material;
4007

4008
		if ( object instanceof THREE.Mesh ) {
4009

4010
			// check all geometry groups
4011

4012
			for( var i = 0, il = geometry.geometryGroupsList.length; i < il; i ++ ) {
4013

4014
				geometryGroup = geometry.geometryGroupsList[ i ];
4015

4016
				material = getBufferMaterial( object, geometryGroup );
4017

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

4020 4021 4022
				if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
					 geometry.__dirtyUvs || geometry.__dirtyNormals ||
					 geometry.__dirtyColors || geometry.__dirtyTangents || customAttributesDirty ) {
4023

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

4026
				}
M
Mr.doob 已提交
4027

4028
			}
4029

4030 4031 4032 4033 4034 4035 4036
			geometry.__dirtyVertices = false;
			geometry.__dirtyMorphTargets = false;
			geometry.__dirtyElements = false;
			geometry.__dirtyUvs = false;
			geometry.__dirtyNormals = false;
			geometry.__dirtyColors = false;
			geometry.__dirtyTangents = false;
4037

4038
			material.attributes && clearCustomAttributes( material );
4039

4040
		} else if ( object instanceof THREE.Ribbon ) {
4041

4042
			if ( geometry.__dirtyVertices || geometry.__dirtyColors ) {
4043

4044
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
4045

4046
			}
4047

4048 4049
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
4050

4051
		} else if ( object instanceof THREE.Line ) {
4052

4053
			material = getBufferMaterial( object, geometryGroup );
A
alteredq 已提交
4054

4055
			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
A
alteredq 已提交
4056

4057
			if ( geometry.__dirtyVertices ||  geometry.__dirtyColors || customAttributesDirty ) {
A
alteredq 已提交
4058

4059
				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
4060

4061
			}
4062

4063 4064
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
4065

4066
			material.attributes && clearCustomAttributes( material );
4067

4068
		} else if ( object instanceof THREE.ParticleSystem ) {
4069

4070
			material = getBufferMaterial( object, geometryGroup );
4071

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

4074
			if ( geometry.__dirtyVertices || geometry.__dirtyColors || object.sortParticles || customAttributesDirty ) {
4075

4076
				setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
4077

4078
			}
4079

4080 4081
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
4082

4083
			material.attributes && clearCustomAttributes( material );
4084

4085
		}
4086

4087
	};
4088

4089
	// Objects updates - custom attributes check
4090

4091
	function areCustomAttributesDirty ( material ) {
4092

4093
		for ( var a in material.attributes ) {
4094

4095
			if ( material.attributes[ a ].needsUpdate ) return true;
4096

4097
		}
4098

4099
		return false;
4100

4101
	};
4102

4103 4104 4105
	function clearCustomAttributes ( material ) {

		for ( var a in material.attributes ) {
4106

4107
			material.attributes[ a ].needsUpdate = false;
4108

4109
		}
4110

4111
	};
4112

4113
	// Objects removal
4114

4115
	function removeObject ( object, scene ) {
4116

4117 4118 4119 4120
		if ( object instanceof THREE.Mesh  ||
			 object instanceof THREE.ParticleSystem ||
			 object instanceof THREE.Ribbon ||
			 object instanceof THREE.Line ) {
4121

4122
			removeInstances( scene.__webglObjects, object );
4123

4124
		} else if ( object instanceof THREE.Sprite ) {
4125

4126
			removeInstancesDirect( scene.__webglSprites, object );
4127

4128
		} else if ( object instanceof THREE.MarchingCubes || object.immediateRenderCallback ) {
4129

4130
			removeInstances( scene.__webglObjectsImmediate, object );
4131

4132
		}
4133

4134
		object.__webglActive = false;
4135

4136
	};
4137

4138
	function removeInstances ( objlist, object ) {
4139

4140
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4141

4142
			if ( objlist[ o ].object === object ) {
4143

4144
				objlist.splice( o, 1 );
4145

4146
			}
4147

4148
		}
4149

4150
	};
4151

4152
	function removeInstancesDirect ( objlist, object ) {
4153

4154
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4155

4156
			if ( objlist[ o ] === object ) {
4157

4158
				objlist.splice( o, 1 );
4159

4160
			}
4161

4162
		}
4163

4164
	};
4165

4166
	// Materials
4167

4168
	this.initMaterial = function ( material, lights, fog, object ) {
4169

4170
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
4171

4172
		if ( material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
4173

4174
			shaderID = 'depth';
4175

4176
		} else if ( material instanceof THREE.MeshNormalMaterial ) {
4177

4178
			shaderID = 'normal';
M
Mr.doob 已提交
4179

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

4182
			shaderID = 'basic';
M
Mr.doob 已提交
4183

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

4186
			shaderID = 'lambert';
M
Mr.doob 已提交
4187

4188
		} else if ( material instanceof THREE.MeshPhongMaterial ) {
4189

4190
			shaderID = 'phong';
4191

4192
		} else if ( material instanceof THREE.LineBasicMaterial ) {
4193

4194
			shaderID = 'basic';
4195

4196
		} else if ( material instanceof THREE.ParticleBasicMaterial ) {
4197

4198
			shaderID = 'particle_basic';
4199 4200 4201

		}

4202
		if ( shaderID ) {
4203

4204
			setMaterialShaders( material, THREE.ShaderLib[ shaderID ] );
4205

4206
		}
4207

4208 4209
		// heuristics to create shader parameters according to lights in the scene
		// (not to blow over maxLights budget)
4210

4211
		maxLightCount = allocateLights( lights );
4212

4213
		maxShadows = allocateShadows( lights );
4214

4215
		maxBones = allocateBones( object );
4216

4217
		parameters = {
4218

4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235
			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,
			shadowMapWidth: this.shadowMapWidth,
			shadowMapHeight: this.shadowMapHeight,
			maxShadows: maxShadows,
			alphaTest: material.alphaTest,
			metal: material.metal,
			perPixel: material.perPixel
4236

4237
		};
M
Mr.doob 已提交
4238

4239
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
4240

4241
		var attributes = material.program.attributes;
4242

4243 4244 4245 4246
		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 );
4247

4248 4249 4250
		if ( material.skinning &&
			 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
M
Mr.doob 已提交
4251

4252 4253 4254 4255
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
M
Mr.doob 已提交
4256 4257

		}
4258

4259
		if ( material.attributes ) {
A
alteredq 已提交
4260

4261
			for ( a in material.attributes ) {
M
Mr.doob 已提交
4262

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

4265
			}
M
Mr.doob 已提交
4266

4267
		}
M
Mr.doob 已提交
4268

4269
		if ( material.morphTargets ) {
M
Mr.doob 已提交
4270

4271
			material.numSupportedMorphTargets = 0;
4272

4273
			var id, base = "morphTarget";
4274

4275
			for ( i = 0; i < this.maxMorphTargets; i ++ ) {
4276

4277
				id = base + i;
M
Mr.doob 已提交
4278

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

4281 4282
					_gl.enableVertexAttribArray( attributes[ id ] );
					material.numSupportedMorphTargets ++;
4283

4284
				}
4285

4286
			}
4287

4288
		}
4289

4290
		material.uniformsList = [];
4291

4292
		for ( u in material.uniforms ) {
4293

4294
			material.uniformsList.push( [ material.uniforms[ u ], u ] );
4295

4296
		}
M
Mr.doob 已提交
4297

4298
	};
M
Mr.doob 已提交
4299

4300
	function setMaterialShaders ( material, shaders ) {
M
Mr.doob 已提交
4301

4302 4303 4304
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
M
Mr.doob 已提交
4305

4306
	};
M
Mr.doob 已提交
4307

4308
	function setProgram ( camera, lights, fog, material, object ) {
4309

4310
		if ( ! material.program ) {
4311

4312
			_this.initMaterial( material, lights, fog, object );
4313

4314
		}
4315

4316
		if ( material.morphTargets ) {
4317

4318
			if ( ! object.__webglMorphTargetInfluences ) {
4319

4320
				object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );
4321

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

4324
					object.__webglMorphTargetInfluences[ i ] = 0;
4325

4326
				}
4327

4328
			}
4329

4330
		}
4331

4332
		var refreshMaterial = false;
4333

4334 4335 4336
		var program = material.program,
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
4337

4338
		if ( program !== _currentProgram ) {
4339

4340 4341
			_gl.useProgram( program );
			_currentProgram = program;
4342

4343
			refreshMaterial = true;
4344

4345
		}
4346

4347
		if ( material.id !== _currentMaterialId ) {
4348

4349 4350
			_currentMaterialId = material.id;
			refreshMaterial = true;
4351

4352
		}
4353

4354
		if ( refreshMaterial ) {
4355

4356
			_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );
A
alteredq 已提交
4357

4358
			// refresh uniforms common to several materials
4359

4360
			if ( fog && material.fog ) {
4361

4362
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
4363

4364
			}
M
Mr.doob 已提交
4365

4366 4367 4368
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material.lights ) {
4369

4370 4371
				setupLights( program, lights );
				refreshUniformsLights( m_uniforms, _lights );
4372

4373
			}
M
Mr.doob 已提交
4374

4375 4376 4377
			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
4378

4379
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
4380 4381 4382

			}

4383
			// refresh single material specific uniforms
M
Mr.doob 已提交
4384

4385
			if ( material instanceof THREE.LineBasicMaterial ) {
4386

4387
				refreshUniformsLine( m_uniforms, material );
M
Mr.doob 已提交
4388

4389
			} else if ( material instanceof THREE.ParticleBasicMaterial ) {
M
Mr.doob 已提交
4390

4391
				refreshUniformsParticle( m_uniforms, material );
M
Mr.doob 已提交
4392

4393
			} else if ( material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
4394

4395
				refreshUniformsPhong( m_uniforms, material );
M
Mr.doob 已提交
4396

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

4399
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
4400

4401
			} else if ( material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
4402

4403 4404 4405
				m_uniforms.mNear.value = camera.near;
				m_uniforms.mFar.value = camera.far;
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4406

4407
			} else if ( material instanceof THREE.MeshNormalMaterial ) {
M
Mr.doob 已提交
4408

4409
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4410

4411
			}
M
Mr.doob 已提交
4412

4413
			if ( object.receiveShadow && ! material._shadowPass ) {
M
Mr.doob 已提交
4414

4415
				refreshUniformsShadow( m_uniforms, material );
M
Mr.doob 已提交
4416

4417
			}
M
Mr.doob 已提交
4418

4419
			// load common uniforms
M
Mr.doob 已提交
4420

4421
			loadUniformsGeneric( program, material.uniformsList );
M
Mr.doob 已提交
4422

4423 4424
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)
4425

4426 4427 4428
			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
				 material.envMap ) {
4429

4430
				if( p_uniforms.cameraPosition !== null ) {
4431

4432
					_gl.uniform3f( p_uniforms.cameraPosition, camera.position.x, camera.position.y, camera.position.z );
4433

4434
				}
4435 4436 4437

			}

4438 4439 4440 4441
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {
4442

4443
				if( p_uniforms.viewMatrix !== null ) {
4444

4445
					_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
4446

4447
				}
4448

4449
			}
M
Mr.doob 已提交
4450

4451
			if ( material.skinning ) {
4452

4453
				loadUniformsSkinning( p_uniforms, object );
4454

4455
			}
4456

4457
		}
M
Mr.doob 已提交
4458

4459
		loadUniformsMatrices( p_uniforms, object );
M
Mr.doob 已提交
4460

4461 4462 4463 4464
		if ( material instanceof THREE.ShaderMaterial ||
			 material.envMap ||
			 material.skinning ||
			 object.receiveShadow ) {
M
Mr.doob 已提交
4465

4466
			if ( p_uniforms.objectMatrix !== null ) {
M
Mr.doob 已提交
4467

4468
				_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
M
Mr.doob 已提交
4469

4470
			}
4471

4472
		}
4473

4474
		return program;
4475

4476
	};
4477

4478
	// Uniforms (refresh uniforms objects)
A
alteredq 已提交
4479

4480
	function refreshUniformsCommon ( uniforms, material ) {
4481

4482
		uniforms.opacity.value = material.opacity;
4483

4484
		if ( _this.gammaInput ) {
4485

4486
			uniforms.diffuse.value.copyGammaToLinear( material.color );
4487

4488
		} else {
4489

4490
			uniforms.diffuse.value = material.color;
4491

4492
		}
4493

4494
		uniforms.map.texture = material.map;
4495

4496
		if ( material.map ) {
4497

4498
			uniforms.offsetRepeat.value.set( material.map.offset.x, material.map.offset.y, material.map.repeat.x, material.map.repeat.y );
M
Mr.doob 已提交
4499

4500
		}
M
Mr.doob 已提交
4501

4502
		uniforms.lightMap.texture = material.lightMap;
4503

4504 4505
		uniforms.envMap.texture = material.envMap;
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
4506

4507
		if ( _this.gammaInput ) {
4508

4509 4510
			//uniforms.reflectivity.value = material.reflectivity * material.reflectivity;
			uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
4511

4512
		} else {
4513

4514
			uniforms.reflectivity.value = material.reflectivity;
4515

4516
		}
4517

4518 4519 4520
		uniforms.refractionRatio.value = material.refractionRatio;
		uniforms.combine.value = material.combine;
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
M
Mr.doob 已提交
4521

4522
	};
M
Mr.doob 已提交
4523

4524
	function refreshUniformsLine ( uniforms, material ) {
M
Mr.doob 已提交
4525

4526 4527
		uniforms.diffuse.value = material.color;
		uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4528

4529
	};
M
Mr.doob 已提交
4530

4531
	function refreshUniformsParticle ( uniforms, material ) {
4532

4533 4534 4535 4536
		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.
4537

4538
		uniforms.map.texture = material.map;
4539

4540
	};
4541

4542
	function refreshUniformsFog ( uniforms, fog ) {
4543

4544
		uniforms.fogColor.value = fog.color;
4545

4546
		if ( fog instanceof THREE.Fog ) {
4547

4548 4549
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
4550

4551
		} else if ( fog instanceof THREE.FogExp2 ) {
M
Mikael Emtinger 已提交
4552

4553
			uniforms.fogDensity.value = fog.density;
M
Mikael Emtinger 已提交
4554

4555
		}
M
Mikael Emtinger 已提交
4556

4557
	};
M
Mikael Emtinger 已提交
4558

4559
	function refreshUniformsPhong ( uniforms, material ) {
M
Mikael Emtinger 已提交
4560

4561
		uniforms.shininess.value = material.shininess;
4562

4563
		if ( _this.gammaInput ) {
M
Mikael Emtinger 已提交
4564

4565 4566
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
			uniforms.specular.value.copyGammaToLinear( material.specular );
4567

4568
		} else {
4569

4570 4571
			uniforms.ambient.value = material.ambient;
			uniforms.specular.value = material.specular;
4572

4573
		}
4574

4575
	};
4576

4577
	function refreshUniformsLambert ( uniforms, material ) {
4578

4579
		if ( _this.gammaInput ) {
4580

4581
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
M
Mr.doob 已提交
4582

4583
		} else {
4584

4585
			uniforms.ambient.value = material.ambient;
4586

4587
		}
4588

4589
	};
4590

4591
	function refreshUniformsLights ( uniforms, lights ) {
4592

4593
		uniforms.ambientLightColor.value = lights.ambient;
4594

4595 4596
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
4597

4598 4599 4600
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
		uniforms.pointLightDistance.value = lights.point.distances;
4601

4602
	};
4603

4604
	function refreshUniformsShadow ( uniforms, material ) {
M
Mr.doob 已提交
4605

4606
		if ( uniforms.shadowMatrix ) {
4607

4608
			for ( var i = 0; i < _shadowMatrix.length; i ++ ) {
4609

4610 4611
				uniforms.shadowMatrix.value[ i ] = _shadowMatrix[ i ];
				uniforms.shadowMap.texture[ i ] = _this.shadowMap[ i ];
4612 4613


4614
			}
4615

4616 4617 4618
			uniforms.shadowDarkness.value = _this.shadowMapDarkness;
			uniforms.shadowBias.value = _this.shadowMapBias;

4619 4620
		}

4621
	};
4622

4623
	// Uniforms (load to GPU)
4624

4625
	function loadUniformsSkinning ( uniforms, object ) {
4626

4627 4628
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray );
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
4629

4630
	};
4631

4632

4633
	function loadUniformsMatrices ( uniforms, object ) {
4634

4635
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
4636

4637
		if ( uniforms.normalMatrix ) {
4638

4639
			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );
4640

4641
		}
4642

4643
	};
4644

4645
	function loadUniformsGeneric ( program, uniforms ) {
4646

4647
		var uniform, value, type, location, texture, i, il, j, jl, offset;
4648

4649
		for( j = 0, jl = uniforms.length; j < jl; j ++ ) {
4650

4651 4652
			location = program.uniforms[ uniforms[ j ][ 1 ] ];
			if ( !location ) continue;
4653

4654
			uniform = uniforms[ j ][ 0 ];
4655

4656 4657
			type = uniform.type;
			value = uniform.value;
4658

4659
			// single integer
4660

4661
			if( type === "i" ) {
4662

4663
				_gl.uniform1i( location, value );
4664

4665
			// single float
4666

4667
			} else if( type === "f" ) {
4668

4669
				_gl.uniform1f( location, value );
4670

4671
			// single THREE.Vector2
4672

4673
			} else if( type === "v2" ) {
4674

4675
				_gl.uniform2f( location, value.x, value.y );
4676

4677
			// single THREE.Vector3
4678

4679
			} else if( type === "v3" ) {
4680

4681
				_gl.uniform3f( location, value.x, value.y, value.z );
4682

4683
			// single THREE.Vector4
4684

4685
			} else if( type === "v4" ) {
4686

4687
				_gl.uniform4f( location, value.x, value.y, value.z, value.w );
4688

4689
			// single THREE.Color
4690

4691
			} else if( type === "c" ) {
4692

4693
				_gl.uniform3f( location, value.r, value.g, value.b );
4694

4695
			// flat array of floats (JS or typed array)
4696

4697
			} else if( type === "fv1" ) {
4698

4699
				_gl.uniform1fv( location, value );
4700

4701
			// flat array of floats with 3 x N size (JS or typed array)
4702

4703
			} else if( type === "fv" ) {
4704

4705
				_gl.uniform3fv( location, value );
4706

4707
			// array of THREE.Vector3
4708

4709
			} else if( type === "v3v" ) {
4710

4711
				if ( ! uniform._array ) {
4712

4713
					uniform._array = new Float32Array( 3 * value.length );
M
Mr.doob 已提交
4714

4715
				}
A
alteredq 已提交
4716

4717
				for ( i = 0, il = value.length; i < il; i ++ ) {
A
alteredq 已提交
4718

4719
					offset = i * 3;
4720

4721 4722 4723
					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;
					uniform._array[ offset + 2 ] = value[ i ].z;
4724

4725
				}
4726

4727
				_gl.uniform3fv( location, uniform._array );
4728

4729
			// single THREE.Matrix4
4730

4731
			} else if( type === "m4" ) {
M
Mr.doob 已提交
4732

4733
				if ( ! uniform._array ) {
A
alteredq 已提交
4734

4735
					uniform._array = new Float32Array( 16 );
4736

4737
				}
4738

4739 4740
				value.flattenToArray( uniform._array );
				_gl.uniformMatrix4fv( location, false, uniform._array );
4741

4742
			// array of THREE.Matrix4
4743

4744
			} else if( type === "m4v" ) {
A
alteredq 已提交
4745

4746 4747 4748
				if ( ! uniform._array ) {

					uniform._array = new Float32Array( 16 * value.length );
A
alteredq 已提交
4749

M
Mr.doob 已提交
4750
				}
M
Mr.doob 已提交
4751

4752
				for ( i = 0, il = value.length; i < il; i ++ ) {
M
Mr.doob 已提交
4753

4754
					value[ i ].flattenToArrayOffset( uniform._array, i * 16 );
M
Mr.doob 已提交
4755

4756
				}
A
alteredq 已提交
4757

4758
				_gl.uniformMatrix4fv( location, false, uniform._array );
M
Mr.doob 已提交
4759

4760

4761
			// single THREE.Texture (2d or cube)
M
Mr.doob 已提交
4762

4763
			} else if( type === "t" ) {
A
alteredq 已提交
4764

4765
				_gl.uniform1i( location, value );
4766

4767
				texture = uniform.texture;
A
alteredq 已提交
4768

4769
				if ( !texture ) continue;
A
alteredq 已提交
4770

4771
				if ( texture.image instanceof Array && texture.image.length === 6 ) {
A
alteredq 已提交
4772

4773
					setCubeTexture( texture, value );
A
alteredq 已提交
4774

4775
				} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
M
Mr.doob 已提交
4776

4777 4778 4779 4780 4781
					setCubeTextureDynamic( texture, value );

				} else {

					setTexture( texture, value );
4782

M
Mr.doob 已提交
4783
				}
M
Mr.doob 已提交
4784

4785
			// array of THREE.Texture (2d)
M
Mr.doob 已提交
4786

4787
			} else if( type === "tv" ) {
M
Mr.doob 已提交
4788

4789
				if ( ! uniform._array ) {
M
Mr.doob 已提交
4790

4791
					uniform._array = [];
A
alteredq 已提交
4792

4793 4794 4795 4796 4797
					for( i = 0, il = uniform.texture.length; i < il; i ++ ) {

						uniform._array[ i ] = value + i;

					}
A
alteredq 已提交
4798

M
Mr.doob 已提交
4799
				}
A
alteredq 已提交
4800

4801
				_gl.uniform1iv( location, uniform._array );
A
alteredq 已提交
4802

4803
				for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
4804

4805
					texture = uniform.texture[ i ];
4806

4807
					if ( !texture ) continue;
M
Mr.doob 已提交
4808

4809
					setTexture( texture, uniform._array[ i ] );
M
Mr.doob 已提交
4810

M
Mr.doob 已提交
4811
				}
M
Mr.doob 已提交
4812

M
Mr.doob 已提交
4813
			}
M
Mr.doob 已提交
4814

M
Mr.doob 已提交
4815
		}
M
Mr.doob 已提交
4816

4817
	};
M
Mr.doob 已提交
4818

4819
	function setupMatrices ( object, camera, computeNormalMatrix ) {
M
Mr.doob 已提交
4820

4821
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
M
Mr.doob 已提交
4822

4823
		if ( computeNormalMatrix ) {
M
Mr.doob 已提交
4824

4825
			THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
M
Mr.doob 已提交
4826

4827
		}
M
Mr.doob 已提交
4828

A
alteredq 已提交
4829
	};
M
Mr.doob 已提交
4830

4831
	function setupLights ( program, lights ) {
M
Mr.doob 已提交
4832

4833 4834 4835
		var l, ll, light, n,
		r = 0, g = 0, b = 0,
		color, position, intensity, distance,
M
Mr.doob 已提交
4836

4837
		zlights = _lights,
A
alteredq 已提交
4838

4839 4840
		dcolors = zlights.directional.colors,
		dpositions = zlights.directional.positions,
A
alteredq 已提交
4841

4842 4843 4844
		pcolors = zlights.point.colors,
		ppositions = zlights.point.positions,
		pdistances = zlights.point.distances,
4845

4846 4847
		dlength = 0,
		plength = 0,
4848

4849 4850
		doffset = 0,
		poffset = 0;
4851

4852
		for ( l = 0, ll = lights.length; l < ll; l ++ ) {
4853

4854 4855
			light = lights[ l ];
			color = light.color;
A
alteredq 已提交
4856

4857 4858 4859
			position = light.position;
			intensity = light.intensity;
			distance = light.distance;
A
alteredq 已提交
4860

4861
			if ( light instanceof THREE.AmbientLight ) {
4862

4863
				if ( _this.gammaInput ) {
4864

4865 4866 4867
					r += color.r * color.r;
					g += color.g * color.g;
					b += color.b * color.b;
4868

4869
				} else {
4870

4871 4872 4873
					r += color.r;
					g += color.g;
					b += color.b;
4874

4875
				}
4876

4877
			} else if ( light instanceof THREE.DirectionalLight ) {
4878

4879
				doffset = dlength * 3;
4880

4881
				if ( _this.gammaInput ) {
4882

4883 4884 4885
					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;
4886

4887
				} else {
4888

4889 4890 4891
					dcolors[ doffset ]     = color.r * intensity;
					dcolors[ doffset + 1 ] = color.g * intensity;
					dcolors[ doffset + 2 ] = color.b * intensity;
A
alteredq 已提交
4892

4893
				}
A
alteredq 已提交
4894

4895 4896 4897
				dpositions[ doffset ]     = position.x;
				dpositions[ doffset + 1 ] = position.y;
				dpositions[ doffset + 2 ] = position.z;
A
alteredq 已提交
4898

4899
				dlength += 1;
A
alteredq 已提交
4900

4901
			} else if ( light instanceof THREE.SpotLight ) { // hack, not a proper spotlight
A
alteredq 已提交
4902

4903
				doffset = dlength * 3;
A
alteredq 已提交
4904

4905
				if ( _this.gammaInput ) {
4906

4907 4908 4909
					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;
4910

4911
				} else {
A
alteredq 已提交
4912

4913 4914 4915
					dcolors[ doffset ]     = color.r * intensity;
					dcolors[ doffset + 1 ] = color.g * intensity;
					dcolors[ doffset + 2 ] = color.b * intensity;
A
alteredq 已提交
4916 4917 4918

				}

4919
				n = 1 / position.length();
A
alteredq 已提交
4920

4921 4922 4923
				dpositions[ doffset ]     = position.x * n;
				dpositions[ doffset + 1 ] = position.y * n;
				dpositions[ doffset + 2 ] = position.z * n;
M
Mr.doob 已提交
4924

4925
				dlength += 1;
4926

4927
			} else if( light instanceof THREE.PointLight ) {
M
Mr.doob 已提交
4928

4929
				poffset = plength * 3;
M
Mr.doob 已提交
4930

4931
				if ( _this.gammaInput ) {
4932

4933 4934 4935
					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 已提交
4936

4937
				} else {
A
alteredq 已提交
4938

4939 4940 4941
					pcolors[ poffset ]     = color.r * intensity;
					pcolors[ poffset + 1 ] = color.g * intensity;
					pcolors[ poffset + 2 ] = color.b * intensity;
A
alteredq 已提交
4942

4943
				}
A
alteredq 已提交
4944

4945 4946 4947
				ppositions[ poffset ]     = position.x;
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
A
alteredq 已提交
4948

4949
				pdistances[ plength ] = distance;
A
alteredq 已提交
4950

4951
				plength += 1;
4952

4953
			}
4954

4955
		}
A
alteredq 已提交
4956

4957 4958
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
A
alteredq 已提交
4959

4960 4961
		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 已提交
4962

4963 4964
		zlights.point.length = plength;
		zlights.directional.length = dlength;
A
alteredq 已提交
4965

4966 4967 4968
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
4969

4970
	};
M
Mr.doob 已提交
4971

4972
	// GL state setting
M
Mr.doob 已提交
4973

4974
	this.setFaceCulling = function ( cullFace, frontFace ) {
M
Mr.doob 已提交
4975

4976
		if ( cullFace ) {
M
Mr.doob 已提交
4977

4978
			if ( !frontFace || frontFace === "ccw" ) {
4979

4980
				_gl.frontFace( _gl.CCW );
4981

4982
			} else {
4983

4984
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
4985

4986
			}
M
Mr.doob 已提交
4987

4988
			if( cullFace === "back" ) {
4989

4990
				_gl.cullFace( _gl.BACK );
4991

4992
			} else if( cullFace === "front" ) {
4993

4994
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
4995

4996
			} else {
4997

4998
				_gl.cullFace( _gl.FRONT_AND_BACK );
4999

5000
			}
5001

5002
			_gl.enable( _gl.CULL_FACE );
5003

5004
		} else {
5005

5006
			_gl.disable( _gl.CULL_FACE );
5007 5008 5009 5010 5011

		}

	};

5012
	function setLineWidth ( width ) {
5013

5014
		if ( width !== _oldLineWidth ) {
5015

5016
			_gl.lineWidth( width );
5017

5018
			_oldLineWidth = width;
M
Mr.doob 已提交
5019

5020
		}
M
Mr.doob 已提交
5021

5022
	};
5023

5024
	function setObjectFaces ( object ) {
5025

5026
		if ( _oldDoubleSided !== object.doubleSided ) {
M
Mr.doob 已提交
5027

5028
			if( object.doubleSided ) {
M
Mr.doob 已提交
5029

5030
				_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
5031

5032
			} else {
5033

5034
				_gl.enable( _gl.CULL_FACE );
5035

5036
			}
5037

5038
			_oldDoubleSided = object.doubleSided;
5039

5040
		}
5041

5042
		if ( _oldFlipSided !== object.flipSided ) {
5043

5044
			if( object.flipSided ) {
5045

5046
				_gl.frontFace( _gl.CW );
5047

5048
			} else {
5049

5050
				_gl.frontFace( _gl.CCW );
5051

5052
			}
5053

5054
			_oldFlipSided = object.flipSided;
5055

5056
		}
5057

5058
	};
5059

5060
	function setDepthTest ( depthTest ) {
5061

5062
		if ( _oldDepthTest !== depthTest ) {
5063

5064
			if( depthTest ) {
5065

5066
				_gl.enable( _gl.DEPTH_TEST );
5067

5068
			} else {
5069

5070
				_gl.disable( _gl.DEPTH_TEST );
5071 5072 5073

			}

5074
			_oldDepthTest = depthTest;
5075

5076
		}
5077

5078
	};
5079

5080
	function setDepthWrite ( depthWrite ) {
5081

5082
		if ( _oldDepthWrite !== depthWrite ) {
5083

5084 5085
			_gl.depthMask( depthWrite );
			_oldDepthWrite = depthWrite;
5086 5087 5088

		}

5089
	};
5090

5091
	function setPolygonOffset ( polygonoffset, factor, units ) {
5092

5093
		if ( _oldPolygonOffset !== polygonoffset ) {
M
Mr.doob 已提交
5094

5095
			if ( polygonoffset ) {
5096

5097
				_gl.enable( _gl.POLYGON_OFFSET_FILL );
5098

5099
			} else {
5100

5101
				_gl.disable( _gl.POLYGON_OFFSET_FILL );
5102

5103
			}
5104

5105
			_oldPolygonOffset = polygonoffset;
5106

5107
		}
5108

5109
		if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
5110

5111
			_gl.polygonOffset( factor, units );
M
Mr.doob 已提交
5112

5113 5114
			_oldPolygonOffsetFactor = factor;
			_oldPolygonOffsetUnits = units;
M
Mr.doob 已提交
5115

5116
		}
M
Mr.doob 已提交
5117

5118
	};
M
Mr.doob 已提交
5119

5120
	function setBlending ( blending ) {
M
Mr.doob 已提交
5121

5122
		if ( blending !== _oldBlending ) {
M
Mr.doob 已提交
5123

5124
			switch ( blending ) {
M
Mr.doob 已提交
5125

5126
				case THREE.AdditiveBlending:
M
Mr.doob 已提交
5127

5128 5129
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
M
Mr.doob 已提交
5130

5131
					break;
M
Mr.doob 已提交
5132

5133
				case THREE.SubtractiveBlending:
M
Mr.doob 已提交
5134

5135
					// TODO: Find blendFuncSeparate() combination
M
Mr.doob 已提交
5136

5137 5138
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
M
Mr.doob 已提交
5139

5140
					break;
M
Mr.doob 已提交
5141

5142
				case THREE.MultiplyBlending:
M
Mr.doob 已提交
5143

5144
					// TODO: Find blendFuncSeparate() combination
M
Mr.doob 已提交
5145

5146 5147
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
M
Mr.doob 已提交
5148

5149
					break;
5150

5151
				default:
N
Nicolas Garcia Belmonte 已提交
5152

5153 5154
					_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 );
5155

5156
					break;
5157

5158
			}
5159

5160
			_oldBlending = blending;
5161

5162
		}
5163 5164

	};
5165

5166 5167 5168
	// Shaders

	function buildProgram ( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
5169

5170
		var p, pl, program, code;
5171
		var chunks = [];
5172 5173 5174

		// Generate code

5175 5176 5177 5178 5179 5180 5181 5182 5183 5184
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

			chunks.push( fragmentShader );
			chunks.push( vertexShader );

		}
5185 5186 5187

		for ( p in parameters ) {

5188 5189
			chunks.push( p );
			chunks.push( parameters[ p ] );
5190 5191 5192

		}

5193 5194
		code = chunks.join();

5195 5196 5197 5198
		// Check if code has been already compiled

		for ( p = 0, pl = _programs.length; p < pl; p ++ ) {

5199
			if ( _programs[ p ].code === code ) {
5200 5201

				// console.log( "Code already compiled." /*: \n\n" + code*/ );
5202

5203 5204 5205 5206 5207
				return _programs[ p ].program;

			}

		}
5208

5209
		//console.log( "building new program " );
5210 5211 5212

		//

5213
		program = _gl.createProgram();
M
Mr.doob 已提交
5214

5215
		var prefix_vertex = [
M
Mr.doob 已提交
5216

A
alteredq 已提交
5217
			_supportsVertexTextures ? "#define VERTEX_TEXTURES" : "",
5218

5219 5220 5221 5222
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

5223 5224 5225
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

5226 5227
			"#define MAX_SHADOWS " + parameters.maxShadows,

5228 5229
			"#define MAX_BONES " + parameters.maxBones,

5230
			parameters.map ? "#define USE_MAP" : "",
5231 5232 5233
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5234
			parameters.skinning ? "#define USE_SKINNING" : "",
5235
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
A
alteredq 已提交
5236
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
5237

5238
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5239
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
5240

5241 5242
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
5243 5244 5245
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
5246 5247
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
5248
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
5249 5250 5251

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
5252 5253 5254
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
5255
			"attribute vec2 uv2;",
5256

5257
			"#ifdef USE_COLOR",
5258

5259
				"attribute vec3 color;",
5260

5261 5262
			"#endif",

5263
			"#ifdef USE_MORPHTARGETS",
5264

5265 5266 5267 5268 5269 5270 5271 5272
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
				"attribute vec3 morphTarget4;",
				"attribute vec3 morphTarget5;",
				"attribute vec3 morphTarget6;",
				"attribute vec3 morphTarget7;",
5273

5274 5275 5276
			"#endif",

			"#ifdef USE_SKINNING",
5277

5278 5279 5280 5281
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
5282

5283
			"#endif",
5284

M
Mr.doob 已提交
5285
			""
A
alteredq 已提交
5286

M
Mr.doob 已提交
5287
		].join("\n");
5288

M
Mr.doob 已提交
5289 5290 5291
		var prefix_fragment = [

			"#ifdef GL_ES",
5292
			"precision " + _precision + " float;",
M
Mr.doob 已提交
5293 5294 5295 5296 5297
			"#endif",

			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

5298 5299
			"#define MAX_SHADOWS " + parameters.maxShadows,

5300 5301
			parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",

5302 5303 5304 5305
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

M
Mr.doob 已提交
5306 5307
			( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
			( parameters.useFog && parameters.fog instanceof THREE.FogExp2 ) ? "#define FOG_EXP2" : "",
M
Mr.doob 已提交
5308 5309 5310 5311 5312

			parameters.map ? "#define USE_MAP" : "",
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5313

5314 5315 5316
			parameters.metal ? "#define METAL" : "",
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",

5317
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5318 5319 5320
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
			parameters.shadowMapSoft ? "#define SHADOWMAP_WIDTH " + parameters.shadowMapWidth.toFixed( 1 ) : "",
			parameters.shadowMapSoft ? "#define SHADOWMAP_HEIGHT " + parameters.shadowMapHeight.toFixed( 1 ) : "",
M
Mr.doob 已提交
5321 5322 5323 5324 5325 5326 5327

			"uniform mat4 viewMatrix;",
			"uniform vec3 cameraPosition;",
			""

		].join("\n");

5328 5329
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
5330

M
Mr.doob 已提交
5331
		_gl.linkProgram( program );
N
Nicolas Garcia Belmonte 已提交
5332

M
Mr.doob 已提交
5333
		if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
N
Nicolas Garcia Belmonte 已提交
5334

5335
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
5336

N
Nicolas Garcia Belmonte 已提交
5337
		}
5338

5339 5340
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
5341

M
Mr.doob 已提交
5342
		program.uniforms = {};
5343
		program.attributes = {};
M
Mr.doob 已提交
5344

5345 5346 5347 5348
		var identifiers, u, a, i;

		// cache uniform locations

5349
		identifiers = [
5350

5351 5352
			'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
			'cameraInverseMatrix', 'boneGlobalMatrices', 'morphTargetInfluences'
M
Mr.doob 已提交
5353

5354
		];
M
Mr.doob 已提交
5355

5356
		for ( u in uniforms ) {
M
Mr.doob 已提交
5357

5358
			identifiers.push( u );
M
Mr.doob 已提交
5359

5360
		}
M
Mr.doob 已提交
5361

5362
		cacheUniformLocations( program, identifiers );
M
Mr.doob 已提交
5363

5364
		// cache attributes locations
M
Mr.doob 已提交
5365

5366
		identifiers = [
A
alteredq 已提交
5367

5368 5369
			"position", "normal", "uv", "uv2", "tangent", "color",
			"skinVertexA", "skinVertexB", "skinIndex", "skinWeight"
A
alteredq 已提交
5370

5371
		];
M
Mr.doob 已提交
5372

5373
		for ( i = 0; i < parameters.maxMorphTargets; i ++ ) {
M
Mr.doob 已提交
5374

5375
			identifiers.push( "morphTarget" + i );
M
Mr.doob 已提交
5376

5377
		}
5378

5379
		for ( a in attributes ) {
5380

5381
			identifiers.push( a );
5382

5383
		}
5384

5385
		cacheAttributeLocations( program, identifiers );
5386

5387
		program.id = _programs.length;
5388

5389
		_programs.push( { program: program, code: code } );
5390

5391
		_this.info.memory.programs = _programs.length;
5392

5393
		return program;
5394

5395
	};
5396

5397
	// Shader parameters cache
5398

5399
	function cacheUniformLocations ( program, identifiers ) {
5400

5401
		var i, l, id;
5402

5403
		for( i = 0, l = identifiers.length; i < l; i++ ) {
5404

5405 5406
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
5407

5408
		}
M
Mr.doob 已提交
5409

5410
	};
M
Mr.doob 已提交
5411

5412
	function cacheAttributeLocations ( program, identifiers ) {
A
alteredq 已提交
5413

5414
		var i, l, id;
A
alteredq 已提交
5415

5416
		for( i = 0, l = identifiers.length; i < l; i++ ) {
A
alteredq 已提交
5417

5418 5419
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
A
alteredq 已提交
5420

5421
		}
5422

5423
	};
A
alteredq 已提交
5424

5425
	function getShader ( type, string ) {
A
alteredq 已提交
5426

5427
		var shader;
5428

5429
		if ( type === "fragment" ) {
A
alteredq 已提交
5430

5431
			shader = _gl.createShader( _gl.FRAGMENT_SHADER );
A
alteredq 已提交
5432

5433
		} else if ( type === "vertex" ) {
A
alteredq 已提交
5434

5435
			shader = _gl.createShader( _gl.VERTEX_SHADER );
A
alteredq 已提交
5436

5437
		}
A
alteredq 已提交
5438

5439 5440
		_gl.shaderSource( shader, string );
		_gl.compileShader( shader );
5441

5442
		if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {
5443

5444 5445 5446
			console.error( _gl.getShaderInfoLog( shader ) );
			console.error( string );
			return null;
5447

A
alteredq 已提交
5448 5449
		}

5450 5451
		return shader;

A
alteredq 已提交
5452
	};
5453

5454 5455 5456
	// Textures

	function setTextureParameters ( textureType, texture, image ) {
5457

5458
		if ( isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ) ) {
M
Mr.doob 已提交
5459

5460 5461
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
5462

5463 5464
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
5465

5466
			_gl.generateMipmap( textureType );
M
Mr.doob 已提交
5467

5468
		} else {
M
Mr.doob 已提交
5469

5470 5471
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
5472

5473 5474
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
5475

5476
		}
M
Mr.doob 已提交
5477

5478
	};
5479

5480
	function setTexture ( texture, slot ) {
5481

5482
		if ( texture.needsUpdate ) {
A
alteredq 已提交
5483

5484
			if ( ! texture.__webglInit ) {
M
Mr.doob 已提交
5485

5486
				texture.__webglInit = true;
5487
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5488

M
Mr.doob 已提交
5489 5490
				_this.info.memory.textures ++;

5491
			}
M
Mr.doob 已提交
5492

5493
			_gl.activeTexture( _gl.TEXTURE0 + slot );
5494 5495
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );

5496
			if ( texture instanceof THREE.DataTexture ) {
5497 5498

				_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( texture.format ), texture.image.width, texture.image.height, 0, paramThreeToGL( texture.format ), _gl.UNSIGNED_BYTE, texture.image.data );
M
Mr.doob 已提交
5499

A
alteredq 已提交
5500
			} else {
M
Mr.doob 已提交
5501

M
Mr.doob 已提交
5502
				_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
5503 5504 5505

			}

5506
			setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );
M
Mr.doob 已提交
5507

A
alteredq 已提交
5508
			texture.needsUpdate = false;
5509

5510 5511
			if ( texture.onUpdated ) texture.onUpdated();

5512
		} else {
5513

5514 5515
			_gl.activeTexture( _gl.TEXTURE0 + slot );
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
5516 5517

		}
M
Mr.doob 已提交
5518

5519
	};
M
Mr.doob 已提交
5520

5521
	function setCubeTexture ( texture, slot ) {
5522

5523
		if ( texture.image.length === 6 ) {
5524 5525 5526

			if ( texture.needsUpdate ) {

A
alteredq 已提交
5527
				if ( ! texture.image.__webglTextureCube ) {
5528 5529

					texture.image.__webglTextureCube = _gl.createTexture();
5530

A
alteredq 已提交
5531
				}
5532

A
alteredq 已提交
5533 5534
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5535

A
alteredq 已提交
5536
				for ( var i = 0; i < 6; i ++ ) {
5537

A
alteredq 已提交
5538
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
5539

A
alteredq 已提交
5540
				}
5541

A
alteredq 已提交
5542
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[ 0 ] );
5543

A
alteredq 已提交
5544
				texture.needsUpdate = false;
5545

A
alteredq 已提交
5546
			} else {
5547

A
alteredq 已提交
5548 5549
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5550

A
alteredq 已提交
5551
			}
5552

A
alteredq 已提交
5553
		}
5554

A
alteredq 已提交
5555
	};
5556

5557
	function setCubeTextureDynamic ( texture, slot ) {
5558

A
alteredq 已提交
5559 5560
		_gl.activeTexture( _gl.TEXTURE0 + slot );
		_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
5561 5562 5563

	};

5564 5565 5566
	// Render targets

	function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
5567

5568 5569
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
A
alteredq 已提交
5570

5571
	};
M
Mr.doob 已提交
5572

5573
	function setupRenderBuffer ( renderbuffer, renderTarget  ) {
M
Mikael Emtinger 已提交
5574

5575
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
5576

5577
		if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
M
Mr.doob 已提交
5578

5579 5580
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5581

5582 5583
		/* For some reason this is not working. Defaulting to RGBA4.
		} else if( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
A
alteredq 已提交
5584

5585 5586 5587 5588
			_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 已提交
5589

5590 5591
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5592

5593
		} else {
A
alteredq 已提交
5594

5595
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
A
alteredq 已提交
5596

5597
		}
A
alteredq 已提交
5598

5599
	};
A
alteredq 已提交
5600

5601
	function setRenderTarget ( renderTarget ) {
A
alteredq 已提交
5602

5603
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
A
alteredq 已提交
5604

5605
		if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
A
alteredq 已提交
5606

5607 5608
			if( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
			if( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
A
alteredq 已提交
5609

5610
			renderTarget.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5611

5612
			// Setup texture, create render and frame buffers
5613

5614
			if ( isCube ) {
M
Mr.doob 已提交
5615

5616 5617
				renderTarget.__webglFramebuffer = [];
				renderTarget.__webglRenderbuffer = [];
M
Mikael Emtinger 已提交
5618

5619 5620
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, renderTarget );
A
alteredq 已提交
5621

5622
				for ( var i = 0; i < 6; i ++ ) {
A
alteredq 已提交
5623

5624 5625
					renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
					renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
A
alteredq 已提交
5626

5627
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, paramThreeToGL( renderTarget.format ), renderTarget.width, renderTarget.height, 0, paramThreeToGL( renderTarget.format ), paramThreeToGL( renderTarget.type ), null );
A
alteredq 已提交
5628

5629
					setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
A
alteredq 已提交
5630

5631
					setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
A
alteredq 已提交
5632

5633
				}
5634

5635
			} else {
5636

5637 5638
				renderTarget.__webglFramebuffer = _gl.createFramebuffer();
				renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
5639

5640 5641
				_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
				setTextureParameters( _gl.TEXTURE_2D, renderTarget, renderTarget );
5642

5643
				_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTarget.format ), renderTarget.width, renderTarget.height, 0, paramThreeToGL( renderTarget.format ), paramThreeToGL( renderTarget.type ), null );
5644

5645
				setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
5646

5647
				_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTarget.__webglRenderbuffer );
5648

5649
				setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
5650

M
Mikael Emtinger 已提交
5651
			}
5652

5653
			// Release everything
M
Mr.doob 已提交
5654

A
alteredq 已提交
5655 5656 5657 5658 5659 5660 5661 5662 5663 5664
			if ( isCube ) {

				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

			} else {

				_gl.bindTexture( _gl.TEXTURE_2D, null );

			}

5665 5666
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
5667

5668 5669
		}

5670
		var framebuffer, width, height, vx, vy;
M
Mr.doob 已提交
5671

5672
		if ( renderTarget ) {
M
Mr.doob 已提交
5673

A
alteredq 已提交
5674 5675
			if ( isCube ) {

5676
				framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
A
alteredq 已提交
5677 5678 5679

			} else {

5680
				framebuffer = renderTarget.__webglFramebuffer;
A
alteredq 已提交
5681 5682 5683

			}

5684 5685
			width = renderTarget.width;
			height = renderTarget.height;
M
Mr.doob 已提交
5686

5687 5688 5689
			vx = 0;
			vy = 0;

5690
		} else {
M
Mr.doob 已提交
5691

5692
			framebuffer = null;
5693

5694 5695
			width = _viewportWidth;
			height = _viewportHeight;
5696

5697 5698
			vx = _viewportX;
			vy = _viewportY;
M
Mr.doob 已提交
5699

5700
		}
M
Mr.doob 已提交
5701

5702
		if ( framebuffer !== _currentFramebuffer ) {
M
Mr.doob 已提交
5703

5704
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
5705
			_gl.viewport( vx, vy, width, height );
M
Mr.doob 已提交
5706

5707
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
5708

5709
		}
5710

5711
	};
M
Mr.doob 已提交
5712

5713
	function updateRenderTargetMipmap ( renderTarget ) {
M
Mr.doob 已提交
5714

A
alteredq 已提交
5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727
		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 已提交
5728 5729

	};
5730

5731
	// fallback filters for non-power-of-2 textures
5732

5733
	function filterFallback ( f ) {
5734

5735 5736 5737 5738 5739 5740 5741 5742
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mr.doob 已提交
5743
			case THREE.LinearMipMapLinearFilter:
M
Mikael Emtinger 已提交
5744
			default:
5745

M
Mikael Emtinger 已提交
5746
				return _gl.LINEAR; break;
5747 5748

		}
5749

5750
	};
5751

5752
	function paramThreeToGL ( p ) {
M
Mr.doob 已提交
5753

5754
		switch ( p ) {
M
Mr.doob 已提交
5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767

			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;

5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781
			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;

5782
		}
M
Mr.doob 已提交
5783

5784
		return 0;
M
Mr.doob 已提交
5785

5786 5787
	};

5788
	function isPowerOfTwo ( value ) {
5789

5790
		return ( value & ( value - 1 ) ) === 0;
5791 5792 5793

	};

5794
	// Allocations
5795

5796
	function allocateBones ( object ) {
5797

5798 5799 5800 5801 5802 5803 5804
		// 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)
5805

5806
		var maxBones = 50;
5807

5808
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
5809

5810 5811 5812 5813 5814
			maxBones = object.bones.length;

		}

		return maxBones;
5815

5816
	};
5817

5818
	function allocateLights ( lights ) {
5819

5820 5821
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
5822

5823
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
5824

5825
			light = lights[ l ];
5826

5827 5828 5829
			if ( light instanceof THREE.SpotLight ) dirLights ++; // hack, not a proper spotlight
			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
			if ( light instanceof THREE.PointLight ) pointLights ++;
5830

5831
		}
5832

5833
		if ( ( pointLights + dirLights ) <= _maxLights ) {
5834

5835 5836
			maxDirLights = dirLights;
			maxPointLights = pointLights;
5837

5838
		} else {
5839

5840 5841
			maxDirLights = Math.ceil( _maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = _maxLights - maxDirLights;
5842 5843 5844

		}

5845
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
5846 5847

	};
M
Mr.doob 已提交
5848

5849
	function allocateShadows ( lights ) {
5850

M
Mr.doob 已提交
5851
		var l, ll, light, maxShadows = 0;
5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864

		for ( l = 0, ll = lights.length; l < ll; l++ ) {

			light = lights[ l ];

			if ( light instanceof THREE.SpotLight && light.castShadow ) maxShadows ++;

		}

		return maxShadows;

	};

5865
	function maxVertexTextures () {
5866

5867 5868 5869
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
M
Mr.doob 已提交
5870

5871
	// Initialization
M
Mr.doob 已提交
5872

5873
	function initSprites () {
M
Mr.doob 已提交
5874

5875 5876
		_sprite.vertices = new Float32Array( 8 + 8 );
		_sprite.faces    = new Uint16Array( 6 );
M
Mr.doob 已提交
5877

5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935
		var i = 0;

		_sprite.vertices[ i++ ] = -1; _sprite.vertices[ i++ ] = -1;	// vertex 0
		_sprite.vertices[ i++ ] = 0;  _sprite.vertices[ i++ ] = 1;	// uv 0

		_sprite.vertices[ i++ ] = 1;  _sprite.vertices[ i++ ] = -1;	// vertex 1
		_sprite.vertices[ i++ ] = 1;  _sprite.vertices[ i++ ] = 1;	// uv 1

		_sprite.vertices[ i++ ] = 1;  _sprite.vertices[ i++ ] = 1;	// vertex 2
		_sprite.vertices[ i++ ] = 1;  _sprite.vertices[ i++ ] = 0;	// uv 2

		_sprite.vertices[ i++ ] = -1; _sprite.vertices[ i++ ] = 1;	// vertex 3
		_sprite.vertices[ i++ ] = 0;  _sprite.vertices[ i++ ] = 0;	// uv 3

		i = 0;

		_sprite.faces[ i++ ] = 0; _sprite.faces[ i++ ] = 1; _sprite.faces[ i++ ] = 2;
		_sprite.faces[ i++ ] = 0; _sprite.faces[ i++ ] = 2; _sprite.faces[ i++ ] = 3;

		_sprite.vertexBuffer  = _gl.createBuffer();
		_sprite.elementBuffer = _gl.createBuffer();

		_gl.bindBuffer( _gl.ARRAY_BUFFER, _sprite.vertexBuffer );
		_gl.bufferData( _gl.ARRAY_BUFFER, _sprite.vertices, _gl.STATIC_DRAW );

		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _sprite.elementBuffer );
		_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _sprite.faces, _gl.STATIC_DRAW );

		_sprite.program = _gl.createProgram();
		_gl.attachShader( _sprite.program, getShader( "fragment", THREE.ShaderLib.sprite.fragmentShader ) );
		_gl.attachShader( _sprite.program, getShader( "vertex",   THREE.ShaderLib.sprite.vertexShader   ) );
		_gl.linkProgram( _sprite.program );

		_sprite.attributes = {};
		_sprite.uniforms = {};

		_sprite.attributes.position           = _gl.getAttribLocation ( _sprite.program, "position" );
		_sprite.attributes.uv                 = _gl.getAttribLocation ( _sprite.program, "uv" );

		_sprite.uniforms.uvOffset             = _gl.getUniformLocation( _sprite.program, "uvOffset" );
		_sprite.uniforms.uvScale              = _gl.getUniformLocation( _sprite.program, "uvScale" );

		_sprite.uniforms.rotation             = _gl.getUniformLocation( _sprite.program, "rotation" );
		_sprite.uniforms.scale                = _gl.getUniformLocation( _sprite.program, "scale" );
		_sprite.uniforms.alignment            = _gl.getUniformLocation( _sprite.program, "alignment" );

		_sprite.uniforms.color                = _gl.getUniformLocation( _sprite.program, "color" );
		_sprite.uniforms.map                  = _gl.getUniformLocation( _sprite.program, "map" );
		_sprite.uniforms.opacity              = _gl.getUniformLocation( _sprite.program, "opacity" );

		_sprite.uniforms.useScreenCoordinates = _gl.getUniformLocation( _sprite.program, "useScreenCoordinates" );
		_sprite.uniforms.affectedByDistance   = _gl.getUniformLocation( _sprite.program, "affectedByDistance" );
		_sprite.uniforms.screenPosition    	  = _gl.getUniformLocation( _sprite.program, "screenPosition" );
		_sprite.uniforms.modelViewMatrix      = _gl.getUniformLocation( _sprite.program, "modelViewMatrix" );
		_sprite.uniforms.projectionMatrix     = _gl.getUniformLocation( _sprite.program, "projectionMatrix" );

		//_gl.enableVertexAttribArray( _sprite.attributes.position );
		//_gl.enableVertexAttribArray( _sprite.attributes.uv );
M
Mr.doob 已提交
5936

5937
	};
M
Mr.doob 已提交
5938

5939
	function initShadowmaps () {
M
Mr.doob 已提交
5940

5941 5942
		var depthShader = THREE.ShaderLib[ "depthRGBA" ];
		var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
M
Mr.doob 已提交
5943

5944 5945
		_depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } );
		_depthMaterialMorph = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true } );
M
Mr.doob 已提交
5946

5947 5948
		_depthMaterial._shadowPass = true;
		_depthMaterialMorph._shadowPass = true;
M
Mr.doob 已提交
5949

5950
	}
5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002

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

	};

6003
};