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

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

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

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

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

16 17
	_stencil = parameters.stencil !== undefined ? parameters.stencil : true,
	_antialias = parameters.antialias !== undefined ? parameters.antialias : false,
18 19
	_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,

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

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

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

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

	// clearing
M
Mr.doob 已提交
31

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

37 38
	// scene graph

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

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

	// physically based shading

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

50 51 52 53 54 55 56 57 58 59 60
	// 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;

61
	this.shadowMap = [];
62

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

67
	// morphs
68

69
	this.maxMorphTargets = 8;
70

71
	// info
72

73
	this.info = {
74

75
		memory: {
76

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

81
		},
82

83
		render: {
84

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

		}

91
	};
M
Mr.doob 已提交
92

93
	// internal properties
94

95
	var _this = this,
96

97
	_gl,
98

99
	_programs = [],
100

101
	// internal state cache
102

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

109
	// GL state cache
110

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

121 122 123 124
	_viewportX = 0,
	_viewportY = 0,
	_viewportWidth = 0,
	_viewportHeight = 0,
125

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

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

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

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

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

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

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

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

153
	};
M
Mr.doob 已提交
154

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

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

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

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

165
	// initialize
M
Mikael Emtinger 已提交
166

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

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

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

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

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

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

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

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

184
	};
M
Mr.doob 已提交
185

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

188
		return _supportsVertexTextures;
M
Mikael Emtinger 已提交
189

190
	};
M
Mikael Emtinger 已提交
191

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

		_canvas.width = width;
		_canvas.height = height;
196

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

	};
N
Nicolas Garcia Belmonte 已提交
200

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

203 204
		_viewportX = x;
		_viewportY = y;
205

206 207
		_viewportWidth = width;
		_viewportHeight = height;
208

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

N
Nicolas Garcia Belmonte 已提交
211
	};
212

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

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

217
	};
218

219
	this.enableScissorTest = function ( enable ) {
220

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

	};
224

225 226
	// Clearing

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

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

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

234
	};
A
alteredq 已提交
235

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

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

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

	};
244

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

		return _clearColor;

	};

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

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

	};

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

		var bits = 0;

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

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

	};

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

271 272
		setRenderTarget( renderTarget );
		this.clear( color, depth, stencil );
M
Mr.doob 已提交
273 274 275

	};

276 277
	// Deallocation

278 279 280 281 282 283 284 285 286 287 288 289 290 291
	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 ) {

292
			for ( var g in object.geometry.geometryGroups ) {
293 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

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

323 324
	};

325
	// Rendering
326

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

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

331
	};
M
Mr.doob 已提交
332

333
	// Internal functions
334

335
	// Buffer allocation
336

337
	function createParticleBuffers ( geometry ) {
338

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

342
		_this.info.geometries ++;
343

344
	};
345

346
	function createLineBuffers ( geometry ) {
347

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

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

353
	};
354

355
	function createRibbonBuffers ( geometry ) {
356

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

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

362
	};
363

364
	function createMeshBuffers ( geometryGroup ) {
365

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

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

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

381
		if ( geometryGroup.numMorphTargets ) {
382

383
			var m, ml;
384

385
			geometryGroup.__webglMorphTargetsBuffers = [];
386

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

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

391
			}
392

393
		}
394

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

397
	};
398

399
	// Buffer deallocation
400

401
	function deleteParticleBuffers ( geometry ) {
402

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

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

408
	};
409

410
	function deleteLineBuffers ( geometry ) {
411

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

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

417 418
	};

419
	function deleteRibbonBuffers ( geometry ) {
420 421 422 423

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

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

426 427
	};

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

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

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

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

			}

		}

M
Mr.doob 已提交
455 456
		_this.info.memory.geometries --;

457 458
	};

459
	// Buffer initialization
460

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

463 464
		var nvertices = geometry.vertices.length;

465
		var material = object.material;
466

467
		if ( material.attributes ) {
468

469
			if ( geometry.__webglCustomAttributesList === undefined ) {
470

471
				geometry.__webglCustomAttributesList = [];
472

473
			}
474

475
			for ( var a in material.attributes ) {
476

477
				var attribute = material.attributes[ a ];
478

479
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
480

481
					attribute.__webglInitialized = true;
482

A
alteredq 已提交
483
					var size = 1;		// "f" and "i"
484

485 486 487 488
					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;
489

490
					attribute.size = size;
A
alteredq 已提交
491

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

494 495
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
496

497
					attribute.needsUpdate = true;
498

499
				}
500

501
				geometry.__webglCustomAttributesList.push( attribute );
502

503
			}
504

505
		}
506

507
	};
508

509
	function initParticleBuffers ( geometry, object ) {
A
alteredq 已提交
510 511 512 513 514 515

		var nvertices = geometry.vertices.length;

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

516 517 518
		geometry.__sortArray = [];

		geometry.__webglParticleCount = nvertices;
A
alteredq 已提交
519 520 521 522 523

		initCustomAttributes ( geometry, object );

	};

524
	function initLineBuffers ( geometry, object ) {
A
alteredq 已提交
525 526 527 528 529 530

		var nvertices = geometry.vertices.length;

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

531
		geometry.__webglLineCount = nvertices;
A
alteredq 已提交
532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547

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

550 551 552
		var geometry = object.geometry,
			faces3 = geometryGroup.faces3,
			faces4 = geometryGroup.faces4,
M
Mr.doob 已提交
553

554 555 556
			nvertices = faces3.length * 3 + faces4.length * 4,
			ntris     = faces3.length * 1 + faces4.length * 2,
			nlines    = faces3.length * 3 + faces4.length * 4,
557

558
			material = getBufferMaterial( object, geometryGroup ),
559

560 561 562
			uvType = bufferGuessUVType( material ),
			normalType = bufferGuessNormalType( material ),
			vertexColorType = bufferGuessVertexColorType( material );
A
alteredq 已提交
563

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

566
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
567

568
		if ( normalType ) {
M
Mr.doob 已提交
569

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

572
		}
573

574
		if ( geometry.hasTangents ) {
575

576
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
577

578
		}
579

580
		if ( vertexColorType ) {
581

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

584
		}
M
Mr.doob 已提交
585

586
		if ( uvType ) {
587

588
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
589

590 591 592 593 594
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

596 597 598 599 600 601 602 603 604 605 606 607 608 609 610
				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 );

		}

611
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
612
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
613

614 615
		if ( geometryGroup.numMorphTargets ) {

M
Mr.doob 已提交
616
			geometryGroup.__morphTargetsArrays = [];
617

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

620 621
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );

622 623 624
			}

		}
625

626
		geometryGroup.__needsSmoothNormals = ( normalType === THREE.SmoothShading );
627

628 629 630 631
		geometryGroup.__uvType = uvType;
		geometryGroup.__vertexColorType = vertexColorType;
		geometryGroup.__normalType = normalType;

632
		geometryGroup.__webglFaceCount = ntris * 3;
633
		geometryGroup.__webglLineCount = nlines * 2;
634

M
Mr.doob 已提交
635

636
		// custom attributes
M
Mr.doob 已提交
637

638
		if ( material.attributes ) {
639

640
			if ( geometryGroup.__webglCustomAttributesList === undefined ) {
641

642
				geometryGroup.__webglCustomAttributesList = [];
643

644
			}
645

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

648 649
				// Do a shallow copy of the attribute object so different geometryGroup chunks use different
				// attribute buffers which are correctly indexed in the setMeshBuffers function
650

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

653
				var attribute = {};
654

655
				for ( var property in originalAttribute ) {
M
Mr.doob 已提交
656

657
					attribute[ property ] = originalAttribute[ property ];
658

659
				}
660

661
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
662

663
					attribute.__webglInitialized = true;
664

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

667 668 669 670
					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;
671

672
					attribute.size = size;
A
alteredq 已提交
673

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

676 677
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
678

679 680
					originalAttribute.needsUpdate = true;
					attribute.__original = originalAttribute;
681 682 683

				}

684 685
				geometryGroup.__webglCustomAttributesList.push( attribute );

686
			}
M
Mr.doob 已提交
687

688
		}
689

690 691
		geometryGroup.__inittedArrays = true;

692
	};
M
Mr.doob 已提交
693

694
	function getBufferMaterial( object, geometryGroup ) {
695

696
		if ( object.material && ! ( object.material instanceof THREE.MeshFaceMaterial ) ) {
697

698
			return object.material;
699

700
		} else if ( geometryGroup.materialIndex >= 0 ) {
701

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

704
		}
705

706
	};
M
Mr.doob 已提交
707

708
	function materialNeedsSmoothNormals ( material ) {
709

710
		return material && material.shading !== undefined && material.shading === THREE.SmoothShading;
711

712
	};
M
Mr.doob 已提交
713

714
	function bufferGuessNormalType ( material ) {
715

716
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
717

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

720
			return false;
721

722
		}
723

724
		if ( materialNeedsSmoothNormals( material ) ) {
725

726
			return THREE.SmoothShading;
M
Mr.doob 已提交
727

728
		} else {
729

730
			return THREE.FlatShading;
731

732
		}
733

734
	};
735

736
	function bufferGuessVertexColorType ( material ) {
737

738
		if ( material.vertexColors ) {
739

740
			return material.vertexColors;
741

742
		}
M
Mr.doob 已提交
743

744
		return false;
M
Mr.doob 已提交
745

746
	};
M
Mr.doob 已提交
747

748
	function bufferGuessUVType ( material ) {
749

750 751 752 753 754 755 756 757 758 759 760 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
		// 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 已提交
1410

1411
				offset += 9;
M
Mr.doob 已提交
1412

1413
			}
1414

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

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

A
alteredq 已提交
1419 1420 1421 1422
				v1 = vertices[ face.a ].position;
				v2 = vertices[ face.b ].position;
				v3 = vertices[ face.c ].position;
				v4 = vertices[ face.d ].position;
1423

A
alteredq 已提交
1424 1425 1426
				vertexArray[ offset ]     = v1.x;
				vertexArray[ offset + 1 ] = v1.y;
				vertexArray[ offset + 2 ] = v1.z;
1427

A
alteredq 已提交
1428 1429 1430
				vertexArray[ offset + 3 ] = v2.x;
				vertexArray[ offset + 4 ] = v2.y;
				vertexArray[ offset + 5 ] = v2.z;
1431

A
alteredq 已提交
1432 1433 1434
				vertexArray[ offset + 6 ] = v3.x;
				vertexArray[ offset + 7 ] = v3.y;
				vertexArray[ offset + 8 ] = v3.z;
1435

A
alteredq 已提交
1436 1437 1438
				vertexArray[ offset + 9 ]  = v4.x;
				vertexArray[ offset + 10 ] = v4.y;
				vertexArray[ offset + 11 ] = v4.z;
1439

A
alteredq 已提交
1440
				offset += 12;
1441

A
alteredq 已提交
1442
			}
1443

A
alteredq 已提交
1444 1445
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1446

A
alteredq 已提交
1447
		}
M
Mr.doob 已提交
1448

A
alteredq 已提交
1449
		if ( dirtyMorphTargets ) {
M
Mr.doob 已提交
1450

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

A
alteredq 已提交
1453
				face = obj_faces[ chunk_faces3[ f ]	];
1454

A
alteredq 已提交
1455
				for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {
M
Mr.doob 已提交
1456

A
alteredq 已提交
1457 1458 1459
					v1 = morphTargets[ vk ].vertices[ face.a ].position;
					v2 = morphTargets[ vk ].vertices[ face.b ].position;
					v3 = morphTargets[ vk ].vertices[ face.c ].position;
M
Mr.doob 已提交
1460

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

A
alteredq 已提交
1463 1464 1465
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
M
Mr.doob 已提交
1466

A
alteredq 已提交
1467 1468 1469
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
M
Mr.doob 已提交
1470

A
alteredq 已提交
1471 1472 1473
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
M
Mr.doob 已提交
1474

1475 1476
				}

A
alteredq 已提交
1477 1478
				offset_morphTarget += 9;

1479
			}
1480

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

A
alteredq 已提交
1483
				face = obj_faces[ chunk_faces4[ f ] ];
1484

1485
				for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {
1486

1487 1488 1489
					v1 = morphTargets[ vk ].vertices[ face.a ].position;
					v2 = morphTargets[ vk ].vertices[ face.b ].position;
					v3 = morphTargets[ vk ].vertices[ face.c ].position;
A
alteredq 已提交
1490
					v4 = morphTargets[ vk ].vertices[ face.d ].position;
1491

1492
					vka = morphTargetsArrays[ vk ];
1493

1494 1495 1496
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
1497

1498 1499 1500
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
1501

1502 1503 1504
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
1505

A
alteredq 已提交
1506 1507 1508 1509
					vka[ offset_morphTarget + 9 ]  = v4.x;
					vka[ offset_morphTarget + 10 ] = v4.y;
					vka[ offset_morphTarget + 11 ] = v4.z;

1510 1511
				}

A
alteredq 已提交
1512 1513 1514 1515 1516 1517 1518 1519
				offset_morphTarget += 12;

			}

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

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

1521
			}
1522

A
alteredq 已提交
1523 1524 1525 1526 1527 1528 1529
		}

		if ( obj_skinWeights.length ) {

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

				face = obj_faces[ chunk_faces3[ f ]	];
1530

1531
				// weights
A
alteredq 已提交
1532

1533 1534 1535
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
A
alteredq 已提交
1536

1537 1538 1539 1540
				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 已提交
1541

1542 1543 1544 1545
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1546

1547 1548 1549 1550
				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 已提交
1551

1552
				// indices
A
alteredq 已提交
1553

1554 1555 1556
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
A
alteredq 已提交
1557

1558 1559 1560 1561
				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 已提交
1562

1563 1564 1565 1566
				skinIndexArray[ offset_skin + 4 ] = si2.x;
				skinIndexArray[ offset_skin + 5 ] = si2.y;
				skinIndexArray[ offset_skin + 6 ] = si2.z;
				skinIndexArray[ offset_skin + 7 ] = si2.w;
1567

1568 1569 1570 1571
				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 已提交
1572

1573
				// vertices A
A
alteredq 已提交
1574

1575 1576 1577
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
A
alteredq 已提交
1578

1579 1580 1581 1582
				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 已提交
1583

1584 1585 1586 1587
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1588

1589 1590 1591 1592
				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 已提交
1593

1594
				// vertices B
A
alteredq 已提交
1595

1596 1597 1598
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
A
alteredq 已提交
1599

1600 1601 1602 1603
				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 已提交
1604

1605 1606 1607 1608
				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
				skinVertexBArray[ offset_skin + 7 ] = 1;
1609

1610 1611 1612 1613
				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
				skinVertexBArray[ offset_skin + 11 ] = 1;
1614

1615
				offset_skin += 12;
1616

1617
			}
1618

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

A
alteredq 已提交
1621
				face = obj_faces[ chunk_faces4[ f ] ];
1622

A
alteredq 已提交
1623
				// weights
1624

A
alteredq 已提交
1625 1626 1627 1628
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
				sw4 = obj_skinWeights[ face.d ];
1629

A
alteredq 已提交
1630 1631 1632 1633
				skinWeightArray[ offset_skin ]     = sw1.x;
				skinWeightArray[ offset_skin + 1 ] = sw1.y;
				skinWeightArray[ offset_skin + 2 ] = sw1.z;
				skinWeightArray[ offset_skin + 3 ] = sw1.w;
1634

A
alteredq 已提交
1635 1636 1637 1638
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1639

A
alteredq 已提交
1640 1641 1642 1643
				skinWeightArray[ offset_skin + 8 ]  = sw3.x;
				skinWeightArray[ offset_skin + 9 ]  = sw3.y;
				skinWeightArray[ offset_skin + 10 ] = sw3.z;
				skinWeightArray[ offset_skin + 11 ] = sw3.w;
1644

A
alteredq 已提交
1645 1646 1647 1648
				skinWeightArray[ offset_skin + 12 ] = sw4.x;
				skinWeightArray[ offset_skin + 13 ] = sw4.y;
				skinWeightArray[ offset_skin + 14 ] = sw4.z;
				skinWeightArray[ offset_skin + 15 ] = sw4.w;
1649

A
alteredq 已提交
1650
				// indices
1651

A
alteredq 已提交
1652 1653 1654 1655
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
				si4 = obj_skinIndices[ face.d ];
1656

A
alteredq 已提交
1657 1658 1659 1660
				skinIndexArray[ offset_skin ]     = si1.x;
				skinIndexArray[ offset_skin + 1 ] = si1.y;
				skinIndexArray[ offset_skin + 2 ] = si1.z;
				skinIndexArray[ offset_skin + 3 ] = si1.w;
1661

A
alteredq 已提交
1662 1663 1664 1665
				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 已提交
1666

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

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

A
alteredq 已提交
1677
				// vertices A
M
Mr.doob 已提交
1678

A
alteredq 已提交
1679 1680 1681 1682
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
				sa4 = obj_skinVerticesA[ face.d ];
1683

A
alteredq 已提交
1684 1685 1686 1687
				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 已提交
1688

A
alteredq 已提交
1689 1690 1691 1692
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1693

A
alteredq 已提交
1694 1695 1696 1697
				skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
				skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
				skinVertexAArray[ offset_skin + 10 ] = sa3.z;
				skinVertexAArray[ offset_skin + 11 ] = 1;
1698

A
alteredq 已提交
1699 1700 1701 1702
				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 已提交
1703

A
alteredq 已提交
1704
				// vertices B
M
Mr.doob 已提交
1705

A
alteredq 已提交
1706 1707 1708 1709
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
				sb4 = obj_skinVerticesB[ face.d ];
M
Mr.doob 已提交
1710

A
alteredq 已提交
1711 1712 1713 1714
				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 已提交
1715

A
alteredq 已提交
1716 1717 1718 1719
				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
				skinVertexBArray[ offset_skin + 7 ] = 1;
1720

A
alteredq 已提交
1721 1722 1723 1724
				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
				skinVertexBArray[ offset_skin + 11 ] = 1;
1725

A
alteredq 已提交
1726 1727 1728 1729
				skinVertexBArray[ offset_skin + 12 ] = sb4.x;
				skinVertexBArray[ offset_skin + 13 ] = sb4.y;
				skinVertexBArray[ offset_skin + 14 ] = sb4.z;
				skinVertexBArray[ offset_skin + 15 ] = 1;
1730

A
alteredq 已提交
1731
				offset_skin += 16;
M
Mr.doob 已提交
1732

A
alteredq 已提交
1733
			}
M
Mr.doob 已提交
1734

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

A
alteredq 已提交
1737 1738
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );
M
Mr.doob 已提交
1739

A
alteredq 已提交
1740 1741 1742 1743 1744 1745 1746 1747
				_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 );
1748

1749
			}
1750

A
alteredq 已提交
1751
		}
M
Mr.doob 已提交
1752

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

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

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

A
alteredq 已提交
1759 1760
				vertexColors = face.vertexColors;
				faceColor = face.color;
1761

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

A
alteredq 已提交
1764 1765 1766
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
1767

A
alteredq 已提交
1768
				} else {
1769

A
alteredq 已提交
1770 1771 1772
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
1773

A
alteredq 已提交
1774
				}
1775

A
alteredq 已提交
1776 1777 1778
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
1779

A
alteredq 已提交
1780 1781 1782
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
1783

A
alteredq 已提交
1784 1785 1786
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
1787

A
alteredq 已提交
1788
				offset_color += 9;
M
Mr.doob 已提交
1789

A
alteredq 已提交
1790
			}
M
Mr.doob 已提交
1791

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

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

A
alteredq 已提交
1796 1797
				vertexColors = face.vertexColors;
				faceColor = face.color;
M
Mr.doob 已提交
1798

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

A
alteredq 已提交
1801 1802 1803 1804
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
					c4 = vertexColors[ 3 ];
1805

A
alteredq 已提交
1806
				} else {
M
Mr.doob 已提交
1807

A
alteredq 已提交
1808 1809 1810 1811
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
					c4 = faceColor;
M
Mr.doob 已提交
1812

A
alteredq 已提交
1813
				}
1814

A
alteredq 已提交
1815 1816 1817
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
1818

A
alteredq 已提交
1819 1820 1821
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
M
Mr.doob 已提交
1822

A
alteredq 已提交
1823 1824 1825
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
M
Mr.doob 已提交
1826

A
alteredq 已提交
1827 1828 1829
				colorArray[ offset_color + 9 ]  = c4.r;
				colorArray[ offset_color + 10 ] = c4.g;
				colorArray[ offset_color + 11 ] = c4.b;
M
Mr.doob 已提交
1830

A
alteredq 已提交
1831
				offset_color += 12;
1832

1833
			}
1834

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

A
alteredq 已提交
1837 1838
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
M
Mr.doob 已提交
1839

1840
			}
1841

A
alteredq 已提交
1842
		}
M
Mr.doob 已提交
1843

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

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

A
alteredq 已提交
1848
				face = obj_faces[ chunk_faces3[ f ]	];
1849

A
alteredq 已提交
1850
				vertexTangents = face.vertexTangents;
M
Mr.doob 已提交
1851

A
alteredq 已提交
1852 1853 1854
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
1855

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

A
alteredq 已提交
1861 1862 1863 1864
				tangentArray[ offset_tangent + 4 ] = t2.x;
				tangentArray[ offset_tangent + 5 ] = t2.y;
				tangentArray[ offset_tangent + 6 ] = t2.z;
				tangentArray[ offset_tangent + 7 ] = t2.w;
1865

A
alteredq 已提交
1866 1867 1868 1869
				tangentArray[ offset_tangent + 8 ]  = t3.x;
				tangentArray[ offset_tangent + 9 ]  = t3.y;
				tangentArray[ offset_tangent + 10 ] = t3.z;
				tangentArray[ offset_tangent + 11 ] = t3.w;
1870

A
alteredq 已提交
1871
				offset_tangent += 12;
1872

1873
			}
1874

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

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

A
alteredq 已提交
1879
				vertexTangents = face.vertexTangents;
1880

A
alteredq 已提交
1881 1882 1883 1884
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
				t4 = vertexTangents[ 3 ];
1885

A
alteredq 已提交
1886 1887 1888 1889
				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 已提交
1890

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

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

A
alteredq 已提交
1901 1902 1903 1904
				tangentArray[ offset_tangent + 12 ] = t4.x;
				tangentArray[ offset_tangent + 13 ] = t4.y;
				tangentArray[ offset_tangent + 14 ] = t4.z;
				tangentArray[ offset_tangent + 15 ] = t4.w;
1905

A
alteredq 已提交
1906
				offset_tangent += 16;
1907

A
alteredq 已提交
1908
			}
1909

A
alteredq 已提交
1910 1911
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
1912

A
alteredq 已提交
1913
		}
1914

A
alteredq 已提交
1915
		if ( dirtyNormals && normalType ) {
1916

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

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

A
alteredq 已提交
1921 1922
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
1923

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

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

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

A
alteredq 已提交
1930 1931 1932
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
1933

A
alteredq 已提交
1934
						offset_normal += 3;
1935

A
alteredq 已提交
1936
					}
1937

A
alteredq 已提交
1938
				} else {
M
Mr.doob 已提交
1939

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

A
alteredq 已提交
1942 1943 1944
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
1945

A
alteredq 已提交
1946
						offset_normal += 3;
M
Mr.doob 已提交
1947

A
alteredq 已提交
1948
					}
1949

A
alteredq 已提交
1950
				}
1951

A
alteredq 已提交
1952
			}
1953

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

A
alteredq 已提交
1956
				face = obj_faces[ chunk_faces4[ f ] ];
1957

A
alteredq 已提交
1958 1959
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
1960

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

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

A
alteredq 已提交
1965
						vn = vertexNormals[ i ];
1966

A
alteredq 已提交
1967 1968 1969
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
1970

A
alteredq 已提交
1971
						offset_normal += 3;
1972

A
alteredq 已提交
1973
					}
M
Mr.doob 已提交
1974

A
alteredq 已提交
1975
				} else {
1976

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

A
alteredq 已提交
1979 1980 1981
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1982

A
alteredq 已提交
1983
						offset_normal += 3;
M
Mr.doob 已提交
1984

A
alteredq 已提交
1985
					}
1986

A
alteredq 已提交
1987
				}
1988

A
alteredq 已提交
1989
			}
M
Mr.doob 已提交
1990

A
alteredq 已提交
1991 1992
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
1993

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

A
alteredq 已提交
1996
		if ( dirtyUvs && obj_uvs && uvType ) {
1997

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

A
alteredq 已提交
2000
				fi = chunk_faces3[ f ];
2001

A
alteredq 已提交
2002 2003
				face = obj_faces[ fi ];
				uv = obj_uvs[ fi ];
2004

A
alteredq 已提交
2005
				if ( uv === undefined ) continue;
2006

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

A
alteredq 已提交
2009
					uvi = uv[ i ];
2010

A
alteredq 已提交
2011 2012
					uvArray[ offset_uv ]     = uvi.u;
					uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
2013

A
alteredq 已提交
2014
					offset_uv += 2;
M
Mr.doob 已提交
2015

A
alteredq 已提交
2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036
				}

			}

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

2038 2039
				}

2040
			}
2041

A
alteredq 已提交
2042
			if ( offset_uv > 0 ) {
2043

A
alteredq 已提交
2044 2045
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
2046

A
alteredq 已提交
2047
			}
2048

A
alteredq 已提交
2049
		}
2050

A
alteredq 已提交
2051
		if ( dirtyUvs && obj_uvs2 && uvType ) {
2052

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

A
alteredq 已提交
2055
				fi = chunk_faces3[ f ];
2056

A
alteredq 已提交
2057 2058
				face = obj_faces[ fi ];
				uv2 = obj_uvs2[ fi ];
2059

A
alteredq 已提交
2060 2061 2062 2063 2064 2065 2066 2067 2068 2069
				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;
2070

2071 2072
				}

A
alteredq 已提交
2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093
			}

			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;

				}
2094

2095
			}
2096

A
alteredq 已提交
2097
			if ( offset_uv2 > 0 ) {
2098

A
alteredq 已提交
2099 2100
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );
2101

A
alteredq 已提交
2102
			}
2103

A
alteredq 已提交
2104
		}
2105

A
alteredq 已提交
2106
		if ( dirtyElements ) {
2107

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

A
alteredq 已提交
2110
				face = obj_faces[ chunk_faces3[ f ]	];
2111

A
alteredq 已提交
2112 2113 2114
				faceArray[ offset_face ] 	 = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 2;
2115

A
alteredq 已提交
2116
				offset_face += 3;
2117

A
alteredq 已提交
2118 2119
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2120

A
alteredq 已提交
2121 2122
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 2;
2123

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

A
alteredq 已提交
2127
				offset_line += 6;
2128

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

A
alteredq 已提交
2131
			}
2132

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

A
alteredq 已提交
2135
				face = obj_faces[ chunk_faces4[ f ] ];
2136

A
alteredq 已提交
2137 2138 2139
				faceArray[ offset_face ]     = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 3;
2140

A
alteredq 已提交
2141 2142 2143
				faceArray[ offset_face + 3 ] = vertexIndex + 1;
				faceArray[ offset_face + 4 ] = vertexIndex + 2;
				faceArray[ offset_face + 5 ] = vertexIndex + 3;
2144

A
alteredq 已提交
2145
				offset_face += 6;
2146

A
alteredq 已提交
2147 2148
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2149

A
alteredq 已提交
2150 2151
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 3;
2152

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

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

A
alteredq 已提交
2159
				offset_line += 8;
2160

A
alteredq 已提交
2161
				vertexIndex += 4;
2162

2163
			}
2164

A
alteredq 已提交
2165 2166
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
2167

A
alteredq 已提交
2168 2169
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
2170

A
alteredq 已提交
2171
		}
2172

A
alteredq 已提交
2173
		if ( customAttributes ) {
2174

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

2177
				customAttribute = customAttributes[ i ];
2178

2179
				if ( ! customAttribute.__original.needsUpdate ) continue;
2180

2181 2182
				offset_custom = 0;
				offset_customSrc = 0;
2183

2184 2185 2186 2187 2188 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
				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 ++ ) {

2217
							value = customAttribute.value[ chunk_faces3[ f ] ];
2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228

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

2229
							value = customAttribute.value[ chunk_faces4[ f ] ];
2230 2231 2232 2233 2234 2235 2236 2237 2238

							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;

						}
2239

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

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

2244 2245 2246
							customAttribute.array[ offset_custom ] 	   = customAttribute.value[ offset_customSrc ];
							customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ offset_customSrc + 1 ];
							customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ offset_customSrc + 2 ];
2247

2248 2249
							offset_custom += 3;
							offset_customSrc += 3;
M
Mr.doob 已提交
2250

2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283
						}

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

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

							offset_custom += 4;
							offset_customSrc += 4;

						}

					}

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

2285 2286
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2287

2288
							offset_custom += 6;
A
alteredq 已提交
2289

2290
						}
A
alteredq 已提交
2291

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

2294
							face = obj_faces[ chunk_faces4[ f ] ];
A
alteredq 已提交
2295

2296 2297 2298 2299
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
A
alteredq 已提交
2300

2301 2302
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2303

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

2307 2308
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2309

2310 2311
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
A
alteredq 已提交
2312

2313
							offset_custom += 8;
A
alteredq 已提交
2314

2315
						}
A
alteredq 已提交
2316

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

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

2321
							value = customAttribute.value[ chunk_faces3[ f ] ];
A
alteredq 已提交
2322

2323 2324 2325
							v1 = value;
							v2 = value;
							v3 = value;
A
alteredq 已提交
2326

2327 2328
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2329

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

2333 2334
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2335

2336
							offset_custom += 6;
A
alteredq 已提交
2337

2338
						}
A
alteredq 已提交
2339

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

2342
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2343

2344 2345 2346 2347
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2348

2349 2350
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2351

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

2355 2356
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2357

2358 2359
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
2360

2361
							offset_custom += 8;
M
Mr.doob 已提交
2362

2363
						}
M
Mr.doob 已提交
2364

2365
					} else if ( customAttribute.boundTo === "faceVertices" ) {
M
Mr.doob 已提交
2366

2367
						for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
M
Mr.doob 已提交
2368

2369 2370 2371
							v1 = customAttribute.value[ offset_customSrc ];
							v2 = customAttribute.value[ offset_customSrc + 1 ];
							v3 = customAttribute.value[ offset_customSrc + 2 ];
M
Mr.doob 已提交
2372

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

2376 2377
							customAttribute.array[ offset_custom + 2 ] = v2.x;
							customAttribute.array[ offset_custom + 3 ] = v2.y;
2378

2379 2380
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
M
Mr.doob 已提交
2381

2382 2383
							offset_custom += 6;
							offset_customSrc += 3;
M
Mr.doob 已提交
2384

2385
						}
M
Mr.doob 已提交
2386

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

2389 2390 2391 2392
							v1 = customAttribute.value[ offset_customSrc ];
							v2 = customAttribute.value[ offset_customSrc + 1 ];
							v3 = customAttribute.value[ offset_customSrc + 2 ];
							v4 = customAttribute.value[ offset_customSrc + 3 ];
2393

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

2397 2398
							customAttribute.array[ offset_custom + 2 ] = v2.x;
							customAttribute.array[ offset_custom + 3 ] = v2.y;
2399

2400 2401
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
M
Mr.doob 已提交
2402

2403 2404
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
2405

2406 2407
							offset_custom += 8;
							offset_customSrc += 4;
A
alteredq 已提交
2408 2409

						}
M
Mr.doob 已提交
2410 2411

					}
M
Mr.doob 已提交
2412

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

2415
					var pp;
2416

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

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

2421
					} else {
M
Mr.doob 已提交
2422

2423
						pp = [ "x", "y", "z" ];
2424

2425
					}
2426

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

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

2431
							face = obj_faces[ chunk_faces3[ f ]	];
2432

2433 2434 2435
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
2436

2437 2438 2439
							customAttribute.array[ offset_custom ] 	   = v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
2440

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

2445 2446 2447
							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 已提交
2448

2449
							offset_custom += 9;
M
Mr.doob 已提交
2450

2451
						}
M
Mr.doob 已提交
2452

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

2455
							face = obj_faces[ chunk_faces4[ f ] ];
M
Mr.doob 已提交
2456

2457 2458 2459 2460
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
M
Mr.doob 已提交
2461

2462 2463 2464
							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 已提交
2465

2466 2467 2468
							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 已提交
2469

2470 2471 2472
							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 已提交
2473

2474 2475 2476
							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 已提交
2477

2478
							offset_custom += 12;
M
Mr.doob 已提交
2479

2480
						}
M
Mr.doob 已提交
2481

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

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

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

2488 2489 2490
							v1 = value;
							v2 = value;
							v3 = value;
M
Mr.doob 已提交
2491

2492 2493 2494
							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 已提交
2495

2496 2497 2498
							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 已提交
2499

2500 2501 2502
							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 已提交
2503

2504
							offset_custom += 9;
M
Mr.doob 已提交
2505

2506
						}
2507

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

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

2512 2513 2514 2515
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
2516

2517 2518 2519
							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
2520

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

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

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

2533
							offset_custom += 12;
2534

2535
						}
2536

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

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

2541 2542 2543
							v1 = customAttribute.value[ offset_customSrc ];
							v2 = customAttribute.value[ offset_customSrc + 1 ];
							v3 = customAttribute.value[ offset_customSrc + 2 ];
2544

2545 2546 2547
							customAttribute.array[ offset_custom ] 	   = v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
2548

2549 2550 2551
							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 已提交
2552

2553 2554 2555
							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 已提交
2556

2557 2558
							offset_custom += 9;
							offset_customSrc += 3;
2559

2560
						}
2561

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

2564 2565 2566 2567
							v1 = customAttribute.value[ offset_customSrc ];
							v2 = customAttribute.value[ offset_customSrc + 1 ];
							v3 = customAttribute.value[ offset_customSrc + 2 ];
							v4 = customAttribute.value[ offset_customSrc + 3 ];
2568

2569 2570 2571
							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 已提交
2572

2573 2574 2575
							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 已提交
2576

2577 2578 2579
							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 已提交
2580

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

2585 2586
							offset_custom += 12;
							offset_customSrc += 4;
2587

A
alteredq 已提交
2588
						}
2589

A
alteredq 已提交
2590
					}
M
Mr.doob 已提交
2591

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

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

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

2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659
							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 ++ ) {

2660
							value = customAttribute.value[ chunk_faces3[ f ] ];
2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677

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

2681
							offset_custom += 12;
A
alteredq 已提交
2682

2683 2684
						}

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

2687
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2688

2689 2690 2691 2692
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2693

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

2699 2700 2701 2702
							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;
2703

2704 2705 2706 2707
							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;
2708

2709 2710 2711 2712
							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;
2713

2714
							offset_custom += 16;
A
alteredq 已提交
2715

2716
						}
A
alteredq 已提交
2717

2718
					} else if ( customAttribute.boundTo === "faceVertices" ) {
A
alteredq 已提交
2719

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

2722 2723 2724
							v1 = customAttribute.value[ offset_customSrc ];
							v2 = customAttribute.value[ offset_customSrc + 1 ];
							v3 = customAttribute.value[ offset_customSrc + 2 ];
A
alteredq 已提交
2725

2726 2727 2728 2729
							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;
A
alteredq 已提交
2730

2731 2732 2733 2734
							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;
A
alteredq 已提交
2735

2736 2737 2738 2739
							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;
A
alteredq 已提交
2740

2741 2742
							offset_custom += 12;
							offset_customSrc += 3;
A
alteredq 已提交
2743

2744
						}
A
alteredq 已提交
2745

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

2748 2749 2750 2751
							v1 = customAttribute.value[ offset_customSrc ];
							v2 = customAttribute.value[ offset_customSrc + 1 ];
							v3 = customAttribute.value[ offset_customSrc + 2 ];
							v4 = customAttribute.value[ offset_customSrc + 3 ];
A
alteredq 已提交
2752

2753 2754 2755 2756
							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;
2757

2758 2759 2760 2761
							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;
2762

2763 2764 2765 2766
							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;
2767

2768 2769 2770 2771
							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;
2772

2773 2774
							offset_custom += 16;
							offset_customSrc += 4;
2775 2776

						}
A
alteredq 已提交
2777 2778 2779 2780 2781

					}

				}

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

A
alteredq 已提交
2785 2786 2787 2788
			}

		}

2789
		if ( dispose ) {
2790

2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803
			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 已提交
2804

2805
		}
A
alteredq 已提交
2806

2807
	};
A
alteredq 已提交
2808

2809
	// Buffer rendering
A
alteredq 已提交
2810

2811
	function renderBufferImmediate ( object, program, shading ) {
A
alteredq 已提交
2812

2813 2814
		if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
A
alteredq 已提交
2815

2816
		if ( object.hasPos ) {
A
alteredq 已提交
2817

2818 2819 2820 2821
			_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 已提交
2822 2823 2824

		}

2825
		if ( object.hasNormal ) {
A
alteredq 已提交
2826

2827
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
A
alteredq 已提交
2828

2829
			if ( shading === THREE.FlatShading ) {
2830

2831 2832 2833 2834
				var nx, ny, nz,
					nax, nbx, ncx, nay, nby, ncy, naz, nbz, ncz,
					normalArray,
					i, il = object.count * 3;
2835

2836
				for( i = 0; i < il; i += 9 ) {
2837

2838
					normalArray = object.normalArray;
2839

2840 2841 2842
					nax  = normalArray[ i ];
					nay  = normalArray[ i + 1 ];
					naz  = normalArray[ i + 2 ];
2843

2844 2845 2846
					nbx  = normalArray[ i + 3 ];
					nby  = normalArray[ i + 4 ];
					nbz  = normalArray[ i + 5 ];
2847

2848 2849 2850
					ncx  = normalArray[ i + 6 ];
					ncy  = normalArray[ i + 7 ];
					ncz  = normalArray[ i + 8 ];
2851

2852 2853 2854
					nx = ( nax + nbx + ncx ) / 3;
					ny = ( nay + nby + ncy ) / 3;
					nz = ( naz + nbz + ncz ) / 3;
2855

2856 2857 2858
					normalArray[ i ] 	 = nx;
					normalArray[ i + 1 ] = ny;
					normalArray[ i + 2 ] = nz;
2859

2860 2861 2862
					normalArray[ i + 3 ] = nx;
					normalArray[ i + 4 ] = ny;
					normalArray[ i + 5 ] = nz;
2863

2864 2865 2866
					normalArray[ i + 6 ] = nx;
					normalArray[ i + 7 ] = ny;
					normalArray[ i + 8 ] = nz;
2867

2868
				}
2869

2870
			}
2871

2872 2873 2874
			_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 );
2875

2876
		}
2877

2878
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );
2879

2880
		object.count = 0;
2881

2882
	};
2883

2884
	function renderBuffer ( camera, lights, fog, material, geometryGroup, object ) {
2885

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

2888
		var program, attributes, linewidth, primitives, a, attribute, i, il;
2889

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

2892
		attributes = program.attributes;
2893

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

2898
		if ( geometryGroupHash !== _currentGeometryGroupHash ) {
A
alteredq 已提交
2899

2900 2901
			_currentGeometryGroupHash = geometryGroupHash;
			updateBuffers = true;
2902

2903
		}
2904

2905
		// vertices
2906

2907
		if ( !material.morphTargets && attributes.position >= 0 ) {
2908

2909
			if ( updateBuffers ) {
2910

2911 2912
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
				_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
2913

2914
			}
2915

2916
		} else {
2917

2918
			if ( object.morphTargetBase ) {
2919

2920
				setupMorphTargets( material, geometryGroup, object );
2921

2922
			}
2923

2924
		}
2925

2926

2927
		if ( updateBuffers ) {
2928

2929
			// custom attributes
2930

2931
			// Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
2932

2933
			if ( geometryGroup.__webglCustomAttributesList ) {
2934

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

2937
					attribute = geometryGroup.__webglCustomAttributesList[ i ];
2938

2939
					if( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
2940

2941 2942
						_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
						_gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 );
2943

2944
					}
2945

2946
				}
2947

2948
			}
2949 2950


2951
			// colors
2952

2953
			if ( attributes.color >= 0 ) {
2954

2955 2956
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
2957

2958
			}
2959

2960
			// normals
2961

2962
			if ( attributes.normal >= 0 ) {
2963

2964 2965
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
				_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
2966

2967
			}
2968

2969
			// tangents
2970

2971
			if ( attributes.tangent >= 0 ) {
2972

2973 2974
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
				_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
2975

2976
			}
2977

2978
			// uvs
2979

2980
			if ( attributes.uv >= 0 ) {
2981

2982
				if ( geometryGroup.__webglUVBuffer ) {
2983

2984 2985
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
					_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
2986

2987
					_gl.enableVertexAttribArray( attributes.uv );
2988

2989
				} else {
2990

2991
					_gl.disableVertexAttribArray( attributes.uv );
2992 2993 2994 2995 2996

				}

			}

2997
			if ( attributes.uv2 >= 0 ) {
2998

2999
				if ( geometryGroup.__webglUV2Buffer ) {
3000

3001 3002
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
					_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
3003

3004
					_gl.enableVertexAttribArray( attributes.uv2 );
3005

3006
				} else {
3007

3008
					_gl.disableVertexAttribArray( attributes.uv2 );
3009 3010

				}
3011 3012

			}
3013

3014 3015 3016
			if ( material.skinning &&
				 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
				 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
A
alteredq 已提交
3017

3018 3019
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3020

3021 3022
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
				_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3023

3024 3025
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
				_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3026

3027 3028
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
				_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
3029

A
alteredq 已提交
3030
			}
3031

3032
		}
3033

3034
		// render mesh
3035

3036
		if ( object instanceof THREE.Mesh ) {
3037

3038
			// wireframe
3039

3040
			if ( material.wireframe ) {
3041

3042
				setLineWidth( material.wireframeLinewidth );
3043

3044 3045
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
3046

3047
			// triangles
3048

3049
			} else {
3050

3051 3052
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3053

3054
			}
3055

3056 3057 3058
			_this.info.render.calls ++;
			_this.info.render.vertices += geometryGroup.__webglFaceCount;
			_this.info.render.faces += geometryGroup.__webglFaceCount / 3;
3059

3060
		// render lines
3061

3062
		} else if ( object instanceof THREE.Line ) {
3063

3064
			primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
3065

3066
			setLineWidth( material.linewidth );
3067

3068
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
3069

3070
			_this.info.render.calls ++;
3071

3072
		// render particles
3073

3074
		} else if ( object instanceof THREE.ParticleSystem ) {
3075

3076
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
3077

3078
			_this.info.render.calls ++;
3079

3080
		// render ribbon
3081

3082
		} else if ( object instanceof THREE.Ribbon ) {
3083

3084
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
3085

3086
			_this.info.render.calls ++;
3087

3088
		}
3089

3090
	};
3091

3092
	function setupMorphTargets ( material, geometryGroup, object ) {
3093

3094
		// set base
3095

3096
		var attributes = material.program.attributes;
3097

3098
		if ( object.morphTargetBase !== - 1 ) {
3099

3100 3101
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3102

3103
		} else if ( attributes.position >= 0 ) {
3104

3105 3106
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3107

3108
		}
3109

3110
		if ( object.morphTargetForcedOrder.length ) {
3111

3112
			// set forced order
3113

3114 3115 3116 3117 3118
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;

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

3120 3121 3122 3123 3124 3125
				_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 ++;
3126 3127
			}

3128 3129 3130 3131 3132 3133 3134 3135 3136 3137
		} else {

			// find most influencing

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

3139
			if ( object.morphTargetBase !== - 1 ) {
3140

3141
				used[ object.morphTargetBase ] = true;
3142

3143
			}
3144

3145
			while ( m < material.numSupportedMorphTargets ) {
3146

3147
				for ( i = 0; i < il; i ++ ) {
3148

3149
					if ( !used[ i ] && influences[ i ] > candidateInfluence ) {
3150

3151 3152
						candidate = i;
						candidateInfluence = influences[ candidate ];
3153

3154
					}
3155

3156
				}
3157

3158 3159
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
3160

3161
				object.__webglMorphTargetInfluences[ m ] = candidateInfluence;
3162

3163 3164 3165
				used[ candidate ] = 1;
				candidateInfluence = -1;
				m ++;
3166 3167 3168 3169 3170

			}

		}

3171
		// load updated influences uniform
3172

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

3175
			_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
3176

3177
		}
3178

3179
	}
3180

3181
	// Frustum
M
Mr.doob 已提交
3182

3183
	function computeFrustum ( m ) {
M
Mr.doob 已提交
3184

3185 3186 3187 3188 3189 3190
		_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 );
3191

3192
		var i, plane;
3193

3194
		for ( i = 0; i < 6; i ++ ) {
3195

3196 3197
			plane = _frustum[ i ];
			plane.divideScalar( Math.sqrt( plane.x * plane.x + plane.y * plane.y + plane.z * plane.z ) );
3198 3199 3200

		}

3201
	};
M
Mr.doob 已提交
3202

3203
	function isInFrustum ( object ) {
3204

3205 3206
		var distance, matrix = object.matrixWorld,
		radius = - object.geometry.boundingSphere.radius * Math.max( object.scale.x, Math.max( object.scale.y, object.scale.z ) );
3207

3208
		for ( var i = 0; i < 6; i ++ ) {
3209

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

3213
		}
3214

3215
		return true;
3216

3217
	};
3218 3219


3220
	function painterSort ( a, b ) {
3221

3222
		return b.z - a.z;
3223

3224
	};
3225

3226
	// Rendering
3227

3228
	this.render = function ( scene, camera, renderTarget, forceClear ) {
3229

3230 3231 3232 3233
		var i, program, material,
			o, ol, oil, webglObject, object, buffer,
			lights = scene.lights,
			fog = scene.fog;
M
Mr.doob 已提交
3234

3235
		_currentMaterialId = -1;
3236

3237
		if ( this.autoUpdateObjects ) this.initWebGLObjects( scene );
3238

3239
		if ( this.shadowMapEnabled && this.shadowMapAutoUpdate ) renderShadowMap( scene, camera );
3240

3241 3242 3243
		_this.info.render.calls = 0;
		_this.info.render.vertices = 0;
		_this.info.render.faces = 0;
3244

3245
		if ( camera.parent === undefined ) {
3246

3247 3248
			console.warn( 'DEPRECATED: Camera hasn\'t been added to a Scene. Adding it...' );
			scene.add( camera );
3249

3250
		}
3251

3252
		if ( this.autoUpdateScene ) scene.updateMatrixWorld();
3253

3254 3255 3256
		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
		camera.matrixWorldInverse.flattenToArray( _viewMatrixArray );
		camera.projectionMatrix.flattenToArray( _projectionMatrixArray );
3257

3258 3259
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
		computeFrustum( _projScreenMatrix );
3260

3261
		setRenderTarget( renderTarget );
3262

3263
		if ( this.autoClear || forceClear ) {
3264

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

3267
		}
M
Mr.doob 已提交
3268

3269
		// set matrices
3270

3271
		ol = scene.__webglObjects.length;
3272

3273
		for ( o = 0; o < ol; o ++ ) {
3274

3275 3276
			webglObject = scene.__webglObjects[ o ];
			object = webglObject.object;
3277

3278
			if ( object.visible ) {
3279

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

3282
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
3283

3284
					setupMatrices( object, camera, true );
3285

3286
					unrollBufferMaterial( webglObject );
3287

3288
					webglObject.render = true;
3289

3290
					if ( this.sortObjects ) {
3291

3292
						if ( object.renderDepth ) {
3293

3294
							webglObject.z = object.renderDepth;
M
Mr.doob 已提交
3295

3296
						} else {
M
Mr.doob 已提交
3297

3298 3299
							_vector3.copy( object.position );
							_projScreenMatrix.multiplyVector3( _vector3 );
3300

3301
							webglObject.z = _vector3.z;
3302

3303
						}
M
Mr.doob 已提交
3304

3305
					}
M
Mr.doob 已提交
3306

3307
				} else {
3308

3309
					webglObject.render = false;
3310

3311
				}
3312

3313
			} else {
3314

3315
				webglObject.render = false;
3316 3317

			}
3318 3319 3320

		}

3321
		if ( this.sortObjects ) {
M
Mr.doob 已提交
3322

3323
			scene.__webglObjects.sort( painterSort );
3324

3325
		}
3326

3327
		oil = scene.__webglObjectsImmediate.length;
3328

3329
		for ( o = 0; o < oil; o ++ ) {
3330

3331 3332
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
3333

3334
			if ( object.visible ) {
3335

3336
				if( object.matrixAutoUpdate ) {
3337

3338
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3339

3340
				}
M
Mr.doob 已提交
3341

3342
				setupMatrices( object, camera, true );
M
Mr.doob 已提交
3343

3344
				unrollImmediateBufferMaterial( webglObject );
M
Mr.doob 已提交
3345

3346
			}
M
Mr.doob 已提交
3347

3348
		}
3349

3350
		if ( scene.overrideMaterial ) {
3351

3352 3353
			setDepthTest( scene.overrideMaterial.depthTest );
			setBlending( scene.overrideMaterial.blending );
3354

3355
			for ( o = 0; o < ol; o ++ ) {
3356

3357
				webglObject = scene.__webglObjects[ o ];
3358

3359
				if ( webglObject.render ) {
3360

3361 3362
					object = webglObject.object;
					buffer = webglObject.buffer;
3363

3364
					setObjectFaces( object );
M
Mr.doob 已提交
3365

3366
					renderBuffer( camera, lights, fog, scene.overrideMaterial, buffer, object );
3367

3368
				}
3369

3370
			}
M
Mr.doob 已提交
3371

3372
			for ( o = 0; o < oil; o ++ ) {
3373

3374 3375
				webglObject = scene.__webglObjectsImmediate[ o ];
				object = webglObject.object;
3376

3377
				if ( object.visible ) {
M
Mikael Emtinger 已提交
3378

3379
					_currentGeometryGroupHash = -1;
3380

3381
					setObjectFaces( object );
3382

3383
					program = setProgram( camera, lights, fog, scene.overrideMaterial, object );
3384

3385
					if ( object.immediateRenderCallback ) {
3386

3387
						object.immediateRenderCallback( program, _gl, _frustum );
3388

3389
					} else {
3390

3391
						object.render( function( object ) { renderBufferImmediate( object, program, scene.overrideMaterial.shading ); } );
M
Mr.doob 已提交
3392

3393
					}
M
Mr.doob 已提交
3394

3395
				}
M
Mr.doob 已提交
3396

3397
			}
M
Mr.doob 已提交
3398

3399
		} else {
3400

3401 3402
			// opaque pass
			// (front-to-back order)
3403

3404
			setBlending( THREE.NormalBlending );
3405

3406
			for ( o = ol - 1; o >= 0; o -- ) {
3407

3408
				webglObject = scene.__webglObjects[ o ];
3409

3410
				if ( webglObject.render ) {
3411

3412 3413 3414
					object = webglObject.object;
					buffer = webglObject.buffer;
					material = webglObject.opaque;
3415

3416 3417 3418 3419 3420 3421 3422 3423
					if ( ! material ) continue;

					setObjectFaces( object );

					setDepthTest( material.depthTest );
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
					renderBuffer( camera, lights, fog, material, buffer, object );
3424

3425
				}
3426

3427
			}
3428

3429
			// opaque pass (immediate simulator)
M
Mr.doob 已提交
3430

3431
			for ( o = 0; o < oil; o ++ ) {
M
Mr.doob 已提交
3432

3433 3434
				webglObject = scene.__webglObjectsImmediate[ o ];
				object = webglObject.object;
M
Mr.doob 已提交
3435

3436
				if ( object.visible ) {
M
Mr.doob 已提交
3437

3438
					_currentGeometryGroupHash = -1;
M
Mr.doob 已提交
3439

3440
					material = webglObject.opaque;
3441

3442
					if ( ! material ) continue;
3443

3444
					setObjectFaces( object );
3445

3446 3447 3448
					setDepthTest( material.depthTest );
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
3449

3450
					program = setProgram( camera, lights, fog, material, object );
M
Mr.doob 已提交
3451

3452
					if ( object.immediateRenderCallback ) {
3453

3454
						object.immediateRenderCallback( program, _gl, _frustum );
3455

3456
					} else {
3457

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

3460
					}
3461 3462 3463 3464 3465

				}

			}

3466 3467
			// transparent pass
			// (back-to-front order)
3468

3469
			for ( o = 0; o < ol; o ++ ) {
M
Mr.doob 已提交
3470

3471
				webglObject = scene.__webglObjects[ o ];
3472

3473
				if ( webglObject.render ) {
M
Mr.doob 已提交
3474

3475 3476 3477
					object = webglObject.object;
					buffer = webglObject.buffer;
					material = webglObject.transparent;
3478

3479
					if ( ! material ) continue;
M
Mr.doob 已提交
3480

3481
					setObjectFaces( object );
3482

3483 3484 3485 3486
					setBlending( material.blending );
					setDepthTest( material.depthTest );
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
3487

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

3490
				}
3491

3492
			}
3493

3494
			// transparent pass (immediate simulator)
M
Mr.doob 已提交
3495

3496
			for ( o = 0; o < oil; o ++ ) {
3497

3498 3499
				webglObject = scene.__webglObjectsImmediate[ o ];
				object = webglObject.object;
M
Mr.doob 已提交
3500

3501
				if ( object.visible ) {
M
Mr.doob 已提交
3502

3503
					_currentGeometryGroupHash = -1;
M
Mr.doob 已提交
3504

3505
					material = webglObject.transparent;
M
Mr.doob 已提交
3506

3507
					if ( ! material ) continue;
M
Mr.doob 已提交
3508

3509
					setObjectFaces( object );
3510

3511 3512 3513 3514
					setBlending( material.blending );
					setDepthTest( material.depthTest );
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
M
Mr.doob 已提交
3515

3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528
					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 ); } );

					}

				}
3529

M
Mr.doob 已提交
3530
			}
3531

3532
		}
3533

3534
		// render 2d
M
Mr.doob 已提交
3535

3536
		if ( scene.__webglSprites.length ) {
M
Mr.doob 已提交
3537

3538
			renderSprites( scene, camera );
M
Mr.doob 已提交
3539

3540
		}
3541

3542
		// Generate mipmap if we're using any kind of mipmap filtering
3543

3544
		if ( renderTarget && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {
3545

3546
			updateRenderTargetMipmap( renderTarget );
3547

3548
		}
3549

3550
		//_gl.finish();
3551

3552
	};
3553

3554
	function renderShadowMap ( scene, camera ) {
3555

3556 3557 3558 3559 3560 3561 3562 3563 3564
		var i, il, light,
			j = 0,
			shadowMap, shadowMatrix,
			oil,
			material,
			program, buffer,
			o, ol, webglObject, object,
			lights = scene.lights,
			fog = null;
3565

3566
		if ( ! _cameraLight ) {
3567

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

3570
		}
3571

3572
		for ( i = 0, il = lights.length; i < il; i ++ ) {
3573

3574
			light = lights[ i ];
M
Mr.doob 已提交
3575

3576
			if ( light instanceof THREE.SpotLight && light.castShadow ) {
M
Mr.doob 已提交
3577

3578
				_currentMaterialId = -1;
3579

3580
				if ( ! _this.shadowMap[ j ] ) {
3581

3582 3583
					var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
					_this.shadowMap[ j ] = new THREE.WebGLRenderTarget( _this.shadowMapWidth, _this.shadowMapHeight, pars );
3584

3585 3586 3587 3588 3589
				}

				if ( ! _shadowMatrix[ j ] ) {

					_shadowMatrix[ j ] = new THREE.Matrix4();
M
Mr.doob 已提交
3590

M
Mr.doob 已提交
3591
				}
M
Mr.doob 已提交
3592

3593 3594
				shadowMap = _this.shadowMap[ j ];
				shadowMatrix = _shadowMatrix[ j ];
3595

3596 3597
				_cameraLight.position.copy( light.position );
				_cameraLight.lookAt( light.target.position );
3598

3599
				if ( _cameraLight.parent == null ) {
3600

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

M
Mr.doob 已提交
3604 3605
				}

3606
				if ( this.autoUpdateScene ) scene.updateMatrixWorld();
M
Mr.doob 已提交
3607

3608
				_cameraLight.matrixWorldInverse.getInverse( _cameraLight.matrixWorld );
M
Mr.doob 已提交
3609

3610
				// compute shadow matrix
M
Mr.doob 已提交
3611

3612 3613 3614 3615
				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 );
3616

3617 3618
				shadowMatrix.multiplySelf( _cameraLight.projectionMatrix );
				shadowMatrix.multiplySelf( _cameraLight.matrixWorldInverse );
3619

3620
				// render shadow map
M
Mr.doob 已提交
3621

3622 3623
				_cameraLight.matrixWorldInverse.flattenToArray( _viewMatrixArray );
				_cameraLight.projectionMatrix.flattenToArray( _projectionMatrixArray );
M
Mr.doob 已提交
3624

3625 3626
				_projScreenMatrix.multiply( _cameraLight.projectionMatrix, _cameraLight.matrixWorldInverse );
				computeFrustum( _projScreenMatrix );
M
Mr.doob 已提交
3627

3628
				setRenderTarget( shadowMap );
3629

3630 3631
				// using arbitrary clear color in depth pass
				// creates variance in shadows
3632

3633 3634
				_gl.clearColor( 1, 1, 1, 1 );
				//_gl.clearColor( 0, 0, 0, 1 );
3635

3636
				_this.clear();
3637

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

A
alteredq 已提交
3640

3641
				// set matrices & frustum culling
3642

3643 3644
				ol = scene.__webglObjects.length;
				oil = scene.__webglObjectsImmediate.length;
A
alteredq 已提交
3645

3646
				for ( o = 0; o < ol; o ++ ) {
3647

3648 3649
					webglObject = scene.__webglObjects[ o ];
					object = webglObject.object;
M
Mr.doob 已提交
3650

3651
					if ( object.visible && object.castShadow ) {
M
Mr.doob 已提交
3652

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

3655
							object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3656

3657
							setupMatrices( object, _cameraLight, false );
M
Mr.doob 已提交
3658

3659
							webglObject.render = true;
M
Mr.doob 已提交
3660

3661
						} else {
3662

3663
							webglObject.render = false;
M
Mr.doob 已提交
3664

3665
						}
M
Mr.doob 已提交
3666

3667
					} else {
3668

3669
						webglObject.render = false;
3670

3671
					}
3672

3673
				}
3674

3675 3676
				setDepthTest( true );
				setBlending( THREE.NormalBlending ); // maybe blending should be just disabled?
3677

3678
				//_gl.cullFace( _gl.FRONT );
3679

3680
				for ( o = 0; o < ol; o ++ ) {
3681

3682
					webglObject = scene.__webglObjects[ o ];
3683

3684
					if ( webglObject.render ) {
3685

3686 3687
						object = webglObject.object;
						buffer = webglObject.buffer;
M
Mr.doob 已提交
3688

3689
						setObjectFaces( object );
M
Mr.doob 已提交
3690

3691
						if ( object.customDepthMaterial ) {
M
Mr.doob 已提交
3692

3693
							material =  object.customDepthMaterial;
M
Mr.doob 已提交
3694

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

3697
							material =  _depthMaterialMorph;
M
Mr.doob 已提交
3698

3699
						} else {
M
Mr.doob 已提交
3700

3701
							material = _depthMaterial;
M
Mr.doob 已提交
3702

3703
						}
M
Mr.doob 已提交
3704

3705
						renderBuffer( _cameraLight, lights, fog, material, buffer, object );
3706

3707
					}
3708

3709
				}
A
alteredq 已提交
3710 3711


3712
				for ( o = 0; o < oil; o ++ ) {
A
alteredq 已提交
3713

3714 3715
					webglObject = scene.__webglObjectsImmediate[ o ];
					object = webglObject.object;
A
alteredq 已提交
3716

3717
					if ( object.visible && object.castShadow ) {
M
Mr.doob 已提交
3718

3719
						if( object.matrixAutoUpdate ) {
3720

3721
							object.matrixWorld.flattenToArray( object._objectMatrixArray );
3722

3723
						}
3724

3725
						_currentGeometryGroupHash = -1;
3726

3727
						setupMatrices( object, _cameraLight, false );
3728

3729
						setObjectFaces( object );
3730

3731
						program = setProgram( _cameraLight, lights, fog, _depthMaterial, object );
3732

3733
						if ( object.immediateRenderCallback ) {
M
Mr.doob 已提交
3734

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

3737
						} else {
3738

3739
							object.render( function( object ) { renderBufferImmediate( object, program, _depthMaterial.shading ); } );
3740

3741
						}
3742

3743
					}
3744

M
Mr.doob 已提交
3745
				}
M
Mr.doob 已提交
3746

3747
				//_gl.cullFace( _gl.BACK );
3748

3749
				j ++;
3750

3751
			}
3752

3753
		}
3754

3755
	};
3756

3757
	function unrollImmediateBufferMaterial ( globject ) {
3758

3759 3760
		var object = globject.object,
			material = object.material;
3761

3762
		if ( material.transparent ) {
3763

3764 3765
			globject.transparent = material;
			globject.opaque = null;
3766

3767
		} else {
3768

3769 3770
			globject.opaque = material;
			globject.transparent = null;
3771

3772
		}
A
alteredq 已提交
3773

3774
	};
A
alteredq 已提交
3775

3776
	function unrollBufferMaterial ( globject ) {
A
alteredq 已提交
3777

3778 3779 3780
		var object = globject.object,
			buffer = globject.buffer,
			material, materialIndex, meshMaterial;
3781

3782
		meshMaterial = object.material;
3783

3784
		if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
M
Mr.doob 已提交
3785

3786
			materialIndex = buffer.materialIndex;
3787

3788
			if ( materialIndex >= 0 ) {
3789

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

3792
				if ( material.transparent ) {
M
Mr.doob 已提交
3793

3794 3795
					globject.transparent = material;
					globject.opaque = null;
3796

3797
				} else {
3798

3799 3800
					globject.opaque = material;
					globject.transparent = null;
3801

3802
				}
3803

3804
			}
3805

3806
		} else {
3807

3808
			material = meshMaterial;
3809

3810
			if ( material ) {
3811

3812
				if ( material.transparent ) {
M
Mr.doob 已提交
3813

3814 3815
					globject.transparent = material;
					globject.opaque = null;
A
alteredq 已提交
3816

3817
				} else {
3818

3819 3820
					globject.opaque = material;
					globject.transparent = null;
3821

3822
				}
3823

3824
			}
3825

3826
		}
3827

3828
	};
3829

3830
	function renderSprites ( scene, camera ) {
3831

3832 3833 3834 3835 3836 3837 3838 3839 3840
		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;
3841

3842
		// setup gl
3843

3844 3845 3846 3847 3848
		_gl.useProgram( _sprite.program );
		_currentProgram = _sprite.program;
		_oldBlending = -1;
		_oldDepthTest = -1;
		_currentGeometryGroupHash = -1;
3849

3850
		if ( !_spriteAttributesEnabled ) {
3851

3852 3853
			_gl.enableVertexAttribArray( _sprite.attributes.position );
			_gl.enableVertexAttribArray( _sprite.attributes.uv );
3854

3855
			_spriteAttributesEnabled = true;
3856

3857
		}
3858

3859 3860 3861
		_gl.disable( _gl.CULL_FACE );
		_gl.enable( _gl.BLEND );
		_gl.depthMask( true );
3862

3863 3864 3865
		_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 );
3866

3867
		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _sprite.elementBuffer );
3868

3869
		_gl.uniformMatrix4fv( uniforms.projectionMatrix, false, _projectionMatrixArray );
3870

3871 3872
		_gl.activeTexture( _gl.TEXTURE0 );
		_gl.uniform1i( uniforms.map, 0 );
3873

3874
		// update positions and sort
3875

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

3878
			object = scene.__webglSprites[ o ];
3879

3880
			if ( !object.visible || object.opacity === 0 ) continue;
3881

3882
			if( !object.useScreenCoordinates ) {
3883

3884 3885
				object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
				object.z = -object._modelViewMatrix.n34;
M
Mikael Emtinger 已提交
3886

3887 3888 3889
			} else {

				object.z = -object.position.z;
3890 3891

			}
3892

3893
		}
3894

3895
		scene.__webglSprites.sort( painterSort );
3896

3897
		// render all sprites
3898

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

3901
			object = scene.__webglSprites[ o ];
3902

3903
			if ( !object.visible || object.opacity === 0 ) continue;
3904

3905
			if ( object.map && object.map.image && object.map.image.width ) {
3906

3907
				if ( object.useScreenCoordinates ) {
3908

3909 3910 3911 3912
					_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 )));
3913

3914
				} else {
3915

3916 3917 3918
					_gl.uniform1i( uniforms.useScreenCoordinates, 0 );
					_gl.uniform1i( uniforms.affectedByDistance, object.affectedByDistance ? 1 : 0 );
					_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
3919

M
Mikael Emtinger 已提交
3920
				}
3921

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

3924 3925
				scale[ 0 ] = size * invAspect * object.scale.x;
				scale[ 1 ] = size * object.scale.y;
3926

3927 3928 3929
				_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 已提交
3930

3931 3932
				_gl.uniform1f( uniforms.opacity, object.opacity );
				_gl.uniform3f( uniforms.color, object.color.r, object.color.g, object.color.b );
3933

3934 3935
				_gl.uniform1f( uniforms.rotation, object.rotation );
				_gl.uniform2fv( uniforms.scale, scale );
M
Mr.doob 已提交
3936

3937
				if ( object.mergeWith3D && !mergeWith3D ) {
M
Mr.doob 已提交
3938

3939 3940
					_gl.enable( _gl.DEPTH_TEST );
					mergeWith3D = true;
3941

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

3944 3945
					_gl.disable( _gl.DEPTH_TEST );
					mergeWith3D = false;
M
Mikael Emtinger 已提交
3946

3947
				}
3948

3949 3950
				setBlending( object.blending );
				setTexture( object.map, 0 );
3951

3952
				_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
3953

3954
			}
3955

A
alteredq 已提交
3956
		}
3957 3958


3959
		// restore gl
3960

3961 3962 3963
		_gl.enable( _gl.CULL_FACE );
		_gl.enable( _gl.DEPTH_TEST );
		_gl.depthMask( _oldDepthWrite );
3964

3965
	}
3966

3967
	// Geometry splitting
3968

3969
	function sortFacesByMaterial ( geometry ) {
3970

3971 3972 3973
		var f, fl, face, materialIndex, vertices,
			materialHash, groupHash,
			hash_map = {};
3974

3975
		var numMorphTargets = geometry.morphTargets.length;
3976

3977
		geometry.geometryGroups = {};
3978

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

3981 3982
			face = geometry.faces[ f ];
			materialIndex = face.materialIndex;
3983

3984
			materialHash = ( materialIndex !== undefined ) ? materialIndex : -1;
3985

3986
			if ( hash_map[ materialHash ] === undefined ) {
3987

3988
				hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 };
3989 3990 3991

			}

3992
			groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
3993

3994
			if ( geometry.geometryGroups[ groupHash ] === undefined ) {
3995

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

3998
			}
A
alteredq 已提交
3999

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

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

4004 4005
				hash_map[ materialHash ].counter += 1;
				groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
A
alteredq 已提交
4006

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

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

4011
				}
4012

4013
			}
4014

4015
			if ( face instanceof THREE.Face3 ) {
4016

4017
				geometry.geometryGroups[ groupHash ].faces3.push( f );
4018

4019
			} else {
4020

4021
				geometry.geometryGroups[ groupHash ].faces4.push( f );
4022

A
alteredq 已提交
4023
			}
4024

4025
			geometry.geometryGroups[ groupHash ].vertices += vertices;
4026

4027
		}
4028

4029
		geometry.geometryGroupsList = [];
4030

4031
		for ( var g in geometry.geometryGroups ) {
4032

4033
			geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;
4034

4035
			geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );
4036

4037
		}
4038

4039
	};
4040

4041 4042 4043 4044 4045 4046 4047 4048 4049
	// Objects refresh

	this.initWebGLObjects = function ( scene ) {

		if ( !scene.__webglObjects ) {

			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
			scene.__webglSprites = [];
4050 4051

		}
4052

4053
		while ( scene.__objectsAdded.length ) {
4054

4055 4056
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
4057

4058
		}
A
alteredq 已提交
4059

4060
		while ( scene.__objectsRemoved.length ) {
4061

4062 4063
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
4064

4065
		}
4066

4067
		// update must be called after objects adding / removal
4068

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

4071
			updateObject( scene.__webglObjects[ o ].object );
M
Mr.doob 已提交
4072 4073 4074 4075 4076

		}

	};

4077
	// Objects adding
M
Mr.doob 已提交
4078

4079
	function addObject ( object, scene ) {
A
alteredq 已提交
4080

4081
		var g, geometry, geometryGroup;
4082

4083
		if ( ! object.__webglInit ) {
M
Mr.doob 已提交
4084

4085
			object.__webglInit = true;
M
Mr.doob 已提交
4086

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

4089 4090 4091
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
M
Mr.doob 已提交
4092

4093
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
4094

4095
			if ( object instanceof THREE.Mesh ) {
M
Mr.doob 已提交
4096

4097
				geometry = object.geometry;
M
Mr.doob 已提交
4098

4099
				if ( geometry.geometryGroups === undefined ) {
M
Mr.doob 已提交
4100

4101
					sortFacesByMaterial( geometry );
M
Mr.doob 已提交
4102

4103
				}
M
Mr.doob 已提交
4104

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

4107
				for ( g in geometry.geometryGroups ) {
M
Mr.doob 已提交
4108

4109
					geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
4110

4111
					// initialise VBO on the first access
M
Mr.doob 已提交
4112

4113
					if ( ! geometryGroup.__webglVertexBuffer ) {
4114

4115 4116
						createMeshBuffers( geometryGroup );
						initMeshBuffers( geometryGroup, object );
M
Mr.doob 已提交
4117

4118 4119 4120 4121 4122 4123 4124
						geometry.__dirtyVertices = true;
						geometry.__dirtyMorphTargets = true;
						geometry.__dirtyElements = true;
						geometry.__dirtyUvs = true;
						geometry.__dirtyNormals = true;
						geometry.__dirtyTangents = true;
						geometry.__dirtyColors = true;
M
Mr.doob 已提交
4125

4126
					}
M
Mr.doob 已提交
4127

4128
				}
M
Mr.doob 已提交
4129

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

4132
				geometry = object.geometry;
M
Mr.doob 已提交
4133

4134
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
4135

4136 4137
					createRibbonBuffers( geometry );
					initRibbonBuffers( geometry );
M
Mr.doob 已提交
4138

4139 4140
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
4141

4142
				}
M
Mr.doob 已提交
4143

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

4146
				geometry = object.geometry;
M
Mr.doob 已提交
4147

4148
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
4149

4150 4151
					createLineBuffers( geometry );
					initLineBuffers( geometry, object );
M
Mr.doob 已提交
4152

4153 4154
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
4155

4156
				}
4157

4158
			} else if ( object instanceof THREE.ParticleSystem ) {
4159

4160
				geometry = object.geometry;
4161

4162
				if ( ! geometry.__webglVertexBuffer ) {
4163

4164 4165
					createParticleBuffers( geometry );
					initParticleBuffers( geometry, object );
4166

4167 4168
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
4169

4170
				}
4171

4172
			}
4173

4174
		}
4175

4176
		if ( ! object.__webglActive ) {
4177

4178
			if ( object instanceof THREE.Mesh ) {
4179

4180
				geometry = object.geometry;
4181

4182
				for ( g in geometry.geometryGroups ) {
4183

4184
					geometryGroup = geometry.geometryGroups[ g ];
4185

4186
					addBuffer( scene.__webglObjects, geometryGroup, object );
4187

4188
				}
4189

4190 4191 4192
			} else if ( object instanceof THREE.Ribbon ||
						object instanceof THREE.Line ||
						object instanceof THREE.ParticleSystem ) {
4193

4194 4195
				geometry = object.geometry;
				addBuffer( scene.__webglObjects, geometry, object );
4196

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

4199
				addBufferImmediate( scene.__webglObjectsImmediate, object );
4200

4201
			} else if ( object instanceof THREE.Sprite ) {
4202

4203
				scene.__webglSprites.push( object );
4204

4205 4206
			}

4207
			object.__webglActive = true;
4208

4209
		}
4210

4211
	};
4212

4213
	function addBuffer ( objlist, buffer, object ) {
4214

4215 4216 4217 4218 4219 4220 4221 4222
		objlist.push(
			{
				buffer: buffer,
				object: object,
				opaque: null,
				transparent: null
			}
		);
4223

4224
	};
4225

4226
	function addBufferImmediate ( objlist, object ) {
4227

4228 4229 4230 4231 4232
		objlist.push(
			{
				object: object,
				opaque: null,
				transparent: null
4233
			}
4234
		);
4235

4236
	};
4237

4238
	// Objects updates
4239

4240
	function updateObject ( object ) {
4241

4242 4243
		var geometry = object.geometry,
			geometryGroup, customAttributesDirty, material;
4244

4245
		if ( object instanceof THREE.Mesh ) {
4246

4247
			// check all geometry groups
4248

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

4251
				geometryGroup = geometry.geometryGroupsList[ i ];
4252

4253
				material = getBufferMaterial( object, geometryGroup );
4254

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

4257 4258 4259
				if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
					 geometry.__dirtyUvs || geometry.__dirtyNormals ||
					 geometry.__dirtyColors || geometry.__dirtyTangents || customAttributesDirty ) {
4260

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

4263
				}
M
Mr.doob 已提交
4264

4265
			}
4266

4267 4268 4269 4270 4271 4272 4273
			geometry.__dirtyVertices = false;
			geometry.__dirtyMorphTargets = false;
			geometry.__dirtyElements = false;
			geometry.__dirtyUvs = false;
			geometry.__dirtyNormals = false;
			geometry.__dirtyColors = false;
			geometry.__dirtyTangents = false;
4274

4275
			material.attributes && clearCustomAttributes( material );
4276

4277
		} else if ( object instanceof THREE.Ribbon ) {
4278

4279
			if ( geometry.__dirtyVertices || geometry.__dirtyColors ) {
4280

4281
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
4282

4283
			}
4284

4285 4286
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
4287

4288
		} else if ( object instanceof THREE.Line ) {
4289

4290
			material = getBufferMaterial( object, geometryGroup );
A
alteredq 已提交
4291

4292
			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
A
alteredq 已提交
4293

4294
			if ( geometry.__dirtyVertices ||  geometry.__dirtyColors || customAttributesDirty ) {
A
alteredq 已提交
4295

4296
				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
4297

4298
			}
4299

4300 4301
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
4302

4303
			material.attributes && clearCustomAttributes( material );
4304

4305
		} else if ( object instanceof THREE.ParticleSystem ) {
4306

4307
			material = getBufferMaterial( object, geometryGroup );
4308

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

4311
			if ( geometry.__dirtyVertices || geometry.__dirtyColors || object.sortParticles || customAttributesDirty ) {
4312

4313
				setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
4314

4315
			}
4316

4317 4318
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
4319

4320
			material.attributes && clearCustomAttributes( material );
4321

4322
		}
4323

4324
	};
4325

4326
	// Objects updates - custom attributes check
4327

4328
	function areCustomAttributesDirty ( material ) {
4329

4330
		for ( var a in material.attributes ) {
4331

4332
			if ( material.attributes[ a ].needsUpdate ) return true;
4333

4334
		}
4335

4336
		return false;
4337

4338
	};
4339

4340 4341 4342
	function clearCustomAttributes ( material ) {

		for ( var a in material.attributes ) {
4343

4344
			material.attributes[ a ].needsUpdate = false;
4345

4346
		}
4347

4348
	};
4349

4350
	// Objects removal
4351

4352
	function removeObject ( object, scene ) {
4353

4354 4355 4356 4357
		if ( object instanceof THREE.Mesh  ||
			 object instanceof THREE.ParticleSystem ||
			 object instanceof THREE.Ribbon ||
			 object instanceof THREE.Line ) {
4358

4359
			removeInstances( scene.__webglObjects, object );
4360

4361
		} else if ( object instanceof THREE.Sprite ) {
4362

4363
			removeInstancesDirect( scene.__webglSprites, object );
4364

4365
		} else if ( object instanceof THREE.MarchingCubes || object.immediateRenderCallback ) {
4366

4367
			removeInstances( scene.__webglObjectsImmediate, object );
4368

4369
		}
4370

4371
		object.__webglActive = false;
4372

4373
	};
4374

4375
	function removeInstances ( objlist, object ) {
4376

4377
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4378

4379
			if ( objlist[ o ].object === object ) {
4380

4381
				objlist.splice( o, 1 );
4382

4383
			}
4384

4385
		}
4386

4387
	};
4388

4389
	function removeInstancesDirect ( objlist, object ) {
4390

4391
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4392

4393
			if ( objlist[ o ] === object ) {
4394

4395
				objlist.splice( o, 1 );
4396

4397
			}
4398

4399
		}
4400

4401
	};
4402

4403
	// Materials
4404

4405
	this.initMaterial = function ( material, lights, fog, object ) {
4406

4407
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
4408

4409
		if ( material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
4410

4411
			shaderID = 'depth';
4412

4413
		} else if ( material instanceof THREE.MeshNormalMaterial ) {
4414

4415
			shaderID = 'normal';
M
Mr.doob 已提交
4416

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

4419
			shaderID = 'basic';
M
Mr.doob 已提交
4420

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

4423
			shaderID = 'lambert';
M
Mr.doob 已提交
4424

4425
		} else if ( material instanceof THREE.MeshPhongMaterial ) {
4426

4427
			shaderID = 'phong';
4428

4429
		} else if ( material instanceof THREE.LineBasicMaterial ) {
4430

4431
			shaderID = 'basic';
4432

4433
		} else if ( material instanceof THREE.ParticleBasicMaterial ) {
4434

4435
			shaderID = 'particle_basic';
4436 4437 4438

		}

4439
		if ( shaderID ) {
4440

4441
			setMaterialShaders( material, THREE.ShaderLib[ shaderID ] );
4442

4443
		}
4444

4445 4446
		// heuristics to create shader parameters according to lights in the scene
		// (not to blow over maxLights budget)
4447

4448
		maxLightCount = allocateLights( lights );
4449

4450
		maxShadows = allocateShadows( lights );
4451

4452
		maxBones = allocateBones( object );
4453

4454
		parameters = {
4455

4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472
			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
4473

4474
		};
M
Mr.doob 已提交
4475

4476
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
4477

4478
		var attributes = material.program.attributes;
4479

4480 4481 4482 4483
		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 );
4484

4485 4486 4487
		if ( material.skinning &&
			 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
M
Mr.doob 已提交
4488

4489 4490 4491 4492
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
M
Mr.doob 已提交
4493 4494

		}
4495

4496
		if ( material.attributes ) {
A
alteredq 已提交
4497

4498
			for ( a in material.attributes ) {
M
Mr.doob 已提交
4499

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

4502
			}
M
Mr.doob 已提交
4503

4504
		}
M
Mr.doob 已提交
4505

4506
		if ( material.morphTargets ) {
M
Mr.doob 已提交
4507

4508
			material.numSupportedMorphTargets = 0;
4509

4510
			var id, base = "morphTarget";
4511

4512
			for ( i = 0; i < this.maxMorphTargets; i ++ ) {
4513

4514
				id = base + i;
M
Mr.doob 已提交
4515

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

4518 4519
					_gl.enableVertexAttribArray( attributes[ id ] );
					material.numSupportedMorphTargets ++;
4520

4521
				}
4522

4523
			}
4524

4525
		}
4526

4527
		material.uniformsList = [];
4528

4529
		for ( u in material.uniforms ) {
4530

4531
			material.uniformsList.push( [ material.uniforms[ u ], u ] );
4532

4533
		}
M
Mr.doob 已提交
4534

4535
	};
M
Mr.doob 已提交
4536

4537
	function setMaterialShaders ( material, shaders ) {
M
Mr.doob 已提交
4538

4539 4540 4541
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
M
Mr.doob 已提交
4542

4543
	};
M
Mr.doob 已提交
4544

4545
	function setProgram ( camera, lights, fog, material, object ) {
4546

4547
		if ( ! material.program ) {
4548

4549
			_this.initMaterial( material, lights, fog, object );
4550

4551
		}
4552

4553
		if ( material.morphTargets ) {
4554

4555
			if ( ! object.__webglMorphTargetInfluences ) {
4556

4557
				object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );
4558

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

4561
					object.__webglMorphTargetInfluences[ i ] = 0;
4562

4563
				}
4564

4565
			}
4566

4567
		}
4568

4569
		var refreshMaterial = false;
4570

4571 4572 4573
		var program = material.program,
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
4574

4575
		if ( program !== _currentProgram ) {
4576

4577 4578
			_gl.useProgram( program );
			_currentProgram = program;
4579

4580
			refreshMaterial = true;
4581

4582
		}
4583

4584
		if ( material.id !== _currentMaterialId ) {
4585

4586 4587
			_currentMaterialId = material.id;
			refreshMaterial = true;
4588

4589
		}
4590

4591
		if ( refreshMaterial ) {
4592

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

4595
			// refresh uniforms common to several materials
4596

4597
			if ( fog && material.fog ) {
4598

4599
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
4600

4601
			}
M
Mr.doob 已提交
4602

4603 4604 4605
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material.lights ) {
4606

4607 4608
				setupLights( program, lights );
				refreshUniformsLights( m_uniforms, _lights );
4609

4610
			}
M
Mr.doob 已提交
4611

4612 4613 4614
			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
4615

4616
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
4617 4618 4619

			}

4620
			// refresh single material specific uniforms
M
Mr.doob 已提交
4621

4622
			if ( material instanceof THREE.LineBasicMaterial ) {
4623

4624
				refreshUniformsLine( m_uniforms, material );
M
Mr.doob 已提交
4625

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

4628
				refreshUniformsParticle( m_uniforms, material );
M
Mr.doob 已提交
4629

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

4632
				refreshUniformsPhong( m_uniforms, material );
M
Mr.doob 已提交
4633

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

4636
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
4637

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

4640 4641 4642
				m_uniforms.mNear.value = camera.near;
				m_uniforms.mFar.value = camera.far;
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4643

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

4646
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4647

4648
			}
M
Mr.doob 已提交
4649

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

4652
				refreshUniformsShadow( m_uniforms, material );
M
Mr.doob 已提交
4653

4654
			}
M
Mr.doob 已提交
4655

4656
			// load common uniforms
M
Mr.doob 已提交
4657

4658
			loadUniformsGeneric( program, material.uniformsList );
M
Mr.doob 已提交
4659

4660 4661
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)
4662

4663 4664 4665
			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
				 material.envMap ) {
4666

4667
				if( p_uniforms.cameraPosition !== null ) {
4668

4669
					_gl.uniform3f( p_uniforms.cameraPosition, camera.position.x, camera.position.y, camera.position.z );
4670

4671
				}
4672 4673 4674

			}

4675 4676 4677 4678
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {
4679

4680
				if( p_uniforms.viewMatrix !== null ) {
4681

4682
					_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
4683

4684
				}
4685

4686
			}
M
Mr.doob 已提交
4687

4688
			if ( material.skinning ) {
4689

4690
				loadUniformsSkinning( p_uniforms, object );
4691

4692
			}
4693

4694
		}
M
Mr.doob 已提交
4695

4696
		loadUniformsMatrices( p_uniforms, object );
M
Mr.doob 已提交
4697

4698 4699 4700 4701
		if ( material instanceof THREE.ShaderMaterial ||
			 material.envMap ||
			 material.skinning ||
			 object.receiveShadow ) {
M
Mr.doob 已提交
4702

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

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

4707
			}
4708

4709
		}
4710

4711
		return program;
4712

4713
	};
4714

4715
	// Uniforms (refresh uniforms objects)
A
alteredq 已提交
4716

4717
	function refreshUniformsCommon ( uniforms, material ) {
4718

4719
		uniforms.opacity.value = material.opacity;
4720

4721
		if ( _this.gammaInput ) {
4722

4723
			uniforms.diffuse.value.copyGammaToLinear( material.color );
4724

4725
		} else {
4726

4727
			uniforms.diffuse.value = material.color;
4728

4729
		}
4730

4731
		uniforms.map.texture = material.map;
4732

4733
		if ( material.map ) {
4734

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

4737
		}
M
Mr.doob 已提交
4738

4739
		uniforms.lightMap.texture = material.lightMap;
4740

4741 4742
		uniforms.envMap.texture = material.envMap;
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
4743

4744
		if ( _this.gammaInput ) {
4745

4746 4747
			//uniforms.reflectivity.value = material.reflectivity * material.reflectivity;
			uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
4748

4749
		} else {
4750

4751
			uniforms.reflectivity.value = material.reflectivity;
4752

4753
		}
4754

4755 4756 4757
		uniforms.refractionRatio.value = material.refractionRatio;
		uniforms.combine.value = material.combine;
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
M
Mr.doob 已提交
4758

4759
	};
M
Mr.doob 已提交
4760

4761
	function refreshUniformsLine ( uniforms, material ) {
M
Mr.doob 已提交
4762

4763 4764
		uniforms.diffuse.value = material.color;
		uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4765

4766
	};
M
Mr.doob 已提交
4767

4768
	function refreshUniformsParticle ( uniforms, material ) {
4769

4770 4771 4772 4773
		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.
4774

4775
		uniforms.map.texture = material.map;
4776

4777
	};
4778

4779
	function refreshUniformsFog ( uniforms, fog ) {
4780

4781
		uniforms.fogColor.value = fog.color;
4782

4783
		if ( fog instanceof THREE.Fog ) {
4784

4785 4786
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
4787

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

4790
			uniforms.fogDensity.value = fog.density;
M
Mikael Emtinger 已提交
4791

4792
		}
M
Mikael Emtinger 已提交
4793

4794
	};
M
Mikael Emtinger 已提交
4795

4796
	function refreshUniformsPhong ( uniforms, material ) {
M
Mikael Emtinger 已提交
4797

4798
		uniforms.shininess.value = material.shininess;
4799

4800
		if ( _this.gammaInput ) {
M
Mikael Emtinger 已提交
4801

4802 4803
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
			uniforms.specular.value.copyGammaToLinear( material.specular );
4804

4805
		} else {
4806

4807 4808
			uniforms.ambient.value = material.ambient;
			uniforms.specular.value = material.specular;
4809

4810
		}
4811

4812
	};
4813

4814
	function refreshUniformsLambert ( uniforms, material ) {
4815

4816
		if ( _this.gammaInput ) {
4817

4818
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
M
Mr.doob 已提交
4819

4820
		} else {
4821

4822
			uniforms.ambient.value = material.ambient;
4823

4824
		}
4825

4826
	};
4827

4828
	function refreshUniformsLights ( uniforms, lights ) {
4829

4830
		uniforms.ambientLightColor.value = lights.ambient;
4831

4832 4833
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
4834

4835 4836 4837
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
		uniforms.pointLightDistance.value = lights.point.distances;
4838

4839
	};
4840

4841
	function refreshUniformsShadow ( uniforms, material ) {
M
Mr.doob 已提交
4842

4843
		if ( uniforms.shadowMatrix ) {
4844

4845
			for ( var i = 0; i < _shadowMatrix.length; i ++ ) {
4846

4847 4848
				uniforms.shadowMatrix.value[ i ] = _shadowMatrix[ i ];
				uniforms.shadowMap.texture[ i ] = _this.shadowMap[ i ];
4849 4850


4851
			}
4852

4853 4854 4855
			uniforms.shadowDarkness.value = _this.shadowMapDarkness;
			uniforms.shadowBias.value = _this.shadowMapBias;

4856 4857
		}

4858
	};
4859

4860
	// Uniforms (load to GPU)
4861

4862
	function loadUniformsSkinning ( uniforms, object ) {
4863

4864 4865
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray );
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
4866

4867
	};
4868

4869

4870
	function loadUniformsMatrices ( uniforms, object ) {
4871

4872
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
4873

4874
		if ( uniforms.normalMatrix ) {
4875

4876
			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );
4877

4878
		}
4879

4880
	};
4881

4882
	function loadUniformsGeneric ( program, uniforms ) {
4883

4884
		var uniform, value, type, location, texture, i, il, j, jl, offset;
4885

4886
		for( j = 0, jl = uniforms.length; j < jl; j ++ ) {
4887

4888 4889
			location = program.uniforms[ uniforms[ j ][ 1 ] ];
			if ( !location ) continue;
4890

4891
			uniform = uniforms[ j ][ 0 ];
4892

4893 4894
			type = uniform.type;
			value = uniform.value;
4895

4896
			// single integer
4897

4898
			if( type === "i" ) {
4899

4900
				_gl.uniform1i( location, value );
4901

4902
			// single float
4903

4904
			} else if( type === "f" ) {
4905

4906
				_gl.uniform1f( location, value );
4907

4908
			// single THREE.Vector2
4909

4910
			} else if( type === "v2" ) {
4911

4912
				_gl.uniform2f( location, value.x, value.y );
4913

4914
			// single THREE.Vector3
4915

4916
			} else if( type === "v3" ) {
4917

4918
				_gl.uniform3f( location, value.x, value.y, value.z );
4919

4920
			// single THREE.Vector4
4921

4922
			} else if( type === "v4" ) {
4923

4924
				_gl.uniform4f( location, value.x, value.y, value.z, value.w );
4925

4926
			// single THREE.Color
4927

4928
			} else if( type === "c" ) {
4929

4930
				_gl.uniform3f( location, value.r, value.g, value.b );
4931

4932
			// flat array of floats (JS or typed array)
4933

4934
			} else if( type === "fv1" ) {
4935

4936
				_gl.uniform1fv( location, value );
4937

4938
			// flat array of floats with 3 x N size (JS or typed array)
4939

4940
			} else if( type === "fv" ) {
4941

4942
				_gl.uniform3fv( location, value );
4943

4944
			// array of THREE.Vector3
4945

4946
			} else if( type === "v3v" ) {
4947

4948
				if ( ! uniform._array ) {
4949

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

4952
				}
A
alteredq 已提交
4953

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

4956
					offset = i * 3;
4957

4958 4959 4960
					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;
					uniform._array[ offset + 2 ] = value[ i ].z;
4961

4962
				}
4963

4964
				_gl.uniform3fv( location, uniform._array );
4965

4966
			// single THREE.Matrix4
4967

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

4970
				if ( ! uniform._array ) {
A
alteredq 已提交
4971

4972
					uniform._array = new Float32Array( 16 );
4973

4974
				}
4975

4976 4977
				value.flattenToArray( uniform._array );
				_gl.uniformMatrix4fv( location, false, uniform._array );
4978

4979
			// array of THREE.Matrix4
4980

4981
			} else if( type === "m4v" ) {
A
alteredq 已提交
4982

4983 4984 4985
				if ( ! uniform._array ) {

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

M
Mr.doob 已提交
4987
				}
M
Mr.doob 已提交
4988

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

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

4993
				}
A
alteredq 已提交
4994

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

4997

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

5000
			} else if( type === "t" ) {
A
alteredq 已提交
5001

5002
				_gl.uniform1i( location, value );
5003

5004
				texture = uniform.texture;
A
alteredq 已提交
5005

5006
				if ( !texture ) continue;
A
alteredq 已提交
5007

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

5010
					setCubeTexture( texture, value );
A
alteredq 已提交
5011

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

5014 5015 5016 5017 5018
					setCubeTextureDynamic( texture, value );

				} else {

					setTexture( texture, value );
5019

M
Mr.doob 已提交
5020
				}
M
Mr.doob 已提交
5021

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

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

5026
				if ( ! uniform._array ) {
M
Mr.doob 已提交
5027

5028
					uniform._array = [];
A
alteredq 已提交
5029

5030 5031 5032 5033 5034
					for( i = 0, il = uniform.texture.length; i < il; i ++ ) {

						uniform._array[ i ] = value + i;

					}
A
alteredq 已提交
5035

M
Mr.doob 已提交
5036
				}
A
alteredq 已提交
5037

5038
				_gl.uniform1iv( location, uniform._array );
A
alteredq 已提交
5039

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

5042
					texture = uniform.texture[ i ];
5043

5044
					if ( !texture ) continue;
M
Mr.doob 已提交
5045

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

M
Mr.doob 已提交
5048
				}
M
Mr.doob 已提交
5049

M
Mr.doob 已提交
5050
			}
M
Mr.doob 已提交
5051

M
Mr.doob 已提交
5052
		}
M
Mr.doob 已提交
5053

5054
	};
M
Mr.doob 已提交
5055

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

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

5060
		if ( computeNormalMatrix ) {
M
Mr.doob 已提交
5061

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

5064
		}
M
Mr.doob 已提交
5065

5066
	}
M
Mr.doob 已提交
5067

5068
	function setupLights ( program, lights ) {
M
Mr.doob 已提交
5069

5070 5071 5072
		var l, ll, light, n,
		r = 0, g = 0, b = 0,
		color, position, intensity, distance,
M
Mr.doob 已提交
5073

5074
		zlights = _lights,
A
alteredq 已提交
5075

5076 5077
		dcolors = zlights.directional.colors,
		dpositions = zlights.directional.positions,
A
alteredq 已提交
5078

5079 5080 5081
		pcolors = zlights.point.colors,
		ppositions = zlights.point.positions,
		pdistances = zlights.point.distances,
5082

5083 5084
		dlength = 0,
		plength = 0,
5085

5086 5087
		doffset = 0,
		poffset = 0;
5088

5089
		for ( l = 0, ll = lights.length; l < ll; l ++ ) {
5090

5091 5092
			light = lights[ l ];
			color = light.color;
A
alteredq 已提交
5093

5094 5095 5096
			position = light.position;
			intensity = light.intensity;
			distance = light.distance;
A
alteredq 已提交
5097

5098
			if ( light instanceof THREE.AmbientLight ) {
5099

5100
				if ( _this.gammaInput ) {
5101

5102 5103 5104
					r += color.r * color.r;
					g += color.g * color.g;
					b += color.b * color.b;
5105

5106
				} else {
5107

5108 5109 5110
					r += color.r;
					g += color.g;
					b += color.b;
5111

5112
				}
5113

5114
			} else if ( light instanceof THREE.DirectionalLight ) {
5115

5116
				doffset = dlength * 3;
5117

5118
				if ( _this.gammaInput ) {
5119

5120 5121 5122
					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;
5123

5124
				} else {
5125

5126 5127 5128
					dcolors[ doffset ]     = color.r * intensity;
					dcolors[ doffset + 1 ] = color.g * intensity;
					dcolors[ doffset + 2 ] = color.b * intensity;
A
alteredq 已提交
5129

5130
				}
A
alteredq 已提交
5131

5132 5133 5134
				dpositions[ doffset ]     = position.x;
				dpositions[ doffset + 1 ] = position.y;
				dpositions[ doffset + 2 ] = position.z;
A
alteredq 已提交
5135

5136
				dlength += 1;
A
alteredq 已提交
5137

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

5140
				doffset = dlength * 3;
A
alteredq 已提交
5141

5142
				if ( _this.gammaInput ) {
5143

5144 5145 5146
					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;
5147

5148
				} else {
A
alteredq 已提交
5149

5150 5151 5152
					dcolors[ doffset ]     = color.r * intensity;
					dcolors[ doffset + 1 ] = color.g * intensity;
					dcolors[ doffset + 2 ] = color.b * intensity;
A
alteredq 已提交
5153 5154 5155

				}

5156
				n = 1 / position.length();
A
alteredq 已提交
5157

5158 5159 5160
				dpositions[ doffset ]     = position.x * n;
				dpositions[ doffset + 1 ] = position.y * n;
				dpositions[ doffset + 2 ] = position.z * n;
M
Mr.doob 已提交
5161

5162
				dlength += 1;
5163

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

5166
				poffset = plength * 3;
M
Mr.doob 已提交
5167

5168
				if ( _this.gammaInput ) {
5169

5170 5171 5172
					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 已提交
5173

5174
				} else {
A
alteredq 已提交
5175

5176 5177 5178
					pcolors[ poffset ]     = color.r * intensity;
					pcolors[ poffset + 1 ] = color.g * intensity;
					pcolors[ poffset + 2 ] = color.b * intensity;
A
alteredq 已提交
5179

5180
				}
A
alteredq 已提交
5181

5182 5183 5184
				ppositions[ poffset ]     = position.x;
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
A
alteredq 已提交
5185

5186
				pdistances[ plength ] = distance;
A
alteredq 已提交
5187

5188
				plength += 1;
5189

5190
			}
5191

5192
		}
A
alteredq 已提交
5193

5194 5195
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
A
alteredq 已提交
5196

5197 5198
		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 已提交
5199

5200 5201
		zlights.point.length = plength;
		zlights.directional.length = dlength;
A
alteredq 已提交
5202

5203 5204 5205
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
5206

5207
	};
M
Mr.doob 已提交
5208

5209
	// GL state setting
M
Mr.doob 已提交
5210

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

5213
		if ( cullFace ) {
M
Mr.doob 已提交
5214

5215
			if ( !frontFace || frontFace === "ccw" ) {
5216

5217
				_gl.frontFace( _gl.CCW );
5218

5219
			} else {
5220

5221
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
5222

5223
			}
M
Mr.doob 已提交
5224

5225
			if( cullFace === "back" ) {
5226

5227
				_gl.cullFace( _gl.BACK );
5228

5229
			} else if( cullFace === "front" ) {
5230

5231
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
5232

5233
			} else {
5234

5235
				_gl.cullFace( _gl.FRONT_AND_BACK );
5236

5237
			}
5238

5239
			_gl.enable( _gl.CULL_FACE );
5240

5241
		} else {
5242

5243
			_gl.disable( _gl.CULL_FACE );
5244 5245 5246 5247 5248

		}

	};

5249
	function setLineWidth ( width ) {
5250

5251
		if ( width !== _oldLineWidth ) {
5252

5253
			_gl.lineWidth( width );
5254

5255
			_oldLineWidth = width;
M
Mr.doob 已提交
5256

5257
		}
M
Mr.doob 已提交
5258

5259
	};
5260

5261
	function setObjectFaces ( object ) {
5262

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

5265
			if( object.doubleSided ) {
M
Mr.doob 已提交
5266

5267
				_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
5268

5269
			} else {
5270

5271
				_gl.enable( _gl.CULL_FACE );
5272

5273
			}
5274

5275
			_oldDoubleSided = object.doubleSided;
5276

5277
		}
5278

5279
		if ( _oldFlipSided !== object.flipSided ) {
5280

5281
			if( object.flipSided ) {
5282

5283
				_gl.frontFace( _gl.CW );
5284

5285
			} else {
5286

5287
				_gl.frontFace( _gl.CCW );
5288

5289
			}
5290

5291
			_oldFlipSided = object.flipSided;
5292

5293
		}
5294

5295
	};
5296

5297
	function setDepthTest ( depthTest ) {
5298

5299
		if ( _oldDepthTest !== depthTest ) {
5300

5301
			if( depthTest ) {
5302

5303
				_gl.enable( _gl.DEPTH_TEST );
5304

5305
			} else {
5306

5307
				_gl.disable( _gl.DEPTH_TEST );
5308 5309 5310

			}

5311
			_oldDepthTest = depthTest;
5312

5313
		}
5314

5315
	};
5316

5317
	function setDepthWrite ( depthWrite ) {
5318

5319
		if ( _oldDepthWrite !== depthWrite ) {
5320

5321 5322
			_gl.depthMask( depthWrite );
			_oldDepthWrite = depthWrite;
5323 5324 5325

		}

5326
	};
5327

5328
	function setPolygonOffset ( polygonoffset, factor, units ) {
5329

5330
		if ( _oldPolygonOffset !== polygonoffset ) {
M
Mr.doob 已提交
5331

5332
			if ( polygonoffset ) {
5333

5334
				_gl.enable( _gl.POLYGON_OFFSET_FILL );
5335

5336
			} else {
5337

5338
				_gl.disable( _gl.POLYGON_OFFSET_FILL );
5339

5340
			}
5341

5342
			_oldPolygonOffset = polygonoffset;
5343

5344
		}
5345

5346
		if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
5347

5348
			_gl.polygonOffset( factor, units );
M
Mr.doob 已提交
5349

5350 5351
			_oldPolygonOffsetFactor = factor;
			_oldPolygonOffsetUnits = units;
M
Mr.doob 已提交
5352

5353
		}
M
Mr.doob 已提交
5354

5355
	};
M
Mr.doob 已提交
5356

5357
	function setBlending ( blending ) {
M
Mr.doob 已提交
5358

5359
		if ( blending !== _oldBlending ) {
M
Mr.doob 已提交
5360

5361
			switch ( blending ) {
M
Mr.doob 已提交
5362

5363
				case THREE.AdditiveBlending:
M
Mr.doob 已提交
5364

5365 5366
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
M
Mr.doob 已提交
5367

5368
					break;
M
Mr.doob 已提交
5369

5370
				case THREE.SubtractiveBlending:
M
Mr.doob 已提交
5371

5372
					// TODO: Find blendFuncSeparate() combination
M
Mr.doob 已提交
5373

5374 5375
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
M
Mr.doob 已提交
5376

5377
					break;
M
Mr.doob 已提交
5378

5379
				case THREE.MultiplyBlending:
M
Mr.doob 已提交
5380

5381
					// TODO: Find blendFuncSeparate() combination
M
Mr.doob 已提交
5382

5383 5384
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
M
Mr.doob 已提交
5385

5386
					break;
5387

5388
				default:
N
Nicolas Garcia Belmonte 已提交
5389

5390 5391
					_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 );
5392

5393
					break;
5394

5395
			}
5396

5397
			_oldBlending = blending;
5398

5399
		}
5400 5401

	};
5402

5403 5404 5405
	// Shaders

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

5407
		var p, pl, program, code;
5408
		var chunks = [];
5409 5410 5411

		// Generate code

5412 5413 5414 5415 5416 5417 5418 5419 5420 5421
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

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

		}
5422 5423 5424

		for ( p in parameters ) {

5425 5426
			chunks.push( p );
			chunks.push( parameters[ p ] );
5427 5428 5429

		}

5430 5431
		code = chunks.join();

5432 5433 5434 5435
		// Check if code has been already compiled

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

5436
			if ( _programs[ p ].code === code ) {
5437 5438

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

5440 5441 5442 5443 5444
				return _programs[ p ].program;

			}

		}
5445

5446
		//console.log( "building new program " );
5447 5448 5449

		//

5450
		program = _gl.createProgram();
M
Mr.doob 已提交
5451

5452
		var prefix_vertex = [
M
Mr.doob 已提交
5453

A
alteredq 已提交
5454
			_supportsVertexTextures ? "#define VERTEX_TEXTURES" : "",
5455

5456 5457 5458 5459
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

5460 5461 5462
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

5463 5464
			"#define MAX_SHADOWS " + parameters.maxShadows,

5465 5466
			"#define MAX_BONES " + parameters.maxBones,

5467
			parameters.map ? "#define USE_MAP" : "",
5468 5469 5470
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5471
			parameters.skinning ? "#define USE_SKINNING" : "",
5472
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
A
alteredq 已提交
5473
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
5474

5475
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5476
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
5477

5478 5479
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
5480 5481 5482
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
5483 5484
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
5485
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
5486 5487 5488

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
5489 5490 5491
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
5492
			"attribute vec2 uv2;",
5493

5494
			"#ifdef USE_COLOR",
5495

5496
				"attribute vec3 color;",
5497

5498 5499
			"#endif",

5500
			"#ifdef USE_MORPHTARGETS",
5501

5502 5503 5504 5505 5506 5507 5508 5509
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
				"attribute vec3 morphTarget4;",
				"attribute vec3 morphTarget5;",
				"attribute vec3 morphTarget6;",
				"attribute vec3 morphTarget7;",
5510

5511 5512 5513
			"#endif",

			"#ifdef USE_SKINNING",
5514

5515 5516 5517 5518
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
5519

5520
			"#endif",
5521

M
Mr.doob 已提交
5522
			""
A
alteredq 已提交
5523

M
Mr.doob 已提交
5524
		].join("\n");
5525

M
Mr.doob 已提交
5526 5527 5528 5529 5530 5531 5532 5533 5534
		var prefix_fragment = [

			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",

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

5535 5536
			"#define MAX_SHADOWS " + parameters.maxShadows,

5537 5538
			parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",

5539 5540 5541 5542
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

M
Mr.doob 已提交
5543 5544
			( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
			( parameters.useFog && parameters.fog instanceof THREE.FogExp2 ) ? "#define FOG_EXP2" : "",
M
Mr.doob 已提交
5545 5546 5547 5548 5549

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

5551 5552 5553
			parameters.metal ? "#define METAL" : "",
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",

5554
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5555 5556 5557
			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 已提交
5558 5559 5560 5561 5562 5563 5564

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

		].join("\n");

5565 5566
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
5567

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

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

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

N
Nicolas Garcia Belmonte 已提交
5574
		}
5575

5576 5577
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
5578

M
Mr.doob 已提交
5579
		program.uniforms = {};
5580
		program.attributes = {};
M
Mr.doob 已提交
5581

5582 5583 5584 5585
		var identifiers, u, a, i;

		// cache uniform locations

5586
		identifiers = [
5587

5588 5589
			'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
			'cameraInverseMatrix', 'boneGlobalMatrices', 'morphTargetInfluences'
M
Mr.doob 已提交
5590

5591
		];
M
Mr.doob 已提交
5592

5593
		for ( u in uniforms ) {
M
Mr.doob 已提交
5594

5595
			identifiers.push( u );
M
Mr.doob 已提交
5596

5597
		}
M
Mr.doob 已提交
5598

5599
		cacheUniformLocations( program, identifiers );
M
Mr.doob 已提交
5600

5601
		// cache attributes locations
M
Mr.doob 已提交
5602

5603
		identifiers = [
A
alteredq 已提交
5604

5605 5606
			"position", "normal", "uv", "uv2", "tangent", "color",
			"skinVertexA", "skinVertexB", "skinIndex", "skinWeight"
A
alteredq 已提交
5607

5608
		];
M
Mr.doob 已提交
5609

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

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

5614
		}
5615

5616
		for ( a in attributes ) {
5617

5618
			identifiers.push( a );
5619

5620
		}
5621

5622
		cacheAttributeLocations( program, identifiers );
5623

5624
		program.id = _programs.length;
5625

5626
		_programs.push( { program: program, code: code } );
5627

5628
		_this.info.memory.programs = _programs.length;
5629

5630
		return program;
5631

5632
	};
5633

5634
	// Shader parameters cache
5635

5636
	function cacheUniformLocations ( program, identifiers ) {
5637

5638
		var i, l, id;
5639

5640
		for( i = 0, l = identifiers.length; i < l; i++ ) {
5641

5642 5643
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
5644

5645
		}
M
Mr.doob 已提交
5646

5647
	};
M
Mr.doob 已提交
5648

5649
	function cacheAttributeLocations ( program, identifiers ) {
A
alteredq 已提交
5650

5651
		var i, l, id;
A
alteredq 已提交
5652

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

5655 5656
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
A
alteredq 已提交
5657

5658
		}
5659

5660
	};
A
alteredq 已提交
5661

5662
	function getShader ( type, string ) {
A
alteredq 已提交
5663

5664
		var shader;
5665

5666
		if ( type === "fragment" ) {
A
alteredq 已提交
5667

5668
			shader = _gl.createShader( _gl.FRAGMENT_SHADER );
A
alteredq 已提交
5669

5670
		} else if ( type === "vertex" ) {
A
alteredq 已提交
5671

5672
			shader = _gl.createShader( _gl.VERTEX_SHADER );
A
alteredq 已提交
5673

5674
		}
A
alteredq 已提交
5675

5676 5677
		_gl.shaderSource( shader, string );
		_gl.compileShader( shader );
5678

5679
		if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {
5680

5681 5682 5683
			console.error( _gl.getShaderInfoLog( shader ) );
			console.error( string );
			return null;
5684

A
alteredq 已提交
5685 5686
		}

5687 5688
		return shader;

A
alteredq 已提交
5689
	};
5690

5691 5692 5693
	// Textures

	function setTextureParameters ( textureType, texture, image ) {
5694

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

5697 5698
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
5699

5700 5701
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
5702

5703
			_gl.generateMipmap( textureType );
M
Mr.doob 已提交
5704

5705
		} else {
M
Mr.doob 已提交
5706

5707 5708
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
5709

5710 5711
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
5712

5713
		}
M
Mr.doob 已提交
5714

5715
	};
5716

5717
	function setTexture ( texture, slot ) {
5718

5719
		if ( texture.needsUpdate ) {
A
alteredq 已提交
5720

5721
			if ( ! texture.__webglInit ) {
M
Mr.doob 已提交
5722

5723
				texture.__webglInit = true;
5724
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5725

M
Mr.doob 已提交
5726 5727
				_this.info.memory.textures ++;

5728
			}
M
Mr.doob 已提交
5729

5730
			_gl.activeTexture( _gl.TEXTURE0 + slot );
5731 5732
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );

5733
			if ( texture instanceof THREE.DataTexture ) {
5734 5735

				_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 已提交
5736

A
alteredq 已提交
5737
			} else {
M
Mr.doob 已提交
5738

M
Mr.doob 已提交
5739
				_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
5740 5741 5742

			}

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

A
alteredq 已提交
5745
			texture.needsUpdate = false;
5746

5747
		} else {
5748

5749 5750
			_gl.activeTexture( _gl.TEXTURE0 + slot );
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
5751 5752

		}
M
Mr.doob 已提交
5753

5754
	};
M
Mr.doob 已提交
5755

5756
	function setCubeTexture ( texture, slot ) {
5757

5758
		if ( texture.image.length === 6 ) {
5759 5760 5761

			if ( texture.needsUpdate ) {

A
alteredq 已提交
5762
				if ( ! texture.image.__webglTextureCube ) {
5763 5764

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

A
alteredq 已提交
5766
				}
5767

A
alteredq 已提交
5768 5769
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5770

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

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

A
alteredq 已提交
5775
				}
5776

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

A
alteredq 已提交
5779
				texture.needsUpdate = false;
5780

A
alteredq 已提交
5781
			} else {
5782

A
alteredq 已提交
5783 5784
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5785

A
alteredq 已提交
5786
			}
5787

A
alteredq 已提交
5788
		}
5789

A
alteredq 已提交
5790
	};
5791

5792
	function setCubeTextureDynamic ( texture, slot ) {
5793

A
alteredq 已提交
5794 5795
		_gl.activeTexture( _gl.TEXTURE0 + slot );
		_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
5796 5797 5798

	};

5799 5800 5801
	// Render targets

	function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
5802

5803 5804
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
A
alteredq 已提交
5805

5806
	};
M
Mr.doob 已提交
5807

5808
	function setupRenderBuffer ( renderbuffer, renderTarget  ) {
M
Mikael Emtinger 已提交
5809

5810
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
5811

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

5814 5815
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5816

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

5820 5821 5822 5823
			_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 已提交
5824

5825 5826
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5827

5828
		} else {
A
alteredq 已提交
5829

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

5832
		}
A
alteredq 已提交
5833

5834
	};
A
alteredq 已提交
5835

5836
	function setRenderTarget ( renderTarget ) {
A
alteredq 已提交
5837

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

5840
		if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
A
alteredq 已提交
5841

5842 5843
			if( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
			if( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
A
alteredq 已提交
5844

5845
			renderTarget.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5846

5847
			// Setup texture, create render and frame buffers
5848

5849
			if ( isCube ) {
M
Mr.doob 已提交
5850

5851 5852
				renderTarget.__webglFramebuffer = [];
				renderTarget.__webglRenderbuffer = [];
M
Mikael Emtinger 已提交
5853

5854 5855
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, renderTarget );
A
alteredq 已提交
5856

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

5859 5860
					renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
					renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
A
alteredq 已提交
5861

5862
					_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 已提交
5863

5864
					setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
A
alteredq 已提交
5865

5866
					setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
A
alteredq 已提交
5867

5868
				}
5869

5870
			} else {
5871

5872 5873
				renderTarget.__webglFramebuffer = _gl.createFramebuffer();
				renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
5874

5875 5876
				_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
				setTextureParameters( _gl.TEXTURE_2D, renderTarget, renderTarget );
5877

5878
				_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTarget.format ), renderTarget.width, renderTarget.height, 0, paramThreeToGL( renderTarget.format ), paramThreeToGL( renderTarget.type ), null );
5879

5880
				setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
5881

5882
				_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTarget.__webglRenderbuffer );
5883

5884
				setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
5885

M
Mikael Emtinger 已提交
5886
			}
5887

5888
			// Release everything
M
Mr.doob 已提交
5889

A
alteredq 已提交
5890 5891 5892 5893 5894 5895 5896 5897 5898 5899
			if ( isCube ) {

				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

			} else {

				_gl.bindTexture( _gl.TEXTURE_2D, null );

			}

5900 5901
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
5902

5903 5904
		}

5905
		var framebuffer, width, height, vx, vy;
M
Mr.doob 已提交
5906

5907
		if ( renderTarget ) {
M
Mr.doob 已提交
5908

A
alteredq 已提交
5909 5910
			if ( isCube ) {

5911
				framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
A
alteredq 已提交
5912 5913 5914

			} else {

5915
				framebuffer = renderTarget.__webglFramebuffer;
A
alteredq 已提交
5916 5917 5918

			}

5919 5920
			width = renderTarget.width;
			height = renderTarget.height;
M
Mr.doob 已提交
5921

5922 5923 5924
			vx = 0;
			vy = 0;

5925
		} else {
M
Mr.doob 已提交
5926

5927
			framebuffer = null;
5928

5929 5930
			width = _viewportWidth;
			height = _viewportHeight;
5931

5932 5933
			vx = _viewportX;
			vy = _viewportY;
M
Mr.doob 已提交
5934

5935
		}
M
Mr.doob 已提交
5936

5937
		if ( framebuffer !== _currentFramebuffer ) {
M
Mr.doob 已提交
5938

5939
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
5940
			_gl.viewport( vx, vy, width, height );
M
Mr.doob 已提交
5941

5942
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
5943

5944
		}
5945

5946
	};
M
Mr.doob 已提交
5947

5948
	function updateRenderTargetMipmap ( renderTarget ) {
M
Mr.doob 已提交
5949

A
alteredq 已提交
5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962
		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 已提交
5963 5964

	};
5965

5966
	// fallback filters for non-power-of-2 textures
5967

5968
	function filterFallback ( f ) {
5969

5970 5971 5972 5973 5974 5975 5976 5977
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mr.doob 已提交
5978
			case THREE.LinearMipMapLinearFilter:
M
Mikael Emtinger 已提交
5979
			default:
5980

M
Mikael Emtinger 已提交
5981
				return _gl.LINEAR; break;
5982 5983

		}
5984

5985
	};
5986

5987
	function paramThreeToGL ( p ) {
M
Mr.doob 已提交
5988

5989
		switch ( p ) {
M
Mr.doob 已提交
5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002

			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;

6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016
			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;

6017
		}
M
Mr.doob 已提交
6018

6019
		return 0;
M
Mr.doob 已提交
6020

6021 6022
	};

6023
	function isPowerOfTwo ( value ) {
6024

6025
		return ( value & ( value - 1 ) ) === 0;
6026 6027 6028

	};

6029
	// Allocations
6030

6031
	function allocateBones ( object ) {
6032

6033 6034 6035 6036 6037 6038 6039
		// 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)
6040

6041
		var maxBones = 50;
6042

6043
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
6044

6045 6046 6047 6048 6049
			maxBones = object.bones.length;

		}

		return maxBones;
6050

6051
	};
6052

6053
	function allocateLights ( lights ) {
6054

6055 6056
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
6057

6058
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
6059

6060
			light = lights[ l ];
6061

6062 6063 6064
			if ( light instanceof THREE.SpotLight ) dirLights ++; // hack, not a proper spotlight
			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
			if ( light instanceof THREE.PointLight ) pointLights ++;
6065

6066
		}
6067

6068
		if ( ( pointLights + dirLights ) <= _maxLights ) {
6069

6070 6071
			maxDirLights = dirLights;
			maxPointLights = pointLights;
6072

6073
		} else {
6074

6075 6076
			maxDirLights = Math.ceil( _maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = _maxLights - maxDirLights;
6077 6078 6079

		}

6080
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
6081 6082

	};
M
Mr.doob 已提交
6083

6084
	function allocateShadows ( lights ) {
6085

M
Mr.doob 已提交
6086
		var l, ll, light, maxShadows = 0;
6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099

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

			light = lights[ l ];

			if ( light instanceof THREE.SpotLight && light.castShadow ) maxShadows ++;

		}

		return maxShadows;

	};

6100
	function maxVertexTextures () {
6101

6102 6103 6104
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
M
Mr.doob 已提交
6105

6106
	// Initialization
M
Mr.doob 已提交
6107

6108
	function initSprites () {
M
Mr.doob 已提交
6109

6110 6111
		_sprite.vertices = new Float32Array( 8 + 8 );
		_sprite.faces    = new Uint16Array( 6 );
M
Mr.doob 已提交
6112

6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170
		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 已提交
6171

6172
	};
M
Mr.doob 已提交
6173

6174
	function initShadowmaps () {
M
Mr.doob 已提交
6175

6176 6177
		var depthShader = THREE.ShaderLib[ "depthRGBA" ];
		var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
M
Mr.doob 已提交
6178

6179 6180
		_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 已提交
6181

6182 6183
		_depthMaterial._shadowPass = true;
		_depthMaterialMorph._shadowPass = true;
M
Mr.doob 已提交
6184

6185
	}
6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237

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

	};

6238
};