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

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

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

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

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

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

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

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

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

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

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

	// clearing
M
Mr.doob 已提交
35

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

41 42
	// scene graph

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

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

	// physically based shading

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

54 55 56
	// shadow map

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

63
	// morphs
64

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

68 69 70 71
	// flags

	this.autoScaleCubemaps = true;

72 73
	// custom render plugins

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

77
	// info
78

79
	this.info = {
80

81
		memory: {
82

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

87
		},
88

89
		render: {
90

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

		}

98
	};
M
Mr.doob 已提交
99

100
	// internal properties
101

102
	var _this = this,
103

104
	_gl,
105

106
	_programs = [],
107

108
	// internal state cache
109

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

117
	// GL state cache
118

119 120 121 122 123 124 125 126 127
	_oldDoubleSided = null,
	_oldFlipSided = null,
	_oldBlending = null,
	_oldDepthTest = null,
	_oldDepthWrite = null,
	_oldPolygonOffset = null,
	_oldPolygonOffsetFactor = null,
	_oldPolygonOffsetUnits = null,
	_oldLineWidth = null,
128

129 130 131 132
	_viewportX = 0,
	_viewportY = 0,
	_viewportWidth = 0,
	_viewportHeight = 0,
A
alteredq 已提交
133 134
	_currentWidth = 0,
	_currentHeight = 0,
135

A
alteredq 已提交
136
	// frustum
M
Mr.doob 已提交
137

A
alteredq 已提交
138
	_frustum = new THREE.Frustum(),
139

140
	 // camera matrices cache
M
Mikael Emtinger 已提交
141

142
	_projScreenMatrix = new THREE.Matrix4(),
A
alteredq 已提交
143
	_projScreenMatrixPS = new THREE.Matrix4(),
M
Mr.doob 已提交
144

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

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

149 150
	_direction = new THREE.Vector3(),

151
	_lights = {
M
Mr.doob 已提交
152

153 154 155
		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 已提交
156

157
	};
M
Mr.doob 已提交
158

159
	// initialize
M
Mikael Emtinger 已提交
160

161
	_gl = initGL();
M
Mikael Emtinger 已提交
162

163
	setDefaultGLState();
M
Mikael Emtinger 已提交
164

165
	this.context = _gl;
M
Mikael Emtinger 已提交
166

167 168 169
	// GPU capabilities

	var _maxVertexTextures = _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ),
A
alteredq 已提交
170
	_maxTextureSize = _gl.getParameter( _gl.MAX_TEXTURE_SIZE ),
171
	_maxCubemapSize = _gl.getParameter( _gl.MAX_CUBE_MAP_TEXTURE_SIZE );
M
Mr.doob 已提交
172

173
	// API
M
Mr.doob 已提交
174

175
	this.getContext = function () {
M
Mr.doob 已提交
176

177
		return _gl;
M
Mr.doob 已提交
178

179
	};
M
Mr.doob 已提交
180

181
	this.supportsVertexTextures = function () {
M
Mikael Emtinger 已提交
182

183
		return _maxVertexTextures > 0;
M
Mikael Emtinger 已提交
184

185
	};
M
Mikael Emtinger 已提交
186

N
Nicolas Garcia Belmonte 已提交
187 188 189 190
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
191

192 193 194
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
195

196
	this.setViewport = function ( x, y, width, height ) {
197

198 199
		_viewportX = x;
		_viewportY = y;
200

201 202
		_viewportWidth = width;
		_viewportHeight = height;
203

204
		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
205

N
Nicolas Garcia Belmonte 已提交
206
	};
207

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

210
		_gl.scissor( x, y, width, height );
211

212
	};
213

214
	this.enableScissorTest = function ( enable ) {
215

M
Mr.doob 已提交
216
		enable ? _gl.enable( _gl.SCISSOR_TEST ) : _gl.disable( _gl.SCISSOR_TEST );
217 218

	};
219

220 221
	// Clearing

222
	this.setClearColorHex = function ( hex, alpha ) {
223

224 225 226 227
		_clearColor.setHex( hex );
		_clearAlpha = alpha;

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

229
	};
A
alteredq 已提交
230

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

233 234 235 236
		_clearColor.copy( color );
		_clearAlpha = alpha;

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

	};
239

M
Mr.doob 已提交
240 241 242 243 244 245 246
	this.getClearColor = function () {

		return _clearColor;

	};

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

M
Mr.doob 已提交
248 249 250 251 252 253 254 255
		return _clearAlpha;

	};

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

		var bits = 0;

256 257 258
		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 已提交
259 260

		_gl.clear( bits );
N
Nicolas Garcia Belmonte 已提交
261 262 263

	};

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

A
alteredq 已提交
266
		this.setRenderTarget( renderTarget );
267
		this.clear( color, depth, stencil );
M
Mr.doob 已提交
268 269 270

	};

271 272
	// Plugins

A
alteredq 已提交
273
	this.addPostPlugin = function ( plugin ) {
274 275

		plugin.init( this );
A
alteredq 已提交
276
		this.renderPluginsPost.push( plugin );
277 278 279

	};

A
alteredq 已提交
280 281 282 283 284 285
	this.addPrePlugin = function ( plugin ) {

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

	};
286

287 288
	// Deallocation

289 290 291 292 293 294 295 296 297 298 299 300 301 302
	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 ) {

303
			for ( var g in object.geometry.geometryGroups ) {
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331

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

334 335
	};

336
	// Rendering
337

338
	this.updateShadowMap = function ( scene, camera ) {
339

A
alteredq 已提交
340 341 342 343 344 345 346 347
		_currentProgram = null;
		_oldBlending = -1;
		_oldDepthTest = -1;
		_oldDepthWrite = -1;
		_currentGeometryGroupHash = -1;
		_currentMaterialId = -1;

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

349
	};
M
Mr.doob 已提交
350

351
	// Internal functions
352

353
	// Buffer allocation
354

355
	function createParticleBuffers ( geometry ) {
356

357 358
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
359

360
		_this.info.geometries ++;
361

362
	};
363

364
	function createLineBuffers ( geometry ) {
365

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

369
		_this.info.memory.geometries ++;
370

371
	};
372

373
	function createRibbonBuffers ( geometry ) {
374

375 376
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
377

378
		_this.info.memory.geometries ++;
M
Mr.doob 已提交
379

380
	};
381

382
	function createMeshBuffers ( geometryGroup ) {
383

384 385 386 387 388 389
		geometryGroup.__webglVertexBuffer = _gl.createBuffer();
		geometryGroup.__webglNormalBuffer = _gl.createBuffer();
		geometryGroup.__webglTangentBuffer = _gl.createBuffer();
		geometryGroup.__webglColorBuffer = _gl.createBuffer();
		geometryGroup.__webglUVBuffer = _gl.createBuffer();
		geometryGroup.__webglUV2Buffer = _gl.createBuffer();
390

391 392 393 394
		geometryGroup.__webglSkinVertexABuffer = _gl.createBuffer();
		geometryGroup.__webglSkinVertexBBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinIndicesBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinWeightsBuffer = _gl.createBuffer();
395

396 397
		geometryGroup.__webglFaceBuffer = _gl.createBuffer();
		geometryGroup.__webglLineBuffer = _gl.createBuffer();
398

399
		var m, ml;
400

401
		if ( geometryGroup.numMorphTargets ) {
402

403
			geometryGroup.__webglMorphTargetsBuffers = [];
404

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

407
				geometryGroup.__webglMorphTargetsBuffers.push( _gl.createBuffer() );
408 409 410 411 412 413 414 415 416 417 418

			}

		}

		if ( geometryGroup.numMorphNormals ) {

			geometryGroup.__webglMorphNormalsBuffers = [];

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

A
alteredq 已提交
419
				geometryGroup.__webglMorphNormalsBuffers.push( _gl.createBuffer() );
420

421
			}
422

423
		}
424

425
		_this.info.memory.geometries ++;
426

427
	};
428

429
	// Buffer deallocation
430

431
	function deleteParticleBuffers ( geometry ) {
432

433 434
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
435

436
		_this.info.memory.geometries --;
437

438
	};
439

440
	function deleteLineBuffers ( geometry ) {
441

442 443
		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );
444

M
Mr.doob 已提交
445 446
		_this.info.memory.geometries --;

447 448
	};

449
	function deleteRibbonBuffers ( geometry ) {
450 451 452 453

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

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

456 457
	};

458
	function deleteMeshBuffers ( geometryGroup ) {
459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474

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

475 476
		var m, ml;

477 478
		if ( geometryGroup.numMorphTargets ) {

479
			for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
480 481

				_gl.deleteBuffer( geometryGroup.__webglMorphTargetsBuffers[ m ] );
482 483 484 485 486 487 488 489 490

			}

		}

		if ( geometryGroup.numMorphNormals ) {

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

A
alteredq 已提交
491
				_gl.deleteBuffer( geometryGroup.__webglMorphNormalsBuffers[ m ] );
492 493 494 495 496

			}

		}

497 498 499 500 501 502 503 504 505 506 507

		if ( geometryGroup.__webglCustomAttributesList ) {

			for ( var id in geometryGroup.__webglCustomAttributesList ) {

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

			}

		}

M
Mr.doob 已提交
508 509
		_this.info.memory.geometries --;

510 511
	};

512
	// Buffer initialization
513

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

516 517
		var nvertices = geometry.vertices.length;

518
		var material = object.material;
519

520
		if ( material.attributes ) {
521

522
			if ( geometry.__webglCustomAttributesList === undefined ) {
523

524
				geometry.__webglCustomAttributesList = [];
525

526
			}
527

528
			for ( var a in material.attributes ) {
529

530
				var attribute = material.attributes[ a ];
531

532
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
533

534
					attribute.__webglInitialized = true;
535

A
alteredq 已提交
536
					var size = 1;		// "f" and "i"
537

538 539 540 541
					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;
542

543
					attribute.size = size;
A
alteredq 已提交
544

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

547 548
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
549

550
					attribute.needsUpdate = true;
551

552
				}
553

554
				geometry.__webglCustomAttributesList.push( attribute );
555

556
			}
557

558
		}
559

560
	};
561

562
	function initParticleBuffers ( geometry, object ) {
A
alteredq 已提交
563 564 565 566 567 568

		var nvertices = geometry.vertices.length;

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

569 570 571
		geometry.__sortArray = [];

		geometry.__webglParticleCount = nvertices;
A
alteredq 已提交
572 573 574 575 576

		initCustomAttributes ( geometry, object );

	};

577
	function initLineBuffers ( geometry, object ) {
A
alteredq 已提交
578 579 580 581 582 583

		var nvertices = geometry.vertices.length;

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

584
		geometry.__webglLineCount = nvertices;
A
alteredq 已提交
585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600

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

603 604 605
		var geometry = object.geometry,
			faces3 = geometryGroup.faces3,
			faces4 = geometryGroup.faces4,
M
Mr.doob 已提交
606

607 608 609
			nvertices = faces3.length * 3 + faces4.length * 4,
			ntris     = faces3.length * 1 + faces4.length * 2,
			nlines    = faces3.length * 3 + faces4.length * 4,
610

611
			material = getBufferMaterial( object, geometryGroup ),
612

613 614 615
			uvType = bufferGuessUVType( material ),
			normalType = bufferGuessNormalType( material ),
			vertexColorType = bufferGuessVertexColorType( material );
A
alteredq 已提交
616

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

619
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
620

621
		if ( normalType ) {
M
Mr.doob 已提交
622

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

625
		}
626

627
		if ( geometry.hasTangents ) {
628

629
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
630

631
		}
632

633
		if ( vertexColorType ) {
634

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

637
		}
M
Mr.doob 已提交
638

639
		if ( uvType ) {
640

641
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
642

643 644 645 646 647
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

649 650 651 652 653 654 655 656 657 658 659 660 661 662 663
				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 );

		}

664
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
665
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
666

667 668
		var m, ml;

669 670
		if ( geometryGroup.numMorphTargets ) {

M
Mr.doob 已提交
671
			geometryGroup.__morphTargetsArrays = [];
672

673
			for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
674

675
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );
676 677 678 679 680 681 682 683 684 685 686

			}

		}

		if ( geometryGroup.numMorphNormals ) {

			geometryGroup.__morphNormalsArrays = [];

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

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

689 690 691
			}

		}
692

693
		geometryGroup.__webglFaceCount = ntris * 3;
694
		geometryGroup.__webglLineCount = nlines * 2;
695

M
Mr.doob 已提交
696

697
		// custom attributes
M
Mr.doob 已提交
698

699
		if ( material.attributes ) {
700

701
			if ( geometryGroup.__webglCustomAttributesList === undefined ) {
702

703
				geometryGroup.__webglCustomAttributesList = [];
704

705
			}
706

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

709 710
				// Do a shallow copy of the attribute object so different geometryGroup chunks use different
				// attribute buffers which are correctly indexed in the setMeshBuffers function
711

712
				var originalAttribute = material.attributes[ a ];
713

714
				var attribute = {};
715

716
				for ( var property in originalAttribute ) {
M
Mr.doob 已提交
717

718
					attribute[ property ] = originalAttribute[ property ];
719

720
				}
721

722
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
723

724
					attribute.__webglInitialized = true;
725

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

728 729 730 731
					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;
732

733
					attribute.size = size;
A
alteredq 已提交
734

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

737 738
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
739

740 741
					originalAttribute.needsUpdate = true;
					attribute.__original = originalAttribute;
742 743 744

				}

745 746
				geometryGroup.__webglCustomAttributesList.push( attribute );

747
			}
M
Mr.doob 已提交
748

749
		}
750

751 752
		geometryGroup.__inittedArrays = true;

753
	};
M
Mr.doob 已提交
754

755
	function getBufferMaterial( object, geometryGroup ) {
756

757
		if ( object.material && ! ( object.material instanceof THREE.MeshFaceMaterial ) ) {
758

759
			return object.material;
760

761
		} else if ( geometryGroup.materialIndex >= 0 ) {
762

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

765
		}
766

767
	};
M
Mr.doob 已提交
768

769
	function materialNeedsSmoothNormals ( material ) {
770

771
		return material && material.shading !== undefined && material.shading === THREE.SmoothShading;
772

773
	};
M
Mr.doob 已提交
774

775
	function bufferGuessNormalType ( material ) {
776

777
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
778

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

781
			return false;
782

783
		}
784

785
		if ( materialNeedsSmoothNormals( material ) ) {
786

787
			return THREE.SmoothShading;
M
Mr.doob 已提交
788

789
		} else {
790

791
			return THREE.FlatShading;
792

793
		}
794

795
	};
796

797
	function bufferGuessVertexColorType ( material ) {
798

799
		if ( material.vertexColors ) {
800

801
			return material.vertexColors;
802

803
		}
M
Mr.doob 已提交
804

805
		return false;
M
Mr.doob 已提交
806

807
	};
M
Mr.doob 已提交
808

809
	function bufferGuessUVType ( material ) {
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
		// 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 ) {

A
alteredq 已提交
851 852
			_projScreenMatrixPS.copy( _projScreenMatrix );
			_projScreenMatrixPS.multiplySelf( object.matrixWorld );
853 854 855 856 857 858

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

				vertex = vertices[ v ].position;

				_vector3.copy( vertex );
A
alteredq 已提交
859
				_projScreenMatrixPS.multiplyVector3( _vector3 );
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

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

		}

	};

1356
	function setMeshBuffers( geometryGroup, object, hint, dispose, material ) {
1357 1358 1359 1360 1361 1362 1363 1364

		if ( ! geometryGroup.__inittedArrays ) {

			// console.log( object );
			return;

		}

1365 1366 1367 1368 1369 1370
		var normalType = bufferGuessNormalType( material ),
		vertexColorType = bufferGuessVertexColorType( material ),
		uvType = bufferGuessUVType( material ),

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

1371 1372 1373 1374
		var f, fl, fi, face,
		vertexNormals, faceNormal, normal,
		vertexColors, faceColor,
		vertexTangents,
A
alteredq 已提交
1375
		uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4, n1, n2, n3, n4,
1376 1377 1378 1379 1380 1381 1382 1383
		c1, c2, c3, c4,
		sw1, sw2, sw3, sw4,
		si1, si2, si3, si4,
		sa1, sa2, sa3, sa4,
		sb1, sb2, sb3, sb4,
		m, ml, i, il,
		vn, uvi, uv2i,
		vk, vkl, vka,
A
alteredq 已提交
1384
		nka, chf, faceVertexNormals,
1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416
		a,

		vertexIndex = 0,

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

		value,

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

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

		morphTargetsArrays = geometryGroup.__morphTargetsArrays,
A
alteredq 已提交
1417
		morphNormalsArrays = geometryGroup.__morphNormalsArrays,
1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449

		customAttributes = geometryGroup.__webglCustomAttributesList,
		customAttribute,

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

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

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

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

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

		obj_colors = geometry.colors,

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

A
alteredq 已提交
1450 1451
		morphTargets = geometry.morphTargets,
		morphNormals = geometry.morphNormals;
1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473

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

1475
				offset += 9;
M
Mr.doob 已提交
1476

1477
			}
1478

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

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

A
alteredq 已提交
1483 1484 1485 1486
				v1 = vertices[ face.a ].position;
				v2 = vertices[ face.b ].position;
				v3 = vertices[ face.c ].position;
				v4 = vertices[ face.d ].position;
1487

A
alteredq 已提交
1488 1489 1490
				vertexArray[ offset ]     = v1.x;
				vertexArray[ offset + 1 ] = v1.y;
				vertexArray[ offset + 2 ] = v1.z;
1491

A
alteredq 已提交
1492 1493 1494
				vertexArray[ offset + 3 ] = v2.x;
				vertexArray[ offset + 4 ] = v2.y;
				vertexArray[ offset + 5 ] = v2.z;
1495

A
alteredq 已提交
1496 1497 1498
				vertexArray[ offset + 6 ] = v3.x;
				vertexArray[ offset + 7 ] = v3.y;
				vertexArray[ offset + 8 ] = v3.z;
1499

A
alteredq 已提交
1500 1501 1502
				vertexArray[ offset + 9 ]  = v4.x;
				vertexArray[ offset + 10 ] = v4.y;
				vertexArray[ offset + 11 ] = v4.z;
1503

A
alteredq 已提交
1504
				offset += 12;
1505

A
alteredq 已提交
1506
			}
1507

A
alteredq 已提交
1508 1509
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1510

A
alteredq 已提交
1511
		}
M
Mr.doob 已提交
1512

A
alteredq 已提交
1513
		if ( dirtyMorphTargets ) {
M
Mr.doob 已提交
1514

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

1517
				offset_morphTarget = 0;
1518

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

A
alteredq 已提交
1521 1522 1523 1524
					chf = chunk_faces3[ f ];
					face = obj_faces[ chf ];

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

A
alteredq 已提交
1526 1527 1528
					v1 = morphTargets[ vk ].vertices[ face.a ].position;
					v2 = morphTargets[ vk ].vertices[ face.b ].position;
					v3 = morphTargets[ vk ].vertices[ face.c ].position;
M
Mr.doob 已提交
1529

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

A
alteredq 已提交
1532 1533 1534
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
M
Mr.doob 已提交
1535

A
alteredq 已提交
1536 1537 1538
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
M
Mr.doob 已提交
1539

A
alteredq 已提交
1540 1541 1542
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
M
Mr.doob 已提交
1543

A
alteredq 已提交
1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581
					// morph normals

					if ( material.morphNormals ) {

						if ( needsSmoothNormals ) {

							faceVertexNormals = morphNormals[ vk ].vertexNormals[ chf ];

							n1 = faceVertexNormals.a;
							n2 = faceVertexNormals.b;
							n3 = faceVertexNormals.c;

						} else {

							n1 = morphNormals[ vk ].faceNormals[ chf ];
							n2 = n1;
							n3 = n1;

						}

						nka = morphNormalsArrays[ vk ];

						nka[ offset_morphTarget ] 	  = n1.x;
						nka[ offset_morphTarget + 1 ] = n1.y;
						nka[ offset_morphTarget + 2 ] = n1.z;

						nka[ offset_morphTarget + 3 ] = n2.x;
						nka[ offset_morphTarget + 4 ] = n2.y;
						nka[ offset_morphTarget + 5 ] = n2.z;

						nka[ offset_morphTarget + 6 ] = n3.x;
						nka[ offset_morphTarget + 7 ] = n3.y;
						nka[ offset_morphTarget + 8 ] = n3.z;

					}

					//

1582
					offset_morphTarget += 9;
1583

1584
				}
1585

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

A
alteredq 已提交
1588 1589 1590 1591
					chf = chunk_faces4[ f ];
					face = obj_faces[ chf ];

					// morph positions
1592

1593 1594 1595
					v1 = morphTargets[ vk ].vertices[ face.a ].position;
					v2 = morphTargets[ vk ].vertices[ face.b ].position;
					v3 = morphTargets[ vk ].vertices[ face.c ].position;
A
alteredq 已提交
1596
					v4 = morphTargets[ vk ].vertices[ face.d ].position;
1597

1598
					vka = morphTargetsArrays[ vk ];
1599

1600 1601 1602
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
1603

1604 1605 1606
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
1607

1608 1609 1610
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
1611

A
alteredq 已提交
1612 1613 1614 1615
					vka[ offset_morphTarget + 9 ]  = v4.x;
					vka[ offset_morphTarget + 10 ] = v4.y;
					vka[ offset_morphTarget + 11 ] = v4.z;

A
alteredq 已提交
1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659
					// morph normals

					if ( material.morphNormals ) {

						if ( needsSmoothNormals ) {

							faceVertexNormals = morphNormals[ vk ].vertexNormals[ chf ];

							n1 = faceVertexNormals.a;
							n2 = faceVertexNormals.b;
							n3 = faceVertexNormals.c;
							n4 = faceVertexNormals.d;

						} else {

							n1 = morphNormals[ vk ].faceNormals[ chf ];
							n2 = n1;
							n3 = n1;
							n4 = n1;

						}

						nka = morphNormalsArrays[ vk ];

						nka[ offset_morphTarget ] 	  = n1.x;
						nka[ offset_morphTarget + 1 ] = n1.y;
						nka[ offset_morphTarget + 2 ] = n1.z;

						nka[ offset_morphTarget + 3 ] = n2.x;
						nka[ offset_morphTarget + 4 ] = n2.y;
						nka[ offset_morphTarget + 5 ] = n2.z;

						nka[ offset_morphTarget + 6 ] = n3.x;
						nka[ offset_morphTarget + 7 ] = n3.y;
						nka[ offset_morphTarget + 8 ] = n3.z;

						nka[ offset_morphTarget + 9 ]  = n4.x;
						nka[ offset_morphTarget + 10 ] = n4.y;
						nka[ offset_morphTarget + 11 ] = n4.z;

					}

					//

1660
					offset_morphTarget += 12;
A
alteredq 已提交
1661

1662
				}
A
alteredq 已提交
1663 1664 1665

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

A
alteredq 已提交
1667 1668 1669 1670 1671 1672 1673
				if ( material.morphNormals ) {

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

				}

1674
			}
1675

A
alteredq 已提交
1676 1677 1678 1679 1680 1681 1682
		}

		if ( obj_skinWeights.length ) {

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

				face = obj_faces[ chunk_faces3[ f ]	];
1683

1684
				// weights
A
alteredq 已提交
1685

1686 1687 1688
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
A
alteredq 已提交
1689

1690 1691 1692 1693
				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 已提交
1694

1695 1696 1697 1698
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1699

1700 1701 1702 1703
				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 已提交
1704

1705
				// indices
A
alteredq 已提交
1706

1707 1708 1709
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
A
alteredq 已提交
1710

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

1716 1717 1718 1719
				skinIndexArray[ offset_skin + 4 ] = si2.x;
				skinIndexArray[ offset_skin + 5 ] = si2.y;
				skinIndexArray[ offset_skin + 6 ] = si2.z;
				skinIndexArray[ offset_skin + 7 ] = si2.w;
1720

1721 1722 1723 1724
				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 已提交
1725

1726
				// vertices A
A
alteredq 已提交
1727

1728 1729 1730
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
A
alteredq 已提交
1731

1732 1733 1734 1735
				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 已提交
1736

1737 1738 1739 1740
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1741

1742 1743 1744 1745
				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 已提交
1746

1747
				// vertices B
A
alteredq 已提交
1748

1749 1750 1751
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
A
alteredq 已提交
1752

1753 1754 1755 1756
				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 已提交
1757

1758 1759 1760 1761
				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
				skinVertexBArray[ offset_skin + 7 ] = 1;
1762

1763 1764 1765 1766
				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
				skinVertexBArray[ offset_skin + 11 ] = 1;
1767

1768
				offset_skin += 12;
1769

1770
			}
1771

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

A
alteredq 已提交
1774
				face = obj_faces[ chunk_faces4[ f ] ];
1775

A
alteredq 已提交
1776
				// weights
1777

A
alteredq 已提交
1778 1779 1780 1781
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
				sw4 = obj_skinWeights[ face.d ];
1782

A
alteredq 已提交
1783 1784 1785 1786
				skinWeightArray[ offset_skin ]     = sw1.x;
				skinWeightArray[ offset_skin + 1 ] = sw1.y;
				skinWeightArray[ offset_skin + 2 ] = sw1.z;
				skinWeightArray[ offset_skin + 3 ] = sw1.w;
1787

A
alteredq 已提交
1788 1789 1790 1791
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1792

A
alteredq 已提交
1793 1794 1795 1796
				skinWeightArray[ offset_skin + 8 ]  = sw3.x;
				skinWeightArray[ offset_skin + 9 ]  = sw3.y;
				skinWeightArray[ offset_skin + 10 ] = sw3.z;
				skinWeightArray[ offset_skin + 11 ] = sw3.w;
1797

A
alteredq 已提交
1798 1799 1800 1801
				skinWeightArray[ offset_skin + 12 ] = sw4.x;
				skinWeightArray[ offset_skin + 13 ] = sw4.y;
				skinWeightArray[ offset_skin + 14 ] = sw4.z;
				skinWeightArray[ offset_skin + 15 ] = sw4.w;
1802

A
alteredq 已提交
1803
				// indices
1804

A
alteredq 已提交
1805 1806 1807 1808
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
				si4 = obj_skinIndices[ face.d ];
1809

A
alteredq 已提交
1810 1811 1812 1813
				skinIndexArray[ offset_skin ]     = si1.x;
				skinIndexArray[ offset_skin + 1 ] = si1.y;
				skinIndexArray[ offset_skin + 2 ] = si1.z;
				skinIndexArray[ offset_skin + 3 ] = si1.w;
1814

A
alteredq 已提交
1815 1816 1817 1818
				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 已提交
1819

A
alteredq 已提交
1820 1821 1822 1823
				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 已提交
1824

A
alteredq 已提交
1825 1826 1827 1828
				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 已提交
1829

A
alteredq 已提交
1830
				// vertices A
M
Mr.doob 已提交
1831

A
alteredq 已提交
1832 1833 1834 1835
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
				sa4 = obj_skinVerticesA[ face.d ];
1836

A
alteredq 已提交
1837 1838 1839 1840
				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 已提交
1841

A
alteredq 已提交
1842 1843 1844 1845
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1846

A
alteredq 已提交
1847 1848 1849 1850
				skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
				skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
				skinVertexAArray[ offset_skin + 10 ] = sa3.z;
				skinVertexAArray[ offset_skin + 11 ] = 1;
1851

A
alteredq 已提交
1852 1853 1854 1855
				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 已提交
1856

A
alteredq 已提交
1857
				// vertices B
M
Mr.doob 已提交
1858

A
alteredq 已提交
1859 1860 1861 1862
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
				sb4 = obj_skinVerticesB[ face.d ];
M
Mr.doob 已提交
1863

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

A
alteredq 已提交
1869 1870 1871 1872
				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
				skinVertexBArray[ offset_skin + 7 ] = 1;
1873

A
alteredq 已提交
1874 1875 1876 1877
				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
				skinVertexBArray[ offset_skin + 11 ] = 1;
1878

A
alteredq 已提交
1879 1880 1881 1882
				skinVertexBArray[ offset_skin + 12 ] = sb4.x;
				skinVertexBArray[ offset_skin + 13 ] = sb4.y;
				skinVertexBArray[ offset_skin + 14 ] = sb4.z;
				skinVertexBArray[ offset_skin + 15 ] = 1;
1883

A
alteredq 已提交
1884
				offset_skin += 16;
M
Mr.doob 已提交
1885

A
alteredq 已提交
1886
			}
M
Mr.doob 已提交
1887

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

A
alteredq 已提交
1890 1891
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );
M
Mr.doob 已提交
1892

A
alteredq 已提交
1893 1894 1895 1896 1897 1898 1899 1900
				_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 );
1901

1902
			}
1903

A
alteredq 已提交
1904
		}
M
Mr.doob 已提交
1905

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

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

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

A
alteredq 已提交
1912 1913
				vertexColors = face.vertexColors;
				faceColor = face.color;
1914

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

A
alteredq 已提交
1917 1918 1919
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
1920

A
alteredq 已提交
1921
				} else {
1922

A
alteredq 已提交
1923 1924 1925
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
1926

A
alteredq 已提交
1927
				}
1928

A
alteredq 已提交
1929 1930 1931
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
1932

A
alteredq 已提交
1933 1934 1935
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
1936

A
alteredq 已提交
1937 1938 1939
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
1940

A
alteredq 已提交
1941
				offset_color += 9;
M
Mr.doob 已提交
1942

A
alteredq 已提交
1943
			}
M
Mr.doob 已提交
1944

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

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

A
alteredq 已提交
1949 1950
				vertexColors = face.vertexColors;
				faceColor = face.color;
M
Mr.doob 已提交
1951

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

A
alteredq 已提交
1954 1955 1956 1957
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
					c4 = vertexColors[ 3 ];
1958

A
alteredq 已提交
1959
				} else {
M
Mr.doob 已提交
1960

A
alteredq 已提交
1961 1962 1963 1964
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
					c4 = faceColor;
M
Mr.doob 已提交
1965

A
alteredq 已提交
1966
				}
1967

A
alteredq 已提交
1968 1969 1970
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
1971

A
alteredq 已提交
1972 1973 1974
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
M
Mr.doob 已提交
1975

A
alteredq 已提交
1976 1977 1978
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
M
Mr.doob 已提交
1979

A
alteredq 已提交
1980 1981 1982
				colorArray[ offset_color + 9 ]  = c4.r;
				colorArray[ offset_color + 10 ] = c4.g;
				colorArray[ offset_color + 11 ] = c4.b;
M
Mr.doob 已提交
1983

A
alteredq 已提交
1984
				offset_color += 12;
1985

1986
			}
1987

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

A
alteredq 已提交
1990 1991
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
M
Mr.doob 已提交
1992

1993
			}
1994

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

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

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

A
alteredq 已提交
2001
				face = obj_faces[ chunk_faces3[ f ]	];
2002

A
alteredq 已提交
2003
				vertexTangents = face.vertexTangents;
M
Mr.doob 已提交
2004

A
alteredq 已提交
2005 2006 2007
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
2008

A
alteredq 已提交
2009 2010 2011 2012
				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 已提交
2013

A
alteredq 已提交
2014 2015 2016 2017
				tangentArray[ offset_tangent + 4 ] = t2.x;
				tangentArray[ offset_tangent + 5 ] = t2.y;
				tangentArray[ offset_tangent + 6 ] = t2.z;
				tangentArray[ offset_tangent + 7 ] = t2.w;
2018

A
alteredq 已提交
2019 2020 2021 2022
				tangentArray[ offset_tangent + 8 ]  = t3.x;
				tangentArray[ offset_tangent + 9 ]  = t3.y;
				tangentArray[ offset_tangent + 10 ] = t3.z;
				tangentArray[ offset_tangent + 11 ] = t3.w;
2023

A
alteredq 已提交
2024
				offset_tangent += 12;
2025

2026
			}
2027

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

A
alteredq 已提交
2030
				face = obj_faces[ chunk_faces4[ f ] ];
2031

A
alteredq 已提交
2032
				vertexTangents = face.vertexTangents;
2033

A
alteredq 已提交
2034 2035 2036 2037
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
				t4 = vertexTangents[ 3 ];
2038

A
alteredq 已提交
2039 2040 2041 2042
				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 已提交
2043

A
alteredq 已提交
2044 2045 2046 2047
				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 已提交
2048

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

A
alteredq 已提交
2054 2055 2056 2057
				tangentArray[ offset_tangent + 12 ] = t4.x;
				tangentArray[ offset_tangent + 13 ] = t4.y;
				tangentArray[ offset_tangent + 14 ] = t4.z;
				tangentArray[ offset_tangent + 15 ] = t4.w;
2058

A
alteredq 已提交
2059
				offset_tangent += 16;
2060

A
alteredq 已提交
2061
			}
2062

A
alteredq 已提交
2063 2064
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
2065

A
alteredq 已提交
2066
		}
2067

A
alteredq 已提交
2068
		if ( dirtyNormals && normalType ) {
2069

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

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

A
alteredq 已提交
2074 2075
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
2076

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

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

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

A
alteredq 已提交
2083 2084 2085
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
2086

A
alteredq 已提交
2087
						offset_normal += 3;
2088

A
alteredq 已提交
2089
					}
2090

A
alteredq 已提交
2091
				} else {
M
Mr.doob 已提交
2092

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

A
alteredq 已提交
2095 2096 2097
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
2098

A
alteredq 已提交
2099
						offset_normal += 3;
M
Mr.doob 已提交
2100

A
alteredq 已提交
2101
					}
2102

A
alteredq 已提交
2103
				}
2104

A
alteredq 已提交
2105
			}
2106

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

A
alteredq 已提交
2109
				face = obj_faces[ chunk_faces4[ f ] ];
2110

A
alteredq 已提交
2111 2112
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
2113

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

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

A
alteredq 已提交
2118
						vn = vertexNormals[ i ];
2119

A
alteredq 已提交
2120 2121 2122
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
2123

A
alteredq 已提交
2124
						offset_normal += 3;
2125

A
alteredq 已提交
2126
					}
M
Mr.doob 已提交
2127

A
alteredq 已提交
2128
				} else {
2129

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

A
alteredq 已提交
2132 2133 2134
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
2135

A
alteredq 已提交
2136
						offset_normal += 3;
M
Mr.doob 已提交
2137

A
alteredq 已提交
2138
					}
2139

A
alteredq 已提交
2140
				}
2141

A
alteredq 已提交
2142
			}
M
Mr.doob 已提交
2143

A
alteredq 已提交
2144 2145
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
2146

A
alteredq 已提交
2147
		}
M
Mr.doob 已提交
2148

A
alteredq 已提交
2149
		if ( dirtyUvs && obj_uvs && uvType ) {
2150

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

A
alteredq 已提交
2153
				fi = chunk_faces3[ f ];
2154

A
alteredq 已提交
2155 2156
				face = obj_faces[ fi ];
				uv = obj_uvs[ fi ];
2157

A
alteredq 已提交
2158
				if ( uv === undefined ) continue;
2159

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

A
alteredq 已提交
2162
					uvi = uv[ i ];
2163

A
alteredq 已提交
2164 2165
					uvArray[ offset_uv ]     = uvi.u;
					uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
2166

A
alteredq 已提交
2167
					offset_uv += 2;
M
Mr.doob 已提交
2168

A
alteredq 已提交
2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189
				}

			}

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

2191 2192
				}

2193
			}
2194

A
alteredq 已提交
2195
			if ( offset_uv > 0 ) {
2196

A
alteredq 已提交
2197 2198
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
2199

A
alteredq 已提交
2200
			}
2201

A
alteredq 已提交
2202
		}
2203

A
alteredq 已提交
2204
		if ( dirtyUvs && obj_uvs2 && uvType ) {
2205

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

A
alteredq 已提交
2208
				fi = chunk_faces3[ f ];
2209

A
alteredq 已提交
2210 2211
				face = obj_faces[ fi ];
				uv2 = obj_uvs2[ fi ];
2212

A
alteredq 已提交
2213 2214 2215 2216 2217 2218 2219 2220 2221 2222
				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;
2223

2224 2225
				}

A
alteredq 已提交
2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246
			}

			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;

				}
2247

2248
			}
2249

A
alteredq 已提交
2250
			if ( offset_uv2 > 0 ) {
2251

A
alteredq 已提交
2252 2253
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );
2254

A
alteredq 已提交
2255
			}
2256

A
alteredq 已提交
2257
		}
2258

A
alteredq 已提交
2259
		if ( dirtyElements ) {
2260

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

A
alteredq 已提交
2263
				face = obj_faces[ chunk_faces3[ f ]	];
2264

A
alteredq 已提交
2265 2266 2267
				faceArray[ offset_face ] 	 = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 2;
2268

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

A
alteredq 已提交
2271 2272
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2273

A
alteredq 已提交
2274 2275
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 2;
2276

A
alteredq 已提交
2277 2278
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
2279

A
alteredq 已提交
2280
				offset_line += 6;
2281

A
alteredq 已提交
2282
				vertexIndex += 3;
2283

A
alteredq 已提交
2284
			}
2285

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

A
alteredq 已提交
2288
				face = obj_faces[ chunk_faces4[ f ] ];
2289

A
alteredq 已提交
2290 2291 2292
				faceArray[ offset_face ]     = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 3;
2293

A
alteredq 已提交
2294 2295 2296
				faceArray[ offset_face + 3 ] = vertexIndex + 1;
				faceArray[ offset_face + 4 ] = vertexIndex + 2;
				faceArray[ offset_face + 5 ] = vertexIndex + 3;
2297

A
alteredq 已提交
2298
				offset_face += 6;
2299

A
alteredq 已提交
2300 2301
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
2302

A
alteredq 已提交
2303 2304
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 3;
2305

A
alteredq 已提交
2306 2307
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
2308

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

A
alteredq 已提交
2312
				offset_line += 8;
2313

A
alteredq 已提交
2314
				vertexIndex += 4;
2315

2316
			}
2317

A
alteredq 已提交
2318 2319
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
2320

A
alteredq 已提交
2321 2322
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
2323

A
alteredq 已提交
2324
		}
2325

A
alteredq 已提交
2326
		if ( customAttributes ) {
2327

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

2330
				customAttribute = customAttributes[ i ];
2331

2332
				if ( ! customAttribute.__original.needsUpdate ) continue;
2333

2334 2335
				offset_custom = 0;
				offset_customSrc = 0;
2336

2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369
				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 ++ ) {

2370
							value = customAttribute.value[ chunk_faces3[ f ] ];
2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381

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

2382
							value = customAttribute.value[ chunk_faces4[ f ] ];
2383 2384 2385 2386 2387 2388 2389 2390 2391

							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;

						}
2392

2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411
					}

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

2413 2414
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2415

2416
							offset_custom += 6;
A
alteredq 已提交
2417

2418
						}
A
alteredq 已提交
2419

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

2422
							face = obj_faces[ chunk_faces4[ f ] ];
A
alteredq 已提交
2423

2424 2425 2426 2427
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
A
alteredq 已提交
2428

2429 2430
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2431

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

2435 2436
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2437

2438 2439
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
A
alteredq 已提交
2440

2441
							offset_custom += 8;
A
alteredq 已提交
2442

2443
						}
A
alteredq 已提交
2444

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

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

2449
							value = customAttribute.value[ chunk_faces3[ f ] ];
A
alteredq 已提交
2450

2451 2452 2453
							v1 = value;
							v2 = value;
							v3 = value;
A
alteredq 已提交
2454

2455 2456
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2457

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

2461 2462
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2463

2464
							offset_custom += 6;
A
alteredq 已提交
2465

2466
						}
A
alteredq 已提交
2467

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

2470
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2471

2472 2473 2474 2475
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2476

2477 2478
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
2479

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

2483 2484
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
2485

2486 2487
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
2488

2489
							offset_custom += 8;
M
Mr.doob 已提交
2490

2491
						}
M
Mr.doob 已提交
2492

M
Mr.doob 已提交
2493
					}
M
Mr.doob 已提交
2494

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

2497
					var pp;
2498

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

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

2503
					} else {
M
Mr.doob 已提交
2504

2505
						pp = [ "x", "y", "z" ];
2506

2507
					}
2508

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

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

2513
							face = obj_faces[ chunk_faces3[ f ]	];
2514

2515 2516 2517
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
2518

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

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

2527 2528 2529
							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 已提交
2530

2531
							offset_custom += 9;
M
Mr.doob 已提交
2532

2533
						}
M
Mr.doob 已提交
2534

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

2537
							face = obj_faces[ chunk_faces4[ f ] ];
M
Mr.doob 已提交
2538

2539 2540 2541 2542
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
M
Mr.doob 已提交
2543

2544 2545 2546
							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 已提交
2547

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

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

2556 2557 2558
							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 已提交
2559

2560
							offset_custom += 12;
M
Mr.doob 已提交
2561

2562
						}
M
Mr.doob 已提交
2563

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

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

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

2570 2571 2572
							v1 = value;
							v2 = value;
							v3 = value;
M
Mr.doob 已提交
2573

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

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

2582 2583 2584
							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 已提交
2585

2586
							offset_custom += 9;
M
Mr.doob 已提交
2587

2588
						}
2589

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

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

2594 2595 2596 2597
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
2598

2599 2600 2601
							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
2602

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

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

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

2615
							offset_custom += 12;
2616

2617
						}
2618

A
alteredq 已提交
2619
					}
M
Mr.doob 已提交
2620

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

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

2625
						for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
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 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688
							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 ++ ) {

2689
							value = customAttribute.value[ chunk_faces3[ f ] ];
2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706

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

2710
							offset_custom += 12;
A
alteredq 已提交
2711

2712 2713
						}

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

2716
							value = customAttribute.value[ chunk_faces4[ f ] ];
A
alteredq 已提交
2717

2718 2719 2720 2721
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
2722

2723 2724 2725 2726
							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;
2727

2728 2729 2730 2731
							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;
2732

2733 2734 2735 2736
							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;
2737

2738 2739 2740 2741
							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;
2742

2743
							offset_custom += 16;
A
alteredq 已提交
2744

2745
						}
A
alteredq 已提交
2746 2747 2748 2749 2750

					}

				}

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

A
alteredq 已提交
2754 2755 2756 2757
			}

		}

2758
		if ( dispose ) {
2759

2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772
			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 已提交
2773

2774
		}
A
alteredq 已提交
2775

2776
	};
A
alteredq 已提交
2777

2778
	// Buffer rendering
A
alteredq 已提交
2779

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

2782 2783
		if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
A
alteredq 已提交
2784

2785
		if ( object.hasPos ) {
A
alteredq 已提交
2786

2787 2788 2789 2790
			_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 已提交
2791 2792 2793

		}

2794
		if ( object.hasNormal ) {
A
alteredq 已提交
2795

2796
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
A
alteredq 已提交
2797

2798
			if ( shading === THREE.FlatShading ) {
2799

2800 2801 2802 2803
				var nx, ny, nz,
					nax, nbx, ncx, nay, nby, ncy, naz, nbz, ncz,
					normalArray,
					i, il = object.count * 3;
2804

2805
				for( i = 0; i < il; i += 9 ) {
2806

2807
					normalArray = object.normalArray;
2808

2809 2810 2811
					nax  = normalArray[ i ];
					nay  = normalArray[ i + 1 ];
					naz  = normalArray[ i + 2 ];
2812

2813 2814 2815
					nbx  = normalArray[ i + 3 ];
					nby  = normalArray[ i + 4 ];
					nbz  = normalArray[ i + 5 ];
2816

2817 2818 2819
					ncx  = normalArray[ i + 6 ];
					ncy  = normalArray[ i + 7 ];
					ncz  = normalArray[ i + 8 ];
2820

2821 2822 2823
					nx = ( nax + nbx + ncx ) / 3;
					ny = ( nay + nby + ncy ) / 3;
					nz = ( naz + nbz + ncz ) / 3;
2824

2825 2826 2827
					normalArray[ i ] 	 = nx;
					normalArray[ i + 1 ] = ny;
					normalArray[ i + 2 ] = nz;
2828

2829 2830 2831
					normalArray[ i + 3 ] = nx;
					normalArray[ i + 4 ] = ny;
					normalArray[ i + 5 ] = nz;
2832

2833 2834 2835
					normalArray[ i + 6 ] = nx;
					normalArray[ i + 7 ] = ny;
					normalArray[ i + 8 ] = nz;
2836

2837
				}
2838

2839
			}
2840

2841 2842 2843
			_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 );
2844

2845
		}
2846

2847
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );
2848

2849
		object.count = 0;
2850

2851
	};
2852

2853 2854 2855 2856
	this.renderBufferDirect = function ( camera, lights, fog, material, geometryGroup, object ) {

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

2857
		var program, attributes, linewidth, primitives, a, attribute;
2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879

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

		attributes = program.attributes;

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

		if ( geometryGroupHash !== _currentGeometryGroupHash ) {

			_currentGeometryGroupHash = geometryGroupHash;
			updateBuffers = true;

		}

		// render mesh

		if ( object instanceof THREE.Mesh ) {

			var offsets = geometryGroup.offsets;

2880
			for ( var i = 0, il = offsets.length; i < il; ++ i ) {
2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944

				if ( updateBuffers ) {

					// vertices

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

					// normals

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

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

					}

					// uvs

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

						if ( geometryGroup.vertexUvBuffer ) {

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

							_gl.enableVertexAttribArray( attributes.uv );

						} else {

							_gl.disableVertexAttribArray( attributes.uv );

						}

					}

					// colors

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

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


					}

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

				}

				// render indexed triangles

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

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

			}

		}

	};

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

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

2949
		var program, attributes, linewidth, primitives, a, attribute, i, il;
2950

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

2953
		attributes = program.attributes;
2954

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

2959
		if ( geometryGroupHash !== _currentGeometryGroupHash ) {
A
alteredq 已提交
2960

2961 2962
			_currentGeometryGroupHash = geometryGroupHash;
			updateBuffers = true;
2963

2964
		}
2965

2966
		// vertices
2967

2968
		if ( !material.morphTargets && attributes.position >= 0 ) {
2969

2970
			if ( updateBuffers ) {
2971

2972 2973
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
				_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
2974

2975
			}
2976

2977
		} else {
2978

2979
			if ( object.morphTargetBase ) {
2980

2981
				setupMorphTargets( material, geometryGroup, object );
2982

2983
			}
2984

2985
		}
2986

2987

2988
		if ( updateBuffers ) {
2989

2990
			// custom attributes
2991

2992
			// Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
2993

2994
			if ( geometryGroup.__webglCustomAttributesList ) {
2995

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

2998
					attribute = geometryGroup.__webglCustomAttributesList[ i ];
2999

3000
					if( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
3001

3002 3003
						_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
						_gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 );
3004

3005
					}
3006

3007
				}
3008

3009
			}
3010 3011


3012
			// colors
3013

3014
			if ( attributes.color >= 0 ) {
3015

3016 3017
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
3018

3019
			}
3020

3021
			// normals
3022

3023
			if ( attributes.normal >= 0 ) {
3024

3025 3026
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
				_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
3027

3028
			}
3029

3030
			// tangents
3031

3032
			if ( attributes.tangent >= 0 ) {
3033

3034 3035
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
				_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
3036

3037
			}
3038

3039
			// uvs
3040

3041
			if ( attributes.uv >= 0 ) {
3042

3043
				if ( geometryGroup.__webglUVBuffer ) {
3044

3045 3046
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
					_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
3047

3048
					_gl.enableVertexAttribArray( attributes.uv );
3049

3050
				} else {
3051

3052
					_gl.disableVertexAttribArray( attributes.uv );
3053 3054 3055 3056 3057

				}

			}

3058
			if ( attributes.uv2 >= 0 ) {
3059

3060
				if ( geometryGroup.__webglUV2Buffer ) {
3061

3062 3063
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
					_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
3064

3065
					_gl.enableVertexAttribArray( attributes.uv2 );
3066

3067
				} else {
3068

3069
					_gl.disableVertexAttribArray( attributes.uv2 );
3070 3071

				}
3072 3073

			}
3074

3075 3076 3077
			if ( material.skinning &&
				 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
				 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
A
alteredq 已提交
3078

3079 3080
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3081

3082 3083
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
				_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3084

3085 3086
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
				_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3087

3088 3089
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
				_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
3090

A
alteredq 已提交
3091
			}
3092

3093
		}
3094

3095
		// render mesh
3096

3097
		if ( object instanceof THREE.Mesh ) {
3098

3099
			// wireframe
3100

3101
			if ( material.wireframe ) {
3102

3103
				setLineWidth( material.wireframeLinewidth );
3104

3105 3106
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
3107

3108
			// triangles
3109

3110
			} else {
3111

3112 3113
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3114

3115
			}
3116

3117 3118 3119
			_this.info.render.calls ++;
			_this.info.render.vertices += geometryGroup.__webglFaceCount;
			_this.info.render.faces += geometryGroup.__webglFaceCount / 3;
3120

3121
		// render lines
3122

3123
		} else if ( object instanceof THREE.Line ) {
3124

3125
			primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
3126

3127
			setLineWidth( material.linewidth );
3128

3129
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
3130

3131
			_this.info.render.calls ++;
3132

3133
		// render particles
3134

3135
		} else if ( object instanceof THREE.ParticleSystem ) {
3136

3137
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
3138

3139
			_this.info.render.calls ++;
3140
			_this.info.render.points += geometryGroup.__webglParticleCount;
3141

3142
		// render ribbon
3143

3144
		} else if ( object instanceof THREE.Ribbon ) {
3145

3146
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
3147

3148
			_this.info.render.calls ++;
3149

3150
		}
3151

3152
	};
3153

3154
	function setupMorphTargets ( material, geometryGroup, object ) {
3155

3156
		// set base
3157

3158
		var attributes = material.program.attributes;
3159

3160
		if ( object.morphTargetBase !== - 1 ) {
3161

3162 3163
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3164

3165
		} else if ( attributes.position >= 0 ) {
3166

3167 3168
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3169

3170
		}
3171

3172
		if ( object.morphTargetForcedOrder.length ) {
3173

3174
			// set forced order
3175

3176 3177 3178 3179 3180
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;

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

3182 3183 3184
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ order[ m ] ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );

A
alteredq 已提交
3185 3186 3187 3188 3189 3190 3191
				if ( material.morphNormals ) {

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

				}

3192 3193 3194
				object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ] ];

				m ++;
3195 3196
			}

3197 3198 3199 3200 3201 3202 3203 3204 3205 3206
		} else {

			// find most influencing

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

3208
			if ( object.morphTargetBase !== - 1 ) {
3209

3210
				used[ object.morphTargetBase ] = true;
3211

3212
			}
3213

3214
			while ( m < material.numSupportedMorphTargets ) {
3215

3216
				for ( i = 0; i < il; i ++ ) {
3217

3218
					if ( !used[ i ] && influences[ i ] > candidateInfluence ) {
3219

3220 3221
						candidate = i;
						candidateInfluence = influences[ candidate ];
3222

3223
					}
3224

3225
				}
3226

3227 3228
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
3229

A
alteredq 已提交
3230 3231 3232 3233 3234 3235 3236
				if ( material.morphNormals ) {

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

				}

3237
				object.__webglMorphTargetInfluences[ m ] = candidateInfluence;
3238

3239 3240 3241
				used[ candidate ] = 1;
				candidateInfluence = -1;
				m ++;
3242 3243 3244 3245 3246

			}

		}

3247
		// load updated influences uniform
3248

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

3251
			_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
3252

3253
		}
3254

3255
	};
3256 3257


3258
	function painterSort ( a, b ) {
3259

3260
		return b.z - a.z;
3261

3262
	};
3263

3264
	// Rendering
3265

3266
	this.render = function ( scene, camera, renderTarget, forceClear ) {
3267

3268 3269 3270 3271 3272 3273
		var i, il,

		program, material,
		webglObject, object,
		renderList,

3274
		lights = scene.__lights,
3275
		fog = scene.fog;
M
Mr.doob 已提交
3276

3277
		_currentMaterialId = -1;
3278

A
alteredq 已提交
3279
		// update scene graph
3280

3281
		if ( camera.parent === undefined ) {
3282

3283 3284
			console.warn( 'DEPRECATED: Camera hasn\'t been added to a Scene. Adding it...' );
			scene.add( camera );
3285

3286
		}
3287

3288
		if ( this.autoUpdateScene ) scene.updateMatrixWorld();
3289

A
alteredq 已提交
3290
		// update camera matrices and frustum
A
alteredq 已提交
3291

A
alteredq 已提交
3292 3293
		if ( ! camera._viewMatrixArray ) camera._viewMatrixArray = new Float32Array( 16 );
		if ( ! camera._projectionMatrixArray ) camera._projectionMatrixArray = new Float32Array( 16 );
A
alteredq 已提交
3294

3295
		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
A
alteredq 已提交
3296 3297 3298

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

3300
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
A
alteredq 已提交
3301
		_frustum.setFromMatrix( _projScreenMatrix );
3302

A
alteredq 已提交
3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317
		// update WebGL objects

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

		// custom render plugins (pre pass)

		renderPlugins( this.renderPluginsPre, scene, camera );

		//

		_this.info.render.calls = 0;
		_this.info.render.vertices = 0;
		_this.info.render.faces = 0;
		_this.info.render.points = 0;

A
alteredq 已提交
3318
		this.setRenderTarget( renderTarget );
3319

3320
		if ( this.autoClear || forceClear ) {
3321

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

3324
		}
M
Mr.doob 已提交
3325

3326
		// set matrices for regular objects (frustum culled)
3327

3328
		renderList = scene.__webglObjects;
3329

3330
		for ( i = 0, il = renderList.length; i < il; i ++ ) {
3331

3332
			webglObject = renderList[ i ];
3333
			object = webglObject.object;
3334

A
alteredq 已提交
3335 3336
			webglObject.render = false;

3337
			if ( object.visible ) {
3338

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

3341
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
3342

A
alteredq 已提交
3343
					setupMatrices( object, camera );
3344

3345
					unrollBufferMaterial( webglObject );
3346

3347
					webglObject.render = true;
3348

3349
					if ( this.sortObjects ) {
3350

3351
						if ( object.renderDepth ) {
3352

3353
							webglObject.z = object.renderDepth;
M
Mr.doob 已提交
3354

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

3357
							_vector3.copy( object.matrixWorld.getPosition() );
3358
							_projScreenMatrix.multiplyVector3( _vector3 );
3359

3360
							webglObject.z = _vector3.z;
3361

3362
						}
M
Mr.doob 已提交
3363

3364
					}
M
Mr.doob 已提交
3365

3366
				}
3367 3368

			}
3369 3370 3371

		}

3372
		if ( this.sortObjects ) {
M
Mr.doob 已提交
3373

3374
			renderList.sort( painterSort );
3375

3376
		}
3377

3378
		// set matrices for immediate objects
3379

3380
		renderList = scene.__webglObjectsImmediate;
3381

3382 3383 3384
		for ( i = 0, il = renderList.length; i < il; i ++ ) {

			webglObject = renderList[ i ];
3385
			object = webglObject.object;
3386

3387
			if ( object.visible ) {
3388

3389
				if( object.matrixAutoUpdate ) {
3390

3391
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3392

3393
				}
M
Mr.doob 已提交
3394

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

3397
				unrollImmediateBufferMaterial( webglObject );
M
Mr.doob 已提交
3398

3399
			}
M
Mr.doob 已提交
3400

3401
		}
3402

3403
		if ( scene.overrideMaterial ) {
3404

3405
			this.setBlending( scene.overrideMaterial.blending );
A
alteredq 已提交
3406
			this.setDepthTest( scene.overrideMaterial.depthTest );
3407
			this.setDepthWrite( scene.overrideMaterial.depthWrite );
3408
			setPolygonOffset( scene.overrideMaterial.polygonOffset, scene.overrideMaterial.polygonOffsetFactor, scene.overrideMaterial.polygonOffsetUnits );
3409

3410 3411
			renderObjects( scene.__webglObjects, false, "", camera, lights, fog, true, scene.overrideMaterial );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "", camera, lights, fog, false, scene.overrideMaterial );
M
Mr.doob 已提交
3412

3413
		} else {
3414

3415
			// opaque pass (front-to-back order)
3416

3417
			this.setBlending( THREE.NormalBlending );
3418

3419 3420
			renderObjects( scene.__webglObjects, true, "opaque", camera, lights, fog, false );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "opaque", camera, lights, fog, false );
3421

3422
			// transparent pass (back-to-front order)
3423

3424 3425
			renderObjects( scene.__webglObjects, false, "transparent", camera, lights, fog, true );
			renderObjectsImmediate( scene.__webglObjectsImmediate, "transparent", camera, lights, fog, true );
3426

3427
		}
3428

A
alteredq 已提交
3429
		// custom render plugins (post pass)
3430

A
alteredq 已提交
3431
		renderPlugins( this.renderPluginsPost, scene, camera );
3432 3433


3434
		// Generate mipmap if we're using any kind of mipmap filtering
3435

3436
		if ( renderTarget && renderTarget.generateMipmaps && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {
3437

3438
			updateRenderTargetMipmap( renderTarget );
3439

3440
		}
3441

3442 3443 3444
		// Ensure depth buffer writing is enabled so it can be cleared on next render

		this.setDepthTest( true );
3445
		this.setDepthWrite( true );
3446

3447
		// _gl.finish();
3448

3449
	};
3450

A
alteredq 已提交
3451 3452 3453 3454 3455 3456 3457
	function renderPlugins( plugins, scene, camera ) {

		if ( ! plugins.length ) return;

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

			_currentProgram = null;
3458
			_currentCamera = null;
A
alteredq 已提交
3459 3460 3461 3462 3463 3464
			_oldBlending = -1;
			_oldDepthTest = -1;
			_oldDepthWrite = -1;
			_currentGeometryGroupHash = -1;
			_currentMaterialId = -1;

A
alteredq 已提交
3465
			plugins[ i ].render( scene, camera, _currentWidth, _currentHeight );
A
alteredq 已提交
3466 3467

			_currentProgram = null;
3468
			_currentCamera = null;
A
alteredq 已提交
3469 3470 3471 3472 3473 3474 3475 3476 3477 3478
			_oldBlending = -1;
			_oldDepthTest = -1;
			_oldDepthWrite = -1;
			_currentGeometryGroupHash = -1;
			_currentMaterialId = -1;

		}

	};

3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514
	function renderObjects ( renderList, reverse, materialType, camera, lights, fog, useBlending, overrideMaterial ) {

		var webglObject, object, buffer, material, start, end, delta;

		if ( reverse ) {

			start = renderList.length - 1;
			end = -1;
			delta = -1;

		} else {

			start = 0;
			end = renderList.length;
			delta = 1;
		}

		for ( var i = start; i !== end; i += delta ) {

			webglObject = renderList[ i ];

			if ( webglObject.render ) {

				object = webglObject.object;
				buffer = webglObject.buffer;

				if ( overrideMaterial ) {

					material = overrideMaterial;

				} else {

					material = webglObject[ materialType ];

					if ( ! material ) continue;

3515
					if ( useBlending ) _this.setBlending( material.blending );
3516

A
alteredq 已提交
3517
					_this.setDepthTest( material.depthTest );
3518
					_this.setDepthWrite( material.depthWrite );
3519 3520 3521 3522
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

A
alteredq 已提交
3523
				_this.setObjectFaces( object );
3524 3525 3526 3527 3528 3529 3530 3531 3532 3533

				if ( buffer instanceof THREE.BufferGeometry ) {

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

				} else {

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

				}
3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561

			}

		}

	};

	function renderObjectsImmediate ( renderList, materialType, camera, lights, fog, useBlending, overrideMaterial ) {

		var webglObject, object, material, program;

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

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

			if ( object.visible ) {

				if ( overrideMaterial ) {

					material = overrideMaterial;

				} else {

					material = webglObject[ materialType ];

					if ( ! material ) continue;

A
alteredq 已提交
3562
					if ( useBlending ) _this.setBlending( material.blending );
3563

A
alteredq 已提交
3564
					_this.setDepthTest( material.depthTest );
3565
					_this.setDepthWrite( material.depthWrite );
3566 3567 3568 3569
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );

				}

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

A
alteredq 已提交
3572
			}
3573

A
alteredq 已提交
3574
		}
3575

A
alteredq 已提交
3576
	};
3577

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

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

A
alteredq 已提交
3582
		_currentGeometryGroupHash = -1;
3583

A
alteredq 已提交
3584 3585 3586 3587 3588 3589 3590 3591 3592
		_this.setObjectFaces( object );

		if ( object.immediateRenderCallback ) {

			object.immediateRenderCallback( program, _gl, _frustum );

		} else {

			object.render( function( object ) { _this.renderBufferImmediate( object, program, material.shading ); } );
3593 3594 3595 3596 3597

		}

	};

3598
	function unrollImmediateBufferMaterial ( globject ) {
3599

3600 3601
		var object = globject.object,
			material = object.material;
3602

3603
		if ( material.transparent ) {
3604

3605 3606
			globject.transparent = material;
			globject.opaque = null;
3607

3608
		} else {
3609

3610 3611
			globject.opaque = material;
			globject.transparent = null;
3612

3613
		}
A
alteredq 已提交
3614

3615
	};
A
alteredq 已提交
3616

3617
	function unrollBufferMaterial ( globject ) {
A
alteredq 已提交
3618

3619 3620 3621
		var object = globject.object,
			buffer = globject.buffer,
			material, materialIndex, meshMaterial;
3622

3623
		meshMaterial = object.material;
3624

3625
		if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
M
Mr.doob 已提交
3626

3627
			materialIndex = buffer.materialIndex;
3628

3629
			if ( materialIndex >= 0 ) {
3630

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

3633
				if ( material.transparent ) {
M
Mr.doob 已提交
3634

3635 3636
					globject.transparent = material;
					globject.opaque = null;
3637

3638
				} else {
3639

3640 3641
					globject.opaque = material;
					globject.transparent = null;
3642

3643
				}
3644

3645
			}
3646

3647
		} else {
3648

3649
			material = meshMaterial;
3650

3651
			if ( material ) {
3652

3653
				if ( material.transparent ) {
M
Mr.doob 已提交
3654

3655 3656
					globject.transparent = material;
					globject.opaque = null;
A
alteredq 已提交
3657

3658
				} else {
3659

3660 3661
					globject.opaque = material;
					globject.transparent = null;
3662

3663
				}
3664

3665
			}
3666

3667
		}
3668

3669
	};
3670

3671
	// Geometry splitting
3672

3673
	function sortFacesByMaterial ( geometry ) {
3674

3675 3676 3677
		var f, fl, face, materialIndex, vertices,
			materialHash, groupHash,
			hash_map = {};
3678

3679
		var numMorphTargets = geometry.morphTargets.length;
3680
		var numMorphNormals = geometry.morphNormals.length;
3681

3682
		geometry.geometryGroups = {};
3683

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

3686 3687
			face = geometry.faces[ f ];
			materialIndex = face.materialIndex;
3688

3689
			materialHash = ( materialIndex !== undefined ) ? materialIndex : -1;
3690

3691
			if ( hash_map[ materialHash ] === undefined ) {
3692

3693
				hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 };
3694 3695 3696

			}

3697
			groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
3698

3699
			if ( geometry.geometryGroups[ groupHash ] === undefined ) {
3700

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

3703
			}
A
alteredq 已提交
3704

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

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

3709 3710
				hash_map[ materialHash ].counter += 1;
				groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
A
alteredq 已提交
3711

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

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

3716
				}
3717

3718
			}
3719

3720
			if ( face instanceof THREE.Face3 ) {
3721

3722
				geometry.geometryGroups[ groupHash ].faces3.push( f );
3723

3724
			} else {
3725

3726
				geometry.geometryGroups[ groupHash ].faces4.push( f );
3727

A
alteredq 已提交
3728
			}
3729

3730
			geometry.geometryGroups[ groupHash ].vertices += vertices;
3731

3732
		}
3733

3734
		geometry.geometryGroupsList = [];
3735

3736
		for ( var g in geometry.geometryGroups ) {
3737

3738
			geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;
3739

3740
			geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );
3741

3742
		}
3743

3744
	};
3745

3746 3747 3748 3749 3750 3751 3752 3753 3754
	// Objects refresh

	this.initWebGLObjects = function ( scene ) {

		if ( !scene.__webglObjects ) {

			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
			scene.__webglSprites = [];
3755
			scene.__webglFlares = [];
3756 3757

		}
3758

3759
		while ( scene.__objectsAdded.length ) {
3760

3761 3762
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
3763

3764
		}
A
alteredq 已提交
3765

3766
		while ( scene.__objectsRemoved.length ) {
3767

3768 3769
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
3770

3771
		}
3772

3773
		// update must be called after objects adding / removal
3774

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

3777
			updateObject( scene.__webglObjects[ o ].object );
M
Mr.doob 已提交
3778 3779 3780 3781 3782

		}

	};

3783
	// Objects adding
M
Mr.doob 已提交
3784

3785
	function addObject ( object, scene ) {
A
alteredq 已提交
3786

3787
		var g, geometry, geometryGroup;
3788

3789
		if ( ! object.__webglInit ) {
M
Mr.doob 已提交
3790

3791
			object.__webglInit = true;
M
Mr.doob 已提交
3792

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

3795 3796 3797
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
M
Mr.doob 已提交
3798

3799
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3800

3801
			if ( object instanceof THREE.Mesh ) {
M
Mr.doob 已提交
3802

3803
				geometry = object.geometry;
M
Mr.doob 已提交
3804

3805
				if ( geometry instanceof THREE.Geometry ) {
M
Mr.doob 已提交
3806

3807
					if ( geometry.geometryGroups === undefined ) {
M
Mr.doob 已提交
3808

3809
						sortFacesByMaterial( geometry );
M
Mr.doob 已提交
3810

3811 3812 3813
					}

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

3815
					for ( g in geometry.geometryGroups ) {
M
Mr.doob 已提交
3816

3817
						geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
3818

3819
						// initialise VBO on the first access
M
Mr.doob 已提交
3820

3821
						if ( ! geometryGroup.__webglVertexBuffer ) {
3822

3823 3824
							createMeshBuffers( geometryGroup );
							initMeshBuffers( geometryGroup, object );
M
Mr.doob 已提交
3825

3826 3827 3828 3829 3830 3831 3832 3833 3834
							geometry.__dirtyVertices = true;
							geometry.__dirtyMorphTargets = true;
							geometry.__dirtyElements = true;
							geometry.__dirtyUvs = true;
							geometry.__dirtyNormals = true;
							geometry.__dirtyTangents = true;
							geometry.__dirtyColors = true;

						}
M
Mr.doob 已提交
3835

3836
					}
M
Mr.doob 已提交
3837

3838
				}
M
Mr.doob 已提交
3839

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

3842
				geometry = object.geometry;
M
Mr.doob 已提交
3843

3844
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
3845

3846 3847
					createRibbonBuffers( geometry );
					initRibbonBuffers( geometry );
M
Mr.doob 已提交
3848

3849 3850
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
3851

3852
				}
M
Mr.doob 已提交
3853

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

3856
				geometry = object.geometry;
M
Mr.doob 已提交
3857

3858
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
3859

3860 3861
					createLineBuffers( geometry );
					initLineBuffers( geometry, object );
M
Mr.doob 已提交
3862

3863 3864
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
3865

3866
				}
3867

3868
			} else if ( object instanceof THREE.ParticleSystem ) {
3869

3870
				geometry = object.geometry;
3871

3872
				if ( ! geometry.__webglVertexBuffer ) {
3873

3874 3875
					createParticleBuffers( geometry );
					initParticleBuffers( geometry, object );
3876

3877 3878
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
3879

3880
				}
3881

3882
			}
3883

3884
		}
3885

3886
		if ( ! object.__webglActive ) {
3887

3888
			if ( object instanceof THREE.Mesh ) {
3889

3890
				geometry = object.geometry;
3891

3892 3893 3894 3895 3896 3897 3898 3899 3900
				if ( geometry instanceof THREE.BufferGeometry ) {

					addBuffer( scene.__webglObjects, geometry, object );

				} else {

					for ( g in geometry.geometryGroups ) {

						geometryGroup = geometry.geometryGroups[ g ];
3901

3902
						addBuffer( scene.__webglObjects, geometryGroup, object );
3903

3904
					}
3905

3906
				}
3907

3908 3909 3910
			} else if ( object instanceof THREE.Ribbon ||
						object instanceof THREE.Line ||
						object instanceof THREE.ParticleSystem ) {
3911

3912 3913
				geometry = object.geometry;
				addBuffer( scene.__webglObjects, geometry, object );
3914

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

3917
				addBufferImmediate( scene.__webglObjectsImmediate, object );
3918

3919
			} else if ( object instanceof THREE.Sprite ) {
3920

3921
				scene.__webglSprites.push( object );
3922

3923 3924 3925 3926
			} else if ( object instanceof THREE.LensFlare ) {

				scene.__webglFlares.push( object );

3927 3928
			}

3929
			object.__webglActive = true;
3930

3931
		}
3932

3933
	};
3934

3935
	function addBuffer ( objlist, buffer, object ) {
3936

3937 3938 3939 3940 3941 3942 3943 3944
		objlist.push(
			{
				buffer: buffer,
				object: object,
				opaque: null,
				transparent: null
			}
		);
3945

3946
	};
3947

3948
	function addBufferImmediate ( objlist, object ) {
3949

3950 3951 3952 3953 3954
		objlist.push(
			{
				object: object,
				opaque: null,
				transparent: null
3955
			}
3956
		);
3957

3958
	};
3959

3960
	// Objects updates
3961

3962
	function updateObject ( object ) {
3963

3964 3965
		var geometry = object.geometry,
			geometryGroup, customAttributesDirty, material;
3966

3967
		if ( object instanceof THREE.Mesh ) {
3968

3969 3970
			if ( geometry instanceof THREE.BufferGeometry ) {

3971
				/*
3972 3973 3974
				if ( geometry.__dirtyVertices || geometry.__dirtyElements ||
					 geometry.__dirtyUvs || geometry.__dirtyNormals ||
					 geometry.__dirtyColors  ) {
3975

3976 3977
					// TODO
					// set buffers from typed arrays
3978

3979
				}
3980
				*/
3981

3982 3983 3984 3985 3986
				geometry.__dirtyVertices = false;
				geometry.__dirtyElements = false;
				geometry.__dirtyUvs = false;
				geometry.__dirtyNormals = false;
				geometry.__dirtyColors = false;
3987

3988
			} else {
3989

3990
				// check all geometry groups
3991

3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006
				for( var i = 0, il = geometry.geometryGroupsList.length; i < il; i ++ ) {

					geometryGroup = geometry.geometryGroupsList[ i ];

					material = getBufferMaterial( object, geometryGroup );

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

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

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

					}
4007

4008
				}
M
Mr.doob 已提交
4009

4010 4011 4012 4013 4014 4015 4016
				geometry.__dirtyVertices = false;
				geometry.__dirtyMorphTargets = false;
				geometry.__dirtyElements = false;
				geometry.__dirtyUvs = false;
				geometry.__dirtyNormals = false;
				geometry.__dirtyColors = false;
				geometry.__dirtyTangents = false;
4017

4018
				material.attributes && clearCustomAttributes( material );
4019

4020
			}
4021

4022
		} else if ( object instanceof THREE.Ribbon ) {
4023

4024
			if ( geometry.__dirtyVertices || geometry.__dirtyColors ) {
4025

4026
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
4027

4028
			}
4029

4030 4031
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
4032

4033
		} else if ( object instanceof THREE.Line ) {
4034

4035
			material = getBufferMaterial( object, geometryGroup );
A
alteredq 已提交
4036

4037
			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
A
alteredq 已提交
4038

4039
			if ( geometry.__dirtyVertices ||  geometry.__dirtyColors || customAttributesDirty ) {
A
alteredq 已提交
4040

4041
				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
4042

4043
			}
4044

4045 4046
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
4047

4048
			material.attributes && clearCustomAttributes( material );
4049

4050
		} else if ( object instanceof THREE.ParticleSystem ) {
4051

4052
			material = getBufferMaterial( object, geometryGroup );
4053

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

4056
			if ( geometry.__dirtyVertices || geometry.__dirtyColors || object.sortParticles || customAttributesDirty ) {
4057

4058
				setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
4059

4060
			}
4061

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

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

4067
		}
4068

4069
	};
4070

4071
	// Objects updates - custom attributes check
4072

4073
	function areCustomAttributesDirty ( material ) {
4074

4075
		for ( var a in material.attributes ) {
4076

4077
			if ( material.attributes[ a ].needsUpdate ) return true;
4078

4079
		}
4080

4081
		return false;
4082

4083
	};
4084

4085 4086 4087
	function clearCustomAttributes ( material ) {

		for ( var a in material.attributes ) {
4088

4089
			material.attributes[ a ].needsUpdate = false;
4090

4091
		}
4092

4093
	};
4094

4095
	// Objects removal
4096

4097
	function removeObject ( object, scene ) {
4098

4099 4100 4101 4102
		if ( object instanceof THREE.Mesh  ||
			 object instanceof THREE.ParticleSystem ||
			 object instanceof THREE.Ribbon ||
			 object instanceof THREE.Line ) {
4103

4104
			removeInstances( scene.__webglObjects, object );
4105

4106
		} else if ( object instanceof THREE.Sprite ) {
4107

4108
			removeInstancesDirect( scene.__webglSprites, object );
4109

4110 4111 4112 4113
		} else if ( object instanceof THREE.LensFlare ) {

			removeInstancesDirect( scene.__webglFlares, object );

4114
		} else if ( object instanceof THREE.MarchingCubes || object.immediateRenderCallback ) {
4115

4116
			removeInstances( scene.__webglObjectsImmediate, object );
4117

4118
		}
4119

4120
		object.__webglActive = false;
4121

4122
	};
4123

4124
	function removeInstances ( objlist, object ) {
4125

4126
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4127

4128
			if ( objlist[ o ].object === object ) {
4129

4130
				objlist.splice( o, 1 );
4131

4132
			}
4133

4134
		}
4135

4136
	};
4137

4138
	function removeInstancesDirect ( objlist, object ) {
4139

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

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

4144
				objlist.splice( o, 1 );
4145

4146
			}
4147

4148
		}
4149

4150
	};
4151

4152
	// Materials
4153

4154
	this.initMaterial = function ( material, lights, fog, object ) {
4155

4156
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
4157

4158
		if ( material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
4159

4160
			shaderID = 'depth';
4161

4162
		} else if ( material instanceof THREE.MeshNormalMaterial ) {
4163

4164
			shaderID = 'normal';
M
Mr.doob 已提交
4165

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

4168
			shaderID = 'basic';
M
Mr.doob 已提交
4169

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

4172
			shaderID = 'lambert';
M
Mr.doob 已提交
4173

4174
		} else if ( material instanceof THREE.MeshPhongMaterial ) {
4175

4176
			shaderID = 'phong';
4177

4178
		} else if ( material instanceof THREE.LineBasicMaterial ) {
4179

4180
			shaderID = 'basic';
4181

4182
		} else if ( material instanceof THREE.ParticleBasicMaterial ) {
4183

4184
			shaderID = 'particle_basic';
4185 4186 4187

		}

4188
		if ( shaderID ) {
4189

4190
			setMaterialShaders( material, THREE.ShaderLib[ shaderID ] );
4191

4192
		}
4193

4194 4195
		// heuristics to create shader parameters according to lights in the scene
		// (not to blow over maxLights budget)
4196

4197
		maxLightCount = allocateLights( lights );
4198

4199
		maxShadows = allocateShadows( lights );
4200

4201
		maxBones = allocateBones( object );
4202

4203
		parameters = {
4204

4205 4206 4207 4208 4209 4210
			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,
A
alteredq 已提交
4211
			morphNormals: material.morphNormals,
4212
			maxMorphTargets: this.maxMorphTargets,
A
alteredq 已提交
4213
			maxMorphNormals: this.maxMorphNormals,
4214 4215 4216 4217
			maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
			maxBones: maxBones,
			shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
			shadowMapSoft: this.shadowMapSoft,
A
alteredq 已提交
4218 4219
			shadowMapDebug: this.shadowMapDebug,
			shadowMapCascade: this.shadowMapCascade,
4220 4221 4222
			maxShadows: maxShadows,
			alphaTest: material.alphaTest,
			metal: material.metal,
4223
			perPixel: material.perPixel,
4224
			wrapAround: material.wrapAround,
4225
			doubleSided: object && object.doubleSided
4226

4227
		};
M
Mr.doob 已提交
4228

4229
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
4230

4231
		var attributes = material.program.attributes;
4232

4233 4234 4235 4236
		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 );
4237

4238 4239 4240
		if ( material.skinning &&
			 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
M
Mr.doob 已提交
4241

4242 4243 4244 4245
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
M
Mr.doob 已提交
4246 4247

		}
4248

4249
		if ( material.attributes ) {
A
alteredq 已提交
4250

4251
			for ( a in material.attributes ) {
M
Mr.doob 已提交
4252

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

4255
			}
M
Mr.doob 已提交
4256

4257
		}
M
Mr.doob 已提交
4258

4259
		if ( material.morphTargets ) {
M
Mr.doob 已提交
4260

4261
			material.numSupportedMorphTargets = 0;
4262

4263
			var id, base = "morphTarget";
4264

4265
			for ( i = 0; i < this.maxMorphTargets; i ++ ) {
4266

4267
				id = base + i;
M
Mr.doob 已提交
4268

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

4271 4272
					_gl.enableVertexAttribArray( attributes[ id ] );
					material.numSupportedMorphTargets ++;
4273

4274
				}
4275

4276
			}
4277

4278
		}
4279

A
alteredq 已提交
4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300
		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

			var id, base = "morphNormal";

			for ( i = 0; i < this.maxMorphNormals; i ++ ) {

				id = base + i;

				if ( attributes[ id ] >= 0 ) {

					_gl.enableVertexAttribArray( attributes[ id ] );
					material.numSupportedMorphNormals ++;

				}

			}

		}

4301
		material.uniformsList = [];
4302

4303
		for ( u in material.uniforms ) {
4304

4305
			material.uniformsList.push( [ material.uniforms[ u ], u ] );
4306

4307
		}
M
Mr.doob 已提交
4308

4309
	};
M
Mr.doob 已提交
4310

4311
	function setMaterialShaders( material, shaders ) {
M
Mr.doob 已提交
4312

4313 4314 4315
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
M
Mr.doob 已提交
4316

4317
	};
M
Mr.doob 已提交
4318

4319
	function setProgram( camera, lights, fog, material, object ) {
4320

A
alteredq 已提交
4321
		if ( ! material.program || material.needsUpdate ) {
4322

4323
			_this.initMaterial( material, lights, fog, object );
A
alteredq 已提交
4324
			material.needsUpdate = false;
4325

4326
		}
4327

4328
		if ( material.morphTargets ) {
4329

4330
			if ( ! object.__webglMorphTargetInfluences ) {
4331

4332
				object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );
4333

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

4336
					object.__webglMorphTargetInfluences[ i ] = 0;
4337

4338
				}
4339

4340
			}
4341

4342
		}
4343

4344
		var refreshMaterial = false;
4345

4346 4347 4348
		var program = material.program,
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
4349

4350
		if ( program !== _currentProgram ) {
4351

4352 4353
			_gl.useProgram( program );
			_currentProgram = program;
4354

4355
			refreshMaterial = true;
4356

4357
		}
4358

4359
		if ( material.id !== _currentMaterialId ) {
4360

4361 4362
			_currentMaterialId = material.id;
			refreshMaterial = true;
4363

4364
		}
4365

4366
		if ( refreshMaterial || camera !== _currentCamera ) {
4367

A
alteredq 已提交
4368
			_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, camera._projectionMatrixArray );
A
alteredq 已提交
4369

4370 4371 4372 4373 4374 4375
			if ( camera !== _currentCamera ) _currentCamera = camera;

		}

		if ( refreshMaterial ) {

4376
			// refresh uniforms common to several materials
4377

4378
			if ( fog && material.fog ) {
4379

4380
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
4381

4382
			}
M
Mr.doob 已提交
4383

4384 4385 4386
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material.lights ) {
4387

4388 4389
				setupLights( program, lights );
				refreshUniformsLights( m_uniforms, _lights );
4390

4391
			}
M
Mr.doob 已提交
4392

4393 4394 4395
			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
4396

4397
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
4398 4399 4400

			}

4401
			// refresh single material specific uniforms
M
Mr.doob 已提交
4402

4403
			if ( material instanceof THREE.LineBasicMaterial ) {
4404

4405
				refreshUniformsLine( m_uniforms, material );
M
Mr.doob 已提交
4406

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

4409
				refreshUniformsParticle( m_uniforms, material );
M
Mr.doob 已提交
4410

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

4413
				refreshUniformsPhong( m_uniforms, material );
M
Mr.doob 已提交
4414

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

4417
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
4418

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

4421 4422 4423
				m_uniforms.mNear.value = camera.near;
				m_uniforms.mFar.value = camera.far;
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4424

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

4427
				m_uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4428

4429
			}
M
Mr.doob 已提交
4430

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

4433
				refreshUniformsShadow( m_uniforms, lights );
M
Mr.doob 已提交
4434

4435
			}
M
Mr.doob 已提交
4436

4437
			// load common uniforms
M
Mr.doob 已提交
4438

4439
			loadUniformsGeneric( program, material.uniformsList );
M
Mr.doob 已提交
4440

4441 4442
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)
4443

4444 4445 4446
			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
				 material.envMap ) {
4447

4448
				if ( p_uniforms.cameraPosition !== null ) {
4449

4450 4451
					var position = camera.matrixWorld.getPosition();
					_gl.uniform3f( p_uniforms.cameraPosition, position.x, position.y, position.z );
4452

4453
				}
4454 4455 4456

			}

4457 4458 4459 4460
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {
4461

4462
				if ( p_uniforms.viewMatrix !== null ) {
4463

A
alteredq 已提交
4464
					_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, camera._viewMatrixArray );
4465

4466
				}
4467

4468
			}
M
Mr.doob 已提交
4469

4470
			if ( material.skinning ) {
4471

A
alteredq 已提交
4472
				_gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.boneMatrices );
4473

4474
			}
4475

4476
		}
M
Mr.doob 已提交
4477

4478
		loadUniformsMatrices( p_uniforms, object );
M
Mr.doob 已提交
4479

4480 4481 4482 4483
		if ( material instanceof THREE.ShaderMaterial ||
			 material.envMap ||
			 material.skinning ||
			 object.receiveShadow ) {
M
Mr.doob 已提交
4484

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

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

4489
			}
4490

4491
		}
4492

4493
		return program;
4494

4495
	};
4496

4497
	// Uniforms (refresh uniforms objects)
A
alteredq 已提交
4498

4499
	function refreshUniformsCommon ( uniforms, material ) {
4500

4501
		uniforms.opacity.value = material.opacity;
4502

4503
		if ( _this.gammaInput ) {
4504

4505
			uniforms.diffuse.value.copyGammaToLinear( material.color );
4506

4507
		} else {
4508

4509
			uniforms.diffuse.value = material.color;
4510

4511
		}
4512

4513
		uniforms.map.texture = material.map;
4514

4515
		if ( material.map ) {
4516

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

4519
		}
M
Mr.doob 已提交
4520

4521
		uniforms.lightMap.texture = material.lightMap;
4522

4523 4524
		uniforms.envMap.texture = material.envMap;
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
4525

4526
		if ( _this.gammaInput ) {
4527

4528 4529
			//uniforms.reflectivity.value = material.reflectivity * material.reflectivity;
			uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
4530

4531
		} else {
4532

4533
			uniforms.reflectivity.value = material.reflectivity;
4534

4535
		}
4536

4537 4538 4539
		uniforms.refractionRatio.value = material.refractionRatio;
		uniforms.combine.value = material.combine;
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
M
Mr.doob 已提交
4540

4541
	};
M
Mr.doob 已提交
4542

4543
	function refreshUniformsLine ( uniforms, material ) {
M
Mr.doob 已提交
4544

4545 4546
		uniforms.diffuse.value = material.color;
		uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
4547

4548
	};
M
Mr.doob 已提交
4549

4550
	function refreshUniformsParticle ( uniforms, material ) {
4551

4552 4553 4554 4555
		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.
4556

4557
		uniforms.map.texture = material.map;
4558

4559
	};
4560

4561
	function refreshUniformsFog ( uniforms, fog ) {
4562

4563
		uniforms.fogColor.value = fog.color;
4564

4565
		if ( fog instanceof THREE.Fog ) {
4566

4567 4568
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
4569

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

4572
			uniforms.fogDensity.value = fog.density;
M
Mikael Emtinger 已提交
4573

4574
		}
M
Mikael Emtinger 已提交
4575

4576
	};
M
Mikael Emtinger 已提交
4577

4578
	function refreshUniformsPhong ( uniforms, material ) {
M
Mikael Emtinger 已提交
4579

4580
		uniforms.shininess.value = material.shininess;
4581

4582
		if ( _this.gammaInput ) {
M
Mikael Emtinger 已提交
4583

4584
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
4585
			uniforms.emissive.value.copyGammaToLinear( material.emissive );
4586
			uniforms.specular.value.copyGammaToLinear( material.specular );
4587

4588
		} else {
4589

4590
			uniforms.ambient.value = material.ambient;
4591
			uniforms.emissive.value = material.emissive;
4592
			uniforms.specular.value = material.specular;
4593

4594
		}
4595

4596 4597 4598 4599 4600 4601
		if ( material.wrapAround ) {

			uniforms.wrapRGB.value.copy( material.wrapRGB );

		}

4602
	};
4603

4604
	function refreshUniformsLambert ( uniforms, material ) {
4605

4606
		if ( _this.gammaInput ) {
4607

4608
			uniforms.ambient.value.copyGammaToLinear( material.ambient );
4609
			uniforms.emissive.value.copyGammaToLinear( material.emissive );
M
Mr.doob 已提交
4610

4611
		} else {
4612

4613
			uniforms.ambient.value = material.ambient;
4614
			uniforms.emissive.value = material.emissive;
4615

4616
		}
4617

4618 4619 4620 4621 4622 4623
		if ( material.wrapAround ) {

			uniforms.wrapRGB.value.copy( material.wrapRGB );

		}

4624
	};
4625

4626
	function refreshUniformsLights ( uniforms, lights ) {
4627

4628
		uniforms.ambientLightColor.value = lights.ambient;
4629

4630 4631
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
4632

4633 4634 4635
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
		uniforms.pointLightDistance.value = lights.point.distances;
4636

4637
	};
4638

4639
	function refreshUniformsShadow ( uniforms, lights ) {
M
Mr.doob 已提交
4640

4641
		if ( uniforms.shadowMatrix ) {
4642

4643
			var j = 0;
4644

4645
			for ( var i = 0, il = lights.length; i < il; i ++ ) {
4646

4647
				var light = lights[ i ];
4648

A
alteredq 已提交
4649 4650
				if ( ! light.castShadow ) continue;

4651
				if ( light instanceof THREE.SpotLight || ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) ) {
4652 4653 4654

					uniforms.shadowMap.texture[ j ] = light.shadowMap;
					uniforms.shadowMapSize.value[ j ] = light.shadowMapSize;
4655

4656 4657 4658 4659 4660 4661 4662 4663 4664 4665
					uniforms.shadowMatrix.value[ j ] = light.shadowMatrix;

					uniforms.shadowDarkness.value[ j ] = light.shadowDarkness;
					uniforms.shadowBias.value[ j ] = light.shadowBias;

					j ++;

				}

			}
4666

4667 4668
		}

4669
	};
4670

4671
	// Uniforms (load to GPU)
4672

4673
	function loadUniformsMatrices ( uniforms, object ) {
4674

4675
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
4676

4677
		if ( uniforms.normalMatrix ) {
4678

4679
			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );
4680

4681
		}
4682

4683
	};
4684

4685
	function loadUniformsGeneric ( program, uniforms ) {
4686

4687
		var uniform, value, type, location, texture, i, il, j, jl, offset;
4688

4689
		for( j = 0, jl = uniforms.length; j < jl; j ++ ) {
4690

4691 4692
			location = program.uniforms[ uniforms[ j ][ 1 ] ];
			if ( !location ) continue;
4693

4694
			uniform = uniforms[ j ][ 0 ];
4695

4696 4697
			type = uniform.type;
			value = uniform.value;
4698

4699
			// single integer
4700

4701
			if( type === "i" ) {
4702

4703
				_gl.uniform1i( location, value );
4704

4705
			// single float
4706

4707
			} else if( type === "f" ) {
4708

4709
				_gl.uniform1f( location, value );
4710

4711
			// single THREE.Vector2
4712

4713
			} else if( type === "v2" ) {
4714

4715
				_gl.uniform2f( location, value.x, value.y );
4716

4717
			// single THREE.Vector3
4718

4719
			} else if( type === "v3" ) {
4720

4721
				_gl.uniform3f( location, value.x, value.y, value.z );
4722

4723
			// single THREE.Vector4
4724

4725
			} else if( type === "v4" ) {
4726

4727
				_gl.uniform4f( location, value.x, value.y, value.z, value.w );
4728

4729
			// single THREE.Color
4730

4731
			} else if( type === "c" ) {
4732

4733
				_gl.uniform3f( location, value.r, value.g, value.b );
4734

4735
			// flat array of floats (JS or typed array)
4736

4737
			} else if( type === "fv1" ) {
4738

4739
				_gl.uniform1fv( location, value );
4740

4741
			// flat array of floats with 3 x N size (JS or typed array)
4742

4743
			} else if( type === "fv" ) {
4744

4745
				_gl.uniform3fv( location, value );
4746

4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767
			// array of THREE.Vector2

			} else if( type === "v2v" ) {

				if ( ! uniform._array ) {

					uniform._array = new Float32Array( 2 * value.length );

				}

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

					offset = i * 2;

					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;

				}

				_gl.uniform2fv( location, uniform._array );

4768
			// array of THREE.Vector3
4769

4770
			} else if( type === "v3v" ) {
4771

4772
				if ( ! uniform._array ) {
4773

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

4776
				}
A
alteredq 已提交
4777

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

4780
					offset = i * 3;
4781

4782 4783 4784
					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;
					uniform._array[ offset + 2 ] = value[ i ].z;
4785

4786
				}
4787

4788
				_gl.uniform3fv( location, uniform._array );
A
alteredq 已提交
4789

4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811
			// array of THREE.Vector4

			} else if( type == "v4v" ) {

				if ( ! uniform._array ) {

					uniform._array = new Float32Array( 4 * value.length );

				}

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

					offset = i * 4;

					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;
					uniform._array[ offset + 2 ] = value[ i ].z;
					uniform._array[ offset + 3 ] = value[ i ].w;

				}

				_gl.uniform4fv( location, uniform._array );
4812

4813
			// single THREE.Matrix4
4814

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

4817
				if ( ! uniform._array ) {
A
alteredq 已提交
4818

4819
					uniform._array = new Float32Array( 16 );
4820

4821
				}
4822

4823 4824
				value.flattenToArray( uniform._array );
				_gl.uniformMatrix4fv( location, false, uniform._array );
4825

4826
			// array of THREE.Matrix4
4827

4828
			} else if( type === "m4v" ) {
A
alteredq 已提交
4829

4830 4831 4832
				if ( ! uniform._array ) {

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

M
Mr.doob 已提交
4834
				}
M
Mr.doob 已提交
4835

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

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

4840
				}
A
alteredq 已提交
4841

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

4844

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

4847
			} else if( type === "t" ) {
A
alteredq 已提交
4848

4849
				_gl.uniform1i( location, value );
4850

4851
				texture = uniform.texture;
A
alteredq 已提交
4852

4853
				if ( !texture ) continue;
A
alteredq 已提交
4854

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

4857
					setCubeTexture( texture, value );
A
alteredq 已提交
4858

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

4861 4862 4863 4864
					setCubeTextureDynamic( texture, value );

				} else {

4865
					_this.setTexture( texture, value );
4866

M
Mr.doob 已提交
4867
				}
M
Mr.doob 已提交
4868

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

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

4873
				if ( ! uniform._array ) {
M
Mr.doob 已提交
4874

4875
					uniform._array = [];
A
alteredq 已提交
4876

4877 4878 4879 4880 4881
					for( i = 0, il = uniform.texture.length; i < il; i ++ ) {

						uniform._array[ i ] = value + i;

					}
A
alteredq 已提交
4882

M
Mr.doob 已提交
4883
				}
A
alteredq 已提交
4884

4885
				_gl.uniform1iv( location, uniform._array );
A
alteredq 已提交
4886

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

4889
					texture = uniform.texture[ i ];
4890

4891
					if ( !texture ) continue;
M
Mr.doob 已提交
4892

4893
					_this.setTexture( texture, uniform._array[ i ] );
M
Mr.doob 已提交
4894

M
Mr.doob 已提交
4895
				}
M
Mr.doob 已提交
4896

M
Mr.doob 已提交
4897
			}
M
Mr.doob 已提交
4898

M
Mr.doob 已提交
4899
		}
M
Mr.doob 已提交
4900

4901
	};
M
Mr.doob 已提交
4902

A
alteredq 已提交
4903
	function setupMatrices ( object, camera ) {
M
Mr.doob 已提交
4904

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

4907
		var inverseMatrix = THREE.Matrix4.makeInvert3x3( object._modelViewMatrix );
4908

4909
		if ( inverseMatrix ) {
4910

4911
			inverseMatrix.transposeIntoArray( object._normalMatrixArray );
M
Mr.doob 已提交
4912

4913
		}
M
Mr.doob 已提交
4914

A
alteredq 已提交
4915
	};
M
Mr.doob 已提交
4916

4917
	function setupLights ( program, lights ) {
M
Mr.doob 已提交
4918

4919 4920 4921
		var l, ll, light, n,
		r = 0, g = 0, b = 0,
		color, position, intensity, distance,
M
Mr.doob 已提交
4922

4923
		zlights = _lights,
A
alteredq 已提交
4924

4925 4926
		dcolors = zlights.directional.colors,
		dpositions = zlights.directional.positions,
A
alteredq 已提交
4927

4928 4929 4930
		pcolors = zlights.point.colors,
		ppositions = zlights.point.positions,
		pdistances = zlights.point.distances,
4931

4932 4933
		dlength = 0,
		plength = 0,
4934

4935 4936
		doffset = 0,
		poffset = 0;
4937

4938
		for ( l = 0, ll = lights.length; l < ll; l ++ ) {
4939

4940
			light = lights[ l ];
A
alteredq 已提交
4941

A
alteredq 已提交
4942 4943 4944
			if ( light.onlyShadow ) continue;

			color = light.color;
4945 4946
			intensity = light.intensity;
			distance = light.distance;
A
alteredq 已提交
4947

4948
			if ( light instanceof THREE.AmbientLight ) {
4949

4950
				if ( _this.gammaInput ) {
4951

4952 4953 4954
					r += color.r * color.r;
					g += color.g * color.g;
					b += color.b * color.b;
4955

4956
				} else {
4957

4958 4959 4960
					r += color.r;
					g += color.g;
					b += color.b;
4961

4962
				}
4963

4964
			} else if ( light instanceof THREE.DirectionalLight ) {
4965

4966
				doffset = dlength * 3;
4967

4968
				if ( _this.gammaInput ) {
4969

4970 4971 4972
					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;
4973

4974
				} else {
4975

4976 4977 4978
					dcolors[ doffset ]     = color.r * intensity;
					dcolors[ doffset + 1 ] = color.g * intensity;
					dcolors[ doffset + 2 ] = color.b * intensity;
A
alteredq 已提交
4979

4980
				}
A
alteredq 已提交
4981

4982 4983 4984
				_direction.copy( light.matrixWorld.getPosition() );
				_direction.subSelf( light.target.matrixWorld.getPosition() );
				_direction.normalize();
A
alteredq 已提交
4985

4986 4987 4988
				dpositions[ doffset ]     = _direction.x;
				dpositions[ doffset + 1 ] = _direction.y;
				dpositions[ doffset + 2 ] = _direction.z;
A
alteredq 已提交
4989

4990
				dlength += 1;
A
alteredq 已提交
4991

4992
			} else if( light instanceof THREE.PointLight || light instanceof THREE.SpotLight ) {
M
Mr.doob 已提交
4993

4994
				poffset = plength * 3;
M
Mr.doob 已提交
4995

4996
				if ( _this.gammaInput ) {
4997

4998 4999 5000
					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 已提交
5001

5002
				} else {
A
alteredq 已提交
5003

5004 5005 5006
					pcolors[ poffset ]     = color.r * intensity;
					pcolors[ poffset + 1 ] = color.g * intensity;
					pcolors[ poffset + 2 ] = color.b * intensity;
A
alteredq 已提交
5007

5008
				}
A
alteredq 已提交
5009

A
alteredq 已提交
5010 5011
				position = light.matrixWorld.getPosition();

5012 5013 5014
				ppositions[ poffset ]     = position.x;
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
A
alteredq 已提交
5015

5016
				pdistances[ plength ] = distance;
A
alteredq 已提交
5017

5018
				plength += 1;
5019

5020
			}
5021

5022
		}
A
alteredq 已提交
5023

5024 5025
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
A
alteredq 已提交
5026

5027 5028
		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 已提交
5029

5030 5031
		zlights.point.length = plength;
		zlights.directional.length = dlength;
A
alteredq 已提交
5032

5033 5034 5035
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
5036

5037
	};
M
Mr.doob 已提交
5038

5039
	// GL state setting
M
Mr.doob 已提交
5040

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

5043
		if ( cullFace ) {
M
Mr.doob 已提交
5044

5045
			if ( !frontFace || frontFace === "ccw" ) {
5046

5047
				_gl.frontFace( _gl.CCW );
5048

5049
			} else {
5050

5051
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
5052

5053
			}
M
Mr.doob 已提交
5054

5055
			if( cullFace === "back" ) {
5056

5057
				_gl.cullFace( _gl.BACK );
5058

5059
			} else if( cullFace === "front" ) {
5060

5061
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
5062

5063
			} else {
5064

5065
				_gl.cullFace( _gl.FRONT_AND_BACK );
5066

5067
			}
5068

5069
			_gl.enable( _gl.CULL_FACE );
5070

5071
		} else {
5072

5073
			_gl.disable( _gl.CULL_FACE );
5074 5075 5076 5077 5078

		}

	};

A
alteredq 已提交
5079
	this.setObjectFaces = function ( object ) {
5080

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

5083
			if( object.doubleSided ) {
M
Mr.doob 已提交
5084

5085
				_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
5086

5087
			} else {
5088

5089
				_gl.enable( _gl.CULL_FACE );
5090

5091
			}
5092

5093
			_oldDoubleSided = object.doubleSided;
5094

5095
		}
5096

5097
		if ( _oldFlipSided !== object.flipSided ) {
5098

5099
			if( object.flipSided ) {
5100

5101
				_gl.frontFace( _gl.CW );
5102

5103
			} else {
5104

5105
				_gl.frontFace( _gl.CCW );
5106

5107
			}
5108

5109
			_oldFlipSided = object.flipSided;
5110

5111
		}
5112

5113
	};
5114

A
alteredq 已提交
5115
	this.setDepthTest = function ( depthTest ) {
5116

5117
		if ( _oldDepthTest !== depthTest ) {
5118

5119
			if ( depthTest ) {
5120

5121
				_gl.enable( _gl.DEPTH_TEST );
5122

5123
			} else {
5124

5125
				_gl.disable( _gl.DEPTH_TEST );
5126 5127 5128

			}

5129
			_oldDepthTest = depthTest;
5130

5131
		}
5132

5133
	};
5134

5135
	this.setDepthWrite = function ( depthWrite ) {
A
alteredq 已提交
5136

5137
		if ( _oldDepthWrite !== depthWrite ) {
A
alteredq 已提交
5138

5139 5140
			_gl.depthMask( depthWrite );
			_oldDepthWrite = depthWrite;
A
alteredq 已提交
5141 5142 5143 5144 5145

		}

	};

5146
	function setLineWidth ( width ) {
5147

5148
		if ( width !== _oldLineWidth ) {
5149

5150 5151 5152
			_gl.lineWidth( width );

			_oldLineWidth = width;
5153 5154 5155

		}

5156
	};
5157

5158
	function setPolygonOffset ( polygonoffset, factor, units ) {
5159

5160
		if ( _oldPolygonOffset !== polygonoffset ) {
M
Mr.doob 已提交
5161

5162
			if ( polygonoffset ) {
5163

5164
				_gl.enable( _gl.POLYGON_OFFSET_FILL );
5165

5166
			} else {
5167

5168
				_gl.disable( _gl.POLYGON_OFFSET_FILL );
5169

5170
			}
5171

5172
			_oldPolygonOffset = polygonoffset;
5173

5174
		}
5175

5176
		if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
5177

5178
			_gl.polygonOffset( factor, units );
M
Mr.doob 已提交
5179

5180 5181
			_oldPolygonOffsetFactor = factor;
			_oldPolygonOffsetUnits = units;
M
Mr.doob 已提交
5182

5183
		}
M
Mr.doob 已提交
5184

5185
	};
M
Mr.doob 已提交
5186

5187
	this.setBlending = function ( blending ) {
M
Mr.doob 已提交
5188

5189
		if ( blending !== _oldBlending ) {
M
Mr.doob 已提交
5190

5191
			switch ( blending ) {
M
Mr.doob 已提交
5192

5193 5194 5195
				case THREE.NoBlending:
                    _gl.disable( _gl.BLEND );
                    break;
5196

5197
				case THREE.AdditiveBlending:
M
Mr.doob 已提交
5198

5199
                    _gl.enable( _gl.BLEND );
5200 5201
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
M
Mr.doob 已提交
5202

5203
					break;
M
Mr.doob 已提交
5204

5205
				case THREE.SubtractiveBlending:
M
Mr.doob 已提交
5206

5207
					// TODO: Find blendFuncSeparate() combination
5208
                    _gl.enable( _gl.BLEND );
5209 5210
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
M
Mr.doob 已提交
5211

5212
					break;
M
Mr.doob 已提交
5213

5214
				case THREE.MultiplyBlending:
M
Mr.doob 已提交
5215

5216
					// TODO: Find blendFuncSeparate() combination
5217
                    _gl.enable( _gl.BLEND );
5218 5219
					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
M
Mr.doob 已提交
5220

5221
					break;
5222

5223
				default:
N
Nicolas Garcia Belmonte 已提交
5224

5225
                    _gl.enable( _gl.BLEND );
5226 5227
					_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 );
5228

5229
					break;
5230

5231
			}
5232

5233
			_oldBlending = blending;
5234

5235
		}
5236 5237

	};
5238

5239 5240 5241
	// Shaders

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

5243
		var p, pl, program, code;
5244
		var chunks = [];
5245 5246 5247

		// Generate code

5248 5249 5250 5251 5252 5253 5254 5255 5256 5257
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

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

		}
5258 5259 5260

		for ( p in parameters ) {

5261 5262
			chunks.push( p );
			chunks.push( parameters[ p ] );
5263 5264 5265

		}

5266 5267
		code = chunks.join();

5268 5269 5270 5271
		// Check if code has been already compiled

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

5272
			if ( _programs[ p ].code === code ) {
5273 5274

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

5276 5277 5278 5279 5280
				return _programs[ p ].program;

			}

		}
5281

5282
		//console.log( "building new program " );
5283 5284 5285

		//

5286
		program = _gl.createProgram();
M
Mr.doob 已提交
5287

5288
		var prefix_vertex = [
M
Mr.doob 已提交
5289

5290 5291
			"precision " + _precision + " float;",

5292
			( _maxVertexTextures > 0 ) ? "#define VERTEX_TEXTURES" : "",
5293

5294 5295 5296 5297
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

5298 5299 5300
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

5301 5302
			"#define MAX_SHADOWS " + parameters.maxShadows,

5303 5304
			"#define MAX_BONES " + parameters.maxBones,

5305
			parameters.map ? "#define USE_MAP" : "",
5306 5307 5308
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5309
			parameters.skinning ? "#define USE_SKINNING" : "",
5310
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
A
alteredq 已提交
5311
			parameters.morphNormals ? "#define USE_MORPHNORMALS" : "",
A
alteredq 已提交
5312
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
5313
			parameters.wrapAround ? "#define WRAP_AROUND" : "",
5314
			parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
5315

5316
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5317
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
A
alteredq 已提交
5318 5319
			parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
			parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
5320

5321 5322
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
5323 5324 5325
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
5326 5327
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
5328
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
5329

M
Mr.doob 已提交
5330 5331 5332
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
5333
			"attribute vec2 uv2;",
5334

5335
			"#ifdef USE_COLOR",
5336

5337
				"attribute vec3 color;",
5338

5339 5340
			"#endif",

5341
			"#ifdef USE_MORPHTARGETS",
5342

5343 5344 5345 5346
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
A
alteredq 已提交
5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362

				"#ifdef USE_MORPHNORMALS",

					"attribute vec3 morphNormal0;",
					"attribute vec3 morphNormal1;",
					"attribute vec3 morphNormal2;",
					"attribute vec3 morphNormal3;",

				"#else",

					"attribute vec3 morphTarget4;",
					"attribute vec3 morphTarget5;",
					"attribute vec3 morphTarget6;",
					"attribute vec3 morphTarget7;",

				"#endif",
5363

5364 5365 5366
			"#endif",

			"#ifdef USE_SKINNING",
5367

5368 5369 5370 5371
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
5372

5373
			"#endif",
5374

M
Mr.doob 已提交
5375
			""
A
alteredq 已提交
5376

M
Mr.doob 已提交
5377
		].join("\n");
5378

M
Mr.doob 已提交
5379 5380
		var prefix_fragment = [

5381
			"precision " + _precision + " float;",
M
Mr.doob 已提交
5382 5383 5384 5385

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

5386 5387
			"#define MAX_SHADOWS " + parameters.maxShadows,

5388 5389
			parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",

5390 5391 5392 5393
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

M
Mr.doob 已提交
5394 5395
			( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
			( parameters.useFog && parameters.fog instanceof THREE.FogExp2 ) ? "#define FOG_EXP2" : "",
M
Mr.doob 已提交
5396 5397 5398 5399 5400

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

5402 5403
			parameters.metal ? "#define METAL" : "",
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
5404
			parameters.wrapAround ? "#define WRAP_AROUND" : "",
5405
			parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
5406

5407
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5408
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
A
alteredq 已提交
5409 5410
			parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
			parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
M
Mr.doob 已提交
5411 5412 5413 5414 5415 5416 5417

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

		].join("\n");

5418 5419
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
5420

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

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

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

N
Nicolas Garcia Belmonte 已提交
5427
		}
5428

5429 5430
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
5431

M
Mr.doob 已提交
5432
		program.uniforms = {};
5433
		program.attributes = {};
M
Mr.doob 已提交
5434

5435 5436 5437 5438
		var identifiers, u, a, i;

		// cache uniform locations

5439
		identifiers = [
5440

5441
			'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
A
alteredq 已提交
5442
			'boneGlobalMatrices', 'morphTargetInfluences'
M
Mr.doob 已提交
5443

5444
		];
M
Mr.doob 已提交
5445

5446
		for ( u in uniforms ) {
M
Mr.doob 已提交
5447

5448
			identifiers.push( u );
M
Mr.doob 已提交
5449

5450
		}
M
Mr.doob 已提交
5451

5452
		cacheUniformLocations( program, identifiers );
M
Mr.doob 已提交
5453

5454
		// cache attributes locations
M
Mr.doob 已提交
5455

5456
		identifiers = [
A
alteredq 已提交
5457

5458 5459
			"position", "normal", "uv", "uv2", "tangent", "color",
			"skinVertexA", "skinVertexB", "skinIndex", "skinWeight"
A
alteredq 已提交
5460

5461
		];
M
Mr.doob 已提交
5462

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

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

5467
		}
5468

A
alteredq 已提交
5469 5470 5471 5472 5473 5474
		for ( i = 0; i < parameters.maxMorphNormals; i ++ ) {

			identifiers.push( "morphNormal" + i );

		}

5475
		for ( a in attributes ) {
5476

5477
			identifiers.push( a );
5478

5479
		}
5480

5481
		cacheAttributeLocations( program, identifiers );
5482

5483
		program.id = _programs.length;
5484

5485
		_programs.push( { program: program, code: code } );
5486

5487
		_this.info.memory.programs = _programs.length;
5488

5489
		return program;
5490

5491
	};
5492

5493
	// Shader parameters cache
5494

5495
	function cacheUniformLocations ( program, identifiers ) {
5496

5497
		var i, l, id;
5498

5499
		for( i = 0, l = identifiers.length; i < l; i ++ ) {
5500

5501 5502
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
5503

5504
		}
M
Mr.doob 已提交
5505

5506
	};
M
Mr.doob 已提交
5507

5508
	function cacheAttributeLocations ( program, identifiers ) {
A
alteredq 已提交
5509

5510
		var i, l, id;
A
alteredq 已提交
5511

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

5514 5515
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
A
alteredq 已提交
5516

5517
		}
5518

5519
	};
A
alteredq 已提交
5520

5521
	function getShader ( type, string ) {
A
alteredq 已提交
5522

5523
		var shader;
5524

5525
		if ( type === "fragment" ) {
A
alteredq 已提交
5526

5527
			shader = _gl.createShader( _gl.FRAGMENT_SHADER );
A
alteredq 已提交
5528

5529
		} else if ( type === "vertex" ) {
A
alteredq 已提交
5530

5531
			shader = _gl.createShader( _gl.VERTEX_SHADER );
A
alteredq 已提交
5532

5533
		}
A
alteredq 已提交
5534

5535 5536
		_gl.shaderSource( shader, string );
		_gl.compileShader( shader );
5537

5538
		if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {
5539

5540 5541 5542
			console.error( _gl.getShaderInfoLog( shader ) );
			console.error( string );
			return null;
5543

A
alteredq 已提交
5544 5545
		}

5546 5547
		return shader;

A
alteredq 已提交
5548
	};
5549

5550 5551
	// Textures

5552 5553 5554 5555 5556 5557 5558

	function isPowerOfTwo ( value ) {

		return ( value & ( value - 1 ) ) === 0;

	};

5559
	function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {
5560

5561
		if ( isImagePowerOfTwo ) {
M
Mr.doob 已提交
5562

5563 5564
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
5565

5566 5567
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
5568

5569
		} else {
M
Mr.doob 已提交
5570

5571 5572
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
5573

5574 5575
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
5576

5577
		}
M
Mr.doob 已提交
5578

5579
	};
5580

5581
	this.setTexture = function ( texture, slot ) {
5582

5583
		if ( texture.needsUpdate ) {
A
alteredq 已提交
5584

5585
			if ( ! texture.__webglInit ) {
M
Mr.doob 已提交
5586

5587
				texture.__webglInit = true;
5588
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5589

M
Mr.doob 已提交
5590 5591
				_this.info.memory.textures ++;

5592
			}
M
Mr.doob 已提交
5593

5594
			_gl.activeTexture( _gl.TEXTURE0 + slot );
5595 5596
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );

5597 5598
			var image = texture.image,
			isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
5599 5600
			glFormat = paramThreeToGL( texture.format ),
			glType = paramThreeToGL( texture.type );
5601

5602 5603
			setTextureParameters( _gl.TEXTURE_2D, texture, isImagePowerOfTwo );

5604
			if ( texture instanceof THREE.DataTexture ) {
5605

5606
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );
M
Mr.doob 已提交
5607

A
alteredq 已提交
5608
			} else {
M
Mr.doob 已提交
5609

5610
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, texture.image );
M
Mr.doob 已提交
5611 5612 5613

			}

5614
			if ( texture.generateMipmaps && isImagePowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
M
Mr.doob 已提交
5615

A
alteredq 已提交
5616
			texture.needsUpdate = false;
5617

5618
			if ( texture.onUpdate ) texture.onUpdate();
5619

5620
		} else {
5621

5622 5623
			_gl.activeTexture( _gl.TEXTURE0 + slot );
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
5624 5625

		}
M
Mr.doob 已提交
5626

5627
	};
M
Mr.doob 已提交
5628

5629 5630 5631 5632 5633 5634 5635 5636 5637 5638
	function clampToMaxSize ( image, maxSize ) {

		if ( image.width <= maxSize && image.height <= maxSize ) {

			return image;

		}

		// Warning: Scaling through the canvas will only work with images that use
		// premultiplied alpha.
5639

5640 5641 5642 5643 5644 5645 5646
		var maxDimension = Math.max( image.width, image.height );
		var newWidth = Math.floor( image.width * maxSize / maxDimension );
		var newHeight = Math.floor( image.height * maxSize / maxDimension );

		var canvas = document.createElement( 'canvas' );
		canvas.width = newWidth;
		canvas.height = newHeight;
5647

5648
		var ctx = canvas.getContext( "2d" );
5649 5650
		ctx.drawImage( image, 0, 0, image.width, image.height, 0, 0, newWidth, newHeight );

5651 5652 5653 5654
		return canvas;

	}

5655
	function setCubeTexture ( texture, slot ) {
5656

5657
		if ( texture.image.length === 6 ) {
5658 5659 5660

			if ( texture.needsUpdate ) {

A
alteredq 已提交
5661
				if ( ! texture.image.__webglTextureCube ) {
5662 5663

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

A
alteredq 已提交
5665
				}
5666

A
alteredq 已提交
5667 5668
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5669

5670
				var cubeImage = [];
5671

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

5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685
					if ( _this.autoScaleCubemaps ) {

						cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize );

					} else {

						cubeImage[ i ] = texture.image[ i ];

					}

				}

5686 5687
				var image = cubeImage[ 0 ],
				isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
5688 5689
				glFormat = paramThreeToGL( texture.format ),
				glType = paramThreeToGL( texture.type );
5690

5691 5692
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo );

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

5695
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
5696

A
alteredq 已提交
5697
				}
5698

5699
				if ( texture.generateMipmaps && isImagePowerOfTwo )	_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
5700

A
alteredq 已提交
5701
				texture.needsUpdate = false;
5702

5703
				if ( texture.onUpdate ) texture.onUpdate();
5704

A
alteredq 已提交
5705
			} else {
5706

A
alteredq 已提交
5707 5708
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5709

A
alteredq 已提交
5710
			}
5711

A
alteredq 已提交
5712
		}
5713

A
alteredq 已提交
5714
	};
5715

5716
	function setCubeTextureDynamic ( texture, slot ) {
5717

A
alteredq 已提交
5718 5719
		_gl.activeTexture( _gl.TEXTURE0 + slot );
		_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
5720 5721 5722

	};

5723 5724 5725
	// Render targets

	function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
5726

5727 5728
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
A
alteredq 已提交
5729

5730
	};
M
Mr.doob 已提交
5731

5732
	function setupRenderBuffer ( renderbuffer, renderTarget  ) {
M
Mikael Emtinger 已提交
5733

5734
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
5735

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

5738 5739
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5740

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

5744 5745 5746 5747
			_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 已提交
5748

5749 5750
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5751

5752
		} else {
A
alteredq 已提交
5753

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

5756
		}
A
alteredq 已提交
5757

5758
	};
A
alteredq 已提交
5759

A
alteredq 已提交
5760
	this.setRenderTarget = function ( renderTarget ) {
A
alteredq 已提交
5761

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

5764
		if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
A
alteredq 已提交
5765

5766 5767
			if( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
			if( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
A
alteredq 已提交
5768

5769
			renderTarget.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5770

5771
			// Setup texture, create render and frame buffers
5772

5773 5774
			var isTargetPowerOfTwo = isPowerOfTwo( renderTarget.width ) && isPowerOfTwo( renderTarget.height ),
				glFormat = paramThreeToGL( renderTarget.format ),
5775 5776
				glType = paramThreeToGL( renderTarget.type );

5777
			if ( isCube ) {
M
Mr.doob 已提交
5778

5779 5780
				renderTarget.__webglFramebuffer = [];
				renderTarget.__webglRenderbuffer = [];
M
Mikael Emtinger 已提交
5781

5782
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
5783
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, isTargetPowerOfTwo );
A
alteredq 已提交
5784

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

5787 5788
					renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
					renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
A
alteredq 已提交
5789

5790
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
A
alteredq 已提交
5791

5792 5793
					setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
					setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
A
alteredq 已提交
5794

5795
				}
5796

5797
			} else {
5798

5799 5800
				renderTarget.__webglFramebuffer = _gl.createFramebuffer();
				renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
5801

5802
				_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
5803
				setTextureParameters( _gl.TEXTURE_2D, renderTarget, isTargetPowerOfTwo );
5804

5805
				_gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
5806

5807 5808
				setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
				setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
5809

M
Mikael Emtinger 已提交
5810
			}
5811

5812
			// Release everything
M
Mr.doob 已提交
5813

A
alteredq 已提交
5814 5815 5816 5817 5818 5819 5820 5821 5822 5823
			if ( isCube ) {

				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

			} else {

				_gl.bindTexture( _gl.TEXTURE_2D, null );

			}

5824 5825
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
5826

5827 5828
		}

5829
		var framebuffer, width, height, vx, vy;
M
Mr.doob 已提交
5830

5831
		if ( renderTarget ) {
M
Mr.doob 已提交
5832

A
alteredq 已提交
5833 5834
			if ( isCube ) {

5835
				framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
A
alteredq 已提交
5836 5837 5838

			} else {

5839
				framebuffer = renderTarget.__webglFramebuffer;
A
alteredq 已提交
5840 5841 5842

			}

5843 5844
			width = renderTarget.width;
			height = renderTarget.height;
M
Mr.doob 已提交
5845

5846 5847 5848
			vx = 0;
			vy = 0;

5849
		} else {
M
Mr.doob 已提交
5850

5851
			framebuffer = null;
5852

5853 5854
			width = _viewportWidth;
			height = _viewportHeight;
5855

5856 5857
			vx = _viewportX;
			vy = _viewportY;
M
Mr.doob 已提交
5858

5859
		}
M
Mr.doob 已提交
5860

5861
		if ( framebuffer !== _currentFramebuffer ) {
M
Mr.doob 已提交
5862

5863
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
5864
			_gl.viewport( vx, vy, width, height );
M
Mr.doob 已提交
5865

5866
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
5867

5868
		}
5869

A
alteredq 已提交
5870 5871 5872
		_currentWidth = width;
		_currentHeight = height;

5873
	};
M
Mr.doob 已提交
5874

5875
	function updateRenderTargetMipmap ( renderTarget ) {
M
Mr.doob 已提交
5876

A
alteredq 已提交
5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889
		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 已提交
5890 5891

	};
5892

5893
	// Fallback filters for non-power-of-2 textures
5894

5895
	function filterFallback ( f ) {
5896

5897 5898 5899 5900 5901 5902 5903 5904
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mr.doob 已提交
5905
			case THREE.LinearMipMapLinearFilter:
M
Mikael Emtinger 已提交
5906
			default:
5907

M
Mikael Emtinger 已提交
5908
				return _gl.LINEAR; break;
5909 5910

		}
5911

5912
	};
5913

5914 5915
	// Map three.js constants to WebGL constants

5916
	function paramThreeToGL ( p ) {
M
Mr.doob 已提交
5917

5918
		switch ( p ) {
M
Mr.doob 已提交
5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931

			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;

5932 5933 5934 5935 5936
			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;
5937
			case THREE.UnsignedIntType: return _gl.UNSIGNED_INT; break;
5938 5939 5940 5941 5942 5943 5944 5945
			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;

5946
		}
M
Mr.doob 已提交
5947

5948
		return 0;
M
Mr.doob 已提交
5949

5950 5951
	};

5952
	// Allocations
5953

5954
	function allocateBones ( object ) {
5955

5956 5957 5958 5959 5960 5961 5962
		// 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)
5963

5964
		var maxBones = 50;
5965

5966
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
5967

5968 5969 5970 5971 5972
			maxBones = object.bones.length;

		}

		return maxBones;
5973

5974
	};
5975

5976
	function allocateLights ( lights ) {
5977

5978 5979
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
5980

5981
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
5982

5983
			light = lights[ l ];
5984

A
alteredq 已提交
5985 5986
			if ( light.onlyShadow ) continue;

5987 5988
			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
			if ( light instanceof THREE.PointLight ) pointLights ++;
5989
			if ( light instanceof THREE.SpotLight ) pointLights ++;
5990

5991
		}
5992

5993
		if ( ( pointLights + dirLights ) <= _maxLights ) {
5994

5995 5996
			maxDirLights = dirLights;
			maxPointLights = pointLights;
5997

5998
		} else {
5999

6000 6001
			maxDirLights = Math.ceil( _maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = _maxLights - maxDirLights;
6002 6003 6004

		}

6005
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
6006 6007

	};
M
Mr.doob 已提交
6008

6009
	function allocateShadows ( lights ) {
6010

M
Mr.doob 已提交
6011
		var l, ll, light, maxShadows = 0;
6012 6013 6014 6015 6016

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

			light = lights[ l ];

A
alteredq 已提交
6017 6018
			if ( ! light.castShadow ) continue;

6019 6020
			if ( light instanceof THREE.SpotLight ) maxShadows ++;
			if ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) maxShadows ++;
6021 6022 6023 6024 6025 6026 6027

		}

		return maxShadows;

	};

6028
	// Initialization
M
Mr.doob 已提交
6029

6030 6031 6032 6033 6034 6035
	function initGL () {

		var gl;

		try {

6036
			if ( ! ( gl = _canvas.getContext( 'experimental-webgl', { alpha: _alpha, premultipliedAlpha: _premultipliedAlpha, antialias: _antialias, stencil: _stencil, preserveDrawingBuffer: _preserveDrawingBuffer } ) ) ) {
6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080

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

	};

6081 6082
	// default plugins (order is important)

A
alteredq 已提交
6083 6084 6085 6086 6087
	this.shadowMapPlugin = new THREE.ShadowMapPlugin();
	this.addPrePlugin( this.shadowMapPlugin );

	this.addPostPlugin( new THREE.SpritePlugin() );
	this.addPostPlugin( new THREE.LensFlarePlugin() );
6088

6089
};