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

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

M
Mr.doob 已提交
10 11
	// Currently you can use just up to 4 directional / point lights total.
	// Chrome barfs on shader linking when there are more than 4 lights :(
M
Mr.doob 已提交
12

13
	// The problem comes from shader using too many varying vectors.
M
Mr.doob 已提交
14

15
	// This is not GPU limitation as the same shader works ok in Firefox
M
Mr.doob 已提交
16
	// and Chrome with "--use-gl=desktop" flag.
M
Mr.doob 已提交
17

M
Mr.doob 已提交
18
	// Difference comes from Chrome on Windows using by default ANGLE,
19
	// thus going DirectX9 route (while FF uses OpenGL).
M
Mr.doob 已提交
20

21
	// See http://code.google.com/p/chromium/issues/detail?id=63491
M
Mr.doob 已提交
22

M
Mr.doob 已提交
23
	var _canvas = document.createElement( 'canvas' ), _gl,
24
	_oldProgram = null,
25
	_oldFramebuffer = null,
M
Mr.doob 已提交
26

A
alteredq 已提交
27
	_this = this,
28

A
alteredq 已提交
29
	// gl state cache
30

31 32
	_oldDoubleSided = null,
	_oldFlipSided = null,
A
alteredq 已提交
33
	_oldBlending = null,
A
alteredq 已提交
34
	_oldDepth = null,
35

36 37 38 39 40
	_viewportX = 0,
	_viewportY = 0,
	_viewportWidth = 0,
	_viewportHeight = 0,

41
	// camera matrices caches
42 43

	_frustum = [
44 45 46 47 48 49 50 51
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4()
	 ],

52
	_projScreenMatrix = new THREE.Matrix4(),
53
	_projectionMatrixArray = new Float32Array( 16 ),
54
	_viewMatrixArray = new Float32Array( 16 ),
55

56
	_vector3 = new THREE.Vector4(),
57

A
alteredq 已提交
58 59 60 61 62 63 64 65 66 67
	// light arrays cache
	
	_lights = {

		ambient: 	 [ 0, 0, 0 ],
		directional: { length: 0, colors: new Array(), positions: new Array() },
		point: 		 { length: 0, colors: new Array(), positions: new Array() }

	},

68
	// parameters defaults
M
Mr.doob 已提交
69

70 71 72
	antialias = true,
	clearColor = new THREE.Color( 0x000000 ),
	clearAlpha = 0;
73

74
	if ( parameters ) {
M
Mr.doob 已提交
75

76 77 78
		if ( parameters.antialias !== undefined ) antialias = parameters.antialias;
		if ( parameters.clearColor !== undefined ) clearColor.setHex( parameters.clearColor );
		if ( parameters.clearAlpha !== undefined ) clearAlpha = parameters.clearAlpha;
M
Mr.doob 已提交
79

80
	}
M
Mr.doob 已提交
81

82
	this.maxMorphTargets = 8;
N
Nicolas Garcia Belmonte 已提交
83 84
	this.domElement = _canvas;
	this.autoClear = true;
85
	this.sortObjects = true;
N
Nicolas Garcia Belmonte 已提交
86

87
	initGL( antialias, clearColor, clearAlpha );
M
Mr.doob 已提交
88

89 90
	this.context = _gl;

91
	// alert( dumpObject( getGLParams() ) );
M
Mr.doob 已提交
92

N
Nicolas Garcia Belmonte 已提交
93 94 95 96
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
97

98 99 100
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
101

102
	this.setViewport = function ( x, y, width, height ) {
103

104 105
		_viewportX = x;
		_viewportY = y;
106

107 108
		_viewportWidth = width;
		_viewportHeight = height;
109

110
		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
111

N
Nicolas Garcia Belmonte 已提交
112
	};
113

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

116
		_gl.scissor( x, y, width, height );
117

118
	};
119

120
	this.enableScissorTest = function ( enable ) {
121

122 123 124 125
		if ( enable )
			_gl.enable( _gl.SCISSOR_TEST );
		else
			_gl.disable( _gl.SCISSOR_TEST );
126

127
	};
128

129
	this.enableDepthBufferWrite = function ( enable ) {
130

131 132 133
		_gl.depthMask( enable );

	};
134

135
	this.setClearColorHex = function ( hex, alpha ) {
136

137 138
		var color = new THREE.Color( hex );
		_gl.clearColor( color.r, color.g, color.b, alpha );
139

140
	};
A
alteredq 已提交
141

142
	this.setClearColor = function ( color, alpha ) {
A
alteredq 已提交
143 144 145 146

		_gl.clearColor( color.r, color.g, color.b, alpha );

	};
147

N
Nicolas Garcia Belmonte 已提交
148 149 150 151 152 153
	this.clear = function () {

		_gl.clear( _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT );

	};

M
Mr.doob 已提交
154

A
alteredq 已提交
155
	function setupLights ( program, lights ) {
156

157
		var l, ll, light, r = 0, g = 0, b = 0,
158
			color, position, intensity,
M
Mr.doob 已提交
159

A
alteredq 已提交
160
			zlights = _lights,
M
Mr.doob 已提交
161

162 163
			dcolors    = zlights.directional.colors,
			dpositions = zlights.directional.positions,
164

165 166
			pcolors    = zlights.point.colors,
			ppositions = zlights.point.positions,
167

168
			dlength = 0,
169
			plength = 0,
170

171 172
			doffset = 0,
			poffset = 0;
M
Mr.doob 已提交
173

174
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
175

176
			light = lights[ l ];
177 178 179
			color = light.color;
			position = light.position;
			intensity = light.intensity;
180 181 182

			if ( light instanceof THREE.AmbientLight ) {

183 184 185
				r += color.r;
				g += color.g;
				b += color.b;
M
Mr.doob 已提交
186

187
			} else if ( light instanceof THREE.DirectionalLight ) {
188

189
				doffset = dlength * 3;
190

191 192 193
				dcolors[ doffset ]     = color.r * intensity;
				dcolors[ doffset + 1 ] = color.g * intensity;
				dcolors[ doffset + 2 ] = color.b * intensity;
194

195 196 197
				dpositions[ doffset ]     = position.x;
				dpositions[ doffset + 1 ] = position.y;
				dpositions[ doffset + 2 ] = position.z;
198

199
				dlength += 1;
M
Mr.doob 已提交
200

201 202
			} else if( light instanceof THREE.PointLight ) {

203
				poffset = plength * 3;
204

205 206 207
				pcolors[ poffset ]     = color.r * intensity;
				pcolors[ poffset + 1 ] = color.g * intensity;
				pcolors[ poffset + 2 ] = color.b * intensity;
208

209 210 211
				ppositions[ poffset ]     = position.x;
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
M
Mr.doob 已提交
212

213
				plength += 1;
M
Mr.doob 已提交
214

215 216 217
			}

		}
218

219 220
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
221

222 223
		for( l = dlength * 3; l < dcolors.length; l++ ) dcolors[ l ] = 0.0;
		for( l = plength * 3; l < pcolors.length; l++ ) pcolors[ l ] = 0.0;
M
Mr.doob 已提交
224

225 226
		zlights.point.length = plength;
		zlights.directional.length = dlength;
M
Mr.doob 已提交
227

228 229 230
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
M
Mr.doob 已提交
231

232
	};
M
Mr.doob 已提交
233

234
	function createParticleBuffers ( geometry ) {
M
Mr.doob 已提交
235

236
		geometry.__webGLVertexBuffer = _gl.createBuffer();
237
		geometry.__webGLColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
238

239
	};
M
Mr.doob 已提交
240

241
	function createLineBuffers ( geometry ) {
M
Mr.doob 已提交
242

243
		geometry.__webGLVertexBuffer = _gl.createBuffer();
244
		geometry.__webGLColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
245

246
	};
247

A
alteredq 已提交
248 249 250 251 252 253 254
	function createRibbonBuffers ( geometry ) {

		geometry.__webGLVertexBuffer = _gl.createBuffer();
		geometry.__webGLColorBuffer = _gl.createBuffer();

	};

255
	function createMeshBuffers ( geometryGroup ) {
M
Mr.doob 已提交
256

257 258 259 260 261 262
		geometryGroup.__webGLVertexBuffer = _gl.createBuffer();
		geometryGroup.__webGLNormalBuffer = _gl.createBuffer();
		geometryGroup.__webGLTangentBuffer = _gl.createBuffer();
		geometryGroup.__webGLColorBuffer = _gl.createBuffer();
		geometryGroup.__webGLUVBuffer = _gl.createBuffer();
		geometryGroup.__webGLUV2Buffer = _gl.createBuffer();
263

264 265 266 267
		geometryGroup.__webGLSkinVertexABuffer = _gl.createBuffer();
		geometryGroup.__webGLSkinVertexBBuffer = _gl.createBuffer();
		geometryGroup.__webGLSkinIndicesBuffer = _gl.createBuffer();
		geometryGroup.__webGLSkinWeightsBuffer = _gl.createBuffer();
268

269 270
		geometryGroup.__webGLFaceBuffer = _gl.createBuffer();
		geometryGroup.__webGLLineBuffer = _gl.createBuffer();
271 272
		
		
273
		if( geometryGroup.numMorphTargets ) {
274
			
275 276
			var m, ml;
			geometryGroup.__webGLMorphTargetsBuffers = []; 
277
			
278
			for( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m++ ) {
279
				
280
				geometryGroup.__webGLMorphTargetsBuffers.push( _gl.createBuffer());	
281 282 283
			}

		}
M
Mr.doob 已提交
284

285
	};
286

287
	function initLineBuffers ( geometry ) {
M
Mr.doob 已提交
288

289 290 291
		var nvertices = geometry.vertices.length;

		geometry.__vertexArray = new Float32Array( nvertices * 3 );
292
		geometry.__colorArray = new Float32Array( nvertices * 3 );
M
Mr.doob 已提交
293

294
		geometry.__webGLLineCount = nvertices;
M
Mr.doob 已提交
295

296
	};
M
Mr.doob 已提交
297

298
	function initRibbonBuffers ( geometry ) {
A
alteredq 已提交
299 300 301 302 303 304 305 306 307

		var nvertices = geometry.vertices.length;

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

		geometry.__webGLVertexCount = nvertices;

	};
308

309
	function initParticleBuffers ( geometry ) {
310 311 312 313

		var nvertices = geometry.vertices.length;

		geometry.__vertexArray = new Float32Array( nvertices * 3 );
A
alteredq 已提交
314
		geometry.__colorArray = new Float32Array( nvertices * 3 );
315

316
		geometry.__sortArray = [];
317 318 319 320 321

		geometry.__webGLParticleCount = nvertices;

	};

322
	function initMeshBuffers ( geometryGroup, object ) {
M
Mr.doob 已提交
323

324 325 326 327 328 329 330 331 332 333 334
		var f, fl, 
		
			nvertices = 0, ntris = 0, nlines = 0,
			
			uvType,
			vertexColorType,
			normalType,
			materials,
		
			geometry = object.geometry,
			obj_faces = geometry.faces,
335
			chunk_faces = geometryGroup.faces;
M
Mr.doob 已提交
336

337
		for ( f = 0, fl = chunk_faces.length; f < fl; f++ ) {
M
Mr.doob 已提交
338

339 340
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
M
Mr.doob 已提交
341

342
			if ( face instanceof THREE.Face3 ) {
M
Mr.doob 已提交
343

344 345 346
				nvertices += 3;
				ntris += 1;
				nlines += 3;
M
Mr.doob 已提交
347

348
			} else if ( face instanceof THREE.Face4 ) {
M
Mr.doob 已提交
349

350 351
				nvertices += 4;
				ntris += 2;
352
				nlines += 4;
M
Mr.doob 已提交
353

354
			}
M
Mr.doob 已提交
355

356
		}
357
		
A
alteredq 已提交
358
		materials = unrollGroupMaterials( geometryGroup, object );		
359 360 361
		
		uvType = bufferGuessUVType( materials, geometryGroup, object );
		normalType = bufferGuessNormalType( materials, geometryGroup, object );
A
alteredq 已提交
362 363
		vertexColorType = bufferGuessVertexColorType( materials, geometryGroup, object );

364
		//console.log("uvType",uvType, "normalType",normalType, "vertexColorType",vertexColorType, object, geometryGroup, materials );
M
Mr.doob 已提交
365

366 367 368
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
		
		if ( normalType ) {
M
Mr.doob 已提交
369

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

372 373 374 375 376
		}
		
		if ( geometry.hasTangents ) {
		
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
377

378 379 380 381 382
		}
		
		if ( vertexColorType ) {
		
			geometryGroup.__colorArray = new Float32Array( nvertices * 3 );
M
Mr.doob 已提交
383

384
		}
M
Mr.doob 已提交
385

386
		if ( uvType ) {
A
alteredq 已提交
387
			
388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
			
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

			if ( geometry.faceUvs.length > 1 || geometry.faceVertexUvs.length > 1 ) {
			
				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 );

		}

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

414
		if( geometryGroup.numMorphTargets ) {
415
			
416 417
			var m, ml;
			geometryGroup.__morphTargetsArrays = []; 
418
			
419
			for( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m++ ) {
420
				
421
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ));
422 423 424
			}

		}
425 426 427 428 429 430 431 432 433
		
		geometryGroup.__needsSmoothNormals = ( normalType == THREE.SmoothShading );
		
		geometryGroup.__uvType = uvType;
		geometryGroup.__vertexColorType = vertexColorType;
		geometryGroup.__normalType = normalType;

		geometryGroup.__webGLFaceCount = ntris * 3;
		geometryGroup.__webGLLineCount = nlines * 2;		
434

435
	};
M
Mr.doob 已提交
436

437
	function setMeshBuffers ( geometryGroup, object, hint ) {
438

439 440 441
		var f, fl, fi, face, 
			vertexNormals, faceNormal, normal,
			vertexColors, faceColor,
442
			vertexTangents,
A
alteredq 已提交
443
			uvType, vertexColorType, normalType,
444
			uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4,
445
			c1, c2, c3, c4,
A
alteredq 已提交
446 447 448 449
			sw1, sw2, sw3, sw4,
			si1, si2, si3, si4,
			sa1, sa2, sa3, sa4,
			sb1, sb2, sb3, sb4,
450
			m, ml, i,
451
			vn, uvi, uv2i,
452
			vk, vkl, vka,
M
Mr.doob 已提交
453

454
		vertexIndex = 0,
455

456 457
		offset = 0,
		offset_uv = 0,
458
		offset_uv2 = 0,
459 460 461 462
		offset_face = 0,
		offset_normal = 0,
		offset_tangent = 0,
		offset_line = 0,
463
		offset_color = 0,
A
alteredq 已提交
464
		offset_skin = 0,
465
		offset_morphTarget = 0,
M
Mr.doob 已提交
466

467 468 469 470 471 472
		vertexArray = geometryGroup.__vertexArray,
		uvArray = geometryGroup.__uvArray,
		uv2Array = geometryGroup.__uv2Array,
		normalArray = geometryGroup.__normalArray,
		tangentArray = geometryGroup.__tangentArray,
		colorArray = geometryGroup.__colorArray,
473

474 475 476 477
		skinVertexAArray = geometryGroup.__skinVertexAArray,
		skinVertexBArray = geometryGroup.__skinVertexBArray,
		skinIndexArray = geometryGroup.__skinIndexArray,
		skinWeightArray = geometryGroup.__skinWeightArray,
M
Mr.doob 已提交
478

479 480
		morphTargetsArrays = geometryGroup.__morphTargetsArrays,

481 482
		faceArray = geometryGroup.__faceArray,
		lineArray = geometryGroup.__lineArray,
M
Mr.doob 已提交
483

484
		needsSmoothNormals = geometryGroup.__needsSmoothNormals,
485 486
		
		vertexColorType = geometryGroup.__vertexColorType,
A
alteredq 已提交
487 488
		uvType = geometryGroup.__uvType,
		normalType = geometryGroup.__normalType,
489

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

492
		dirtyVertices = geometry.__dirtyVertices,
493 494 495
		dirtyElements = geometry.__dirtyElements,
		dirtyUvs = geometry.__dirtyUvs,
		dirtyNormals = geometry.__dirtyNormals,
496
		dirtyTangents = geometry.__dirtyTangents,
497
		dirtyColors = geometry.__dirtyColors,
498
		dirtyMorphTargets = geometry.__dirtyMorphTargets,
M
Mr.doob 已提交
499

500
		vertices = geometry.vertices,
501
		chunk_faces = geometryGroup.faces,
502
		obj_faces = geometry.faces,
503 504 505 506
		
		obj_uvs  = geometry.faceVertexUvs[ 0 ],
		obj_uvs2 = geometry.faceVertexUvs[ 1 ],
		
A
alteredq 已提交
507
		obj_colors = geometry.colors,
508

A
alteredq 已提交
509 510 511
		obj_skinVerticesA = geometry.skinVerticesA,
		obj_skinVerticesB = geometry.skinVerticesB,
		obj_skinIndices = geometry.skinIndices,
512 513 514 515
		obj_skinWeights = geometry.skinWeights,

		morphTargets = geometry.morphTargets;
		
516

517
		for ( f = 0, fl = chunk_faces.length; f < fl; f++ ) {
M
Mr.doob 已提交
518

519 520
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
A
alteredq 已提交
521 522 523 524 525 526 527 528 529 530 531 532
			
			if( obj_uvs ) {

				uv = obj_uvs[ fi ];

			}
			
			if( obj_uvs2 ) {
				
				uv2 = obj_uvs2[ fi ];

			}
M
Mr.doob 已提交
533

534
			vertexNormals = face.vertexNormals;
535
			faceNormal = face.normal;
536 537 538
			
			vertexColors = face.vertexColors;
			faceColor = face.color;
539 540
			
			vertexTangents = face.vertexTangents;
541 542 543

			if ( face instanceof THREE.Face3 ) {

544
				if ( dirtyVertices ) {
M
Mr.doob 已提交
545

546 547 548
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
M
Mr.doob 已提交
549

550 551 552
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
553

554 555 556
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
557

558 559 560
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
M
Mr.doob 已提交
561

562
					offset += 9;
M
Mr.doob 已提交
563

564
				}
565

566
				if ( dirtyMorphTargets ) {
567
					
568
					for( vk = 0, vkl = morphTargets.length; vk < vkl; vk++ ) {
569
						
570 571 572
						v1 = morphTargets[ vk ].vertices[ face.a ].position;
						v2 = morphTargets[ vk ].vertices[ face.b ].position;
						v3 = morphTargets[ vk ].vertices[ face.c ].position;
573

574
						vka = morphTargetsArrays[ vk ];
575
	
576 577 578
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
579
	
580 581 582
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
583
	
584 585 586
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
587 588
					}

589
					offset_morphTarget += 9;
590 591 592
					
				}

A
alteredq 已提交
593 594 595
				if ( obj_skinWeights.length ) {

					// weights
596

A
alteredq 已提交
597 598 599
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
600

A
alteredq 已提交
601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616
					skinWeightArray[ offset_skin ]     = sw1.x;
					skinWeightArray[ offset_skin + 1 ] = sw1.y;
					skinWeightArray[ offset_skin + 2 ] = sw1.z;
					skinWeightArray[ offset_skin + 3 ] = sw1.w;

					skinWeightArray[ offset_skin + 4 ] = sw2.x;
					skinWeightArray[ offset_skin + 5 ] = sw2.y;
					skinWeightArray[ offset_skin + 6 ] = sw2.z;
					skinWeightArray[ offset_skin + 7 ] = sw2.w;

					skinWeightArray[ offset_skin + 8 ]  = sw3.x;
					skinWeightArray[ offset_skin + 9 ]  = sw3.y;
					skinWeightArray[ offset_skin + 10 ] = sw3.z;
					skinWeightArray[ offset_skin + 11 ] = sw3.w;

					// indices
617

A
alteredq 已提交
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637
					si1 = obj_skinIndices[ face.a ];
					si2 = obj_skinIndices[ face.b ];
					si3 = obj_skinIndices[ face.c ];

					skinIndexArray[ offset_skin ]     = si1.x;
					skinIndexArray[ offset_skin + 1 ] = si1.y;
					skinIndexArray[ offset_skin + 2 ] = si1.z;
					skinIndexArray[ offset_skin + 3 ] = si1.w;

					skinIndexArray[ offset_skin + 4 ] = si2.x;
					skinIndexArray[ offset_skin + 5 ] = si2.y;
					skinIndexArray[ offset_skin + 6 ] = si2.z;
					skinIndexArray[ offset_skin + 7 ] = si2.w;

					skinIndexArray[ offset_skin + 8 ]  = si3.x;
					skinIndexArray[ offset_skin + 9 ]  = si3.y;
					skinIndexArray[ offset_skin + 10 ] = si3.z;
					skinIndexArray[ offset_skin + 11 ] = si3.w;

					// vertices A
638

A
alteredq 已提交
639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658
					sa1 = obj_skinVerticesA[ face.a ];
					sa2 = obj_skinVerticesA[ face.b ];
					sa3 = obj_skinVerticesA[ face.c ];

					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

					skinVertexAArray[ offset_skin + 4 ] = sa2.x;
					skinVertexAArray[ offset_skin + 5 ] = sa2.y;
					skinVertexAArray[ offset_skin + 6 ] = sa2.z;
					skinVertexAArray[ offset_skin + 7 ] = 1;

					skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
					skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
					skinVertexAArray[ offset_skin + 10 ] = sa3.z;
					skinVertexAArray[ offset_skin + 11 ] = 1;

					// vertices B
659

A
alteredq 已提交
660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679
					sb1 = obj_skinVerticesB[ face.a ];
					sb2 = obj_skinVerticesB[ face.b ];
					sb3 = obj_skinVerticesB[ face.c ];

					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

					skinVertexBArray[ offset_skin + 4 ] = sb2.x;
					skinVertexBArray[ offset_skin + 5 ] = sb2.y;
					skinVertexBArray[ offset_skin + 6 ] = sb2.z;
					skinVertexBArray[ offset_skin + 7 ] = 1;

					skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
					skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
					skinVertexBArray[ offset_skin + 10 ] = sb3.z;
					skinVertexBArray[ offset_skin + 11 ] = 1;

					offset_skin += 12;
680

A
alteredq 已提交
681
				}
682

683 684 685
				if ( dirtyColors && vertexColorType ) {

					if ( vertexColors.length == 3 && vertexColorType == THREE.VertexColors ) {
686

687 688 689 690 691 692 693 694 695 696 697
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];

					} else {
						
						c1 = faceColor;
						c2 = faceColor;
						c3 = faceColor;

					}
698 699 700 701 702 703 704 705 706 707 708 709

					colorArray[ offset_color ]     = c1.r;
					colorArray[ offset_color + 1 ] = c1.g;
					colorArray[ offset_color + 2 ] = c1.b;

					colorArray[ offset_color + 3 ] = c2.r;
					colorArray[ offset_color + 4 ] = c2.g;
					colorArray[ offset_color + 5 ] = c2.b;

					colorArray[ offset_color + 6 ] = c3.r;
					colorArray[ offset_color + 7 ] = c3.g;
					colorArray[ offset_color + 8 ] = c3.b;
710

711 712 713 714
					offset_color += 9;

				}

715
				if ( dirtyTangents && geometry.hasTangents ) {
716

717 718 719
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
720

721 722 723 724
					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 已提交
725

726 727 728 729
					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 已提交
730

731 732 733 734
					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 已提交
735

736
					offset_tangent += 12;
M
Mr.doob 已提交
737

738 739
				}

A
alteredq 已提交
740
				if ( dirtyNormals && normalType ) {
M
Mr.doob 已提交
741

742 743 744
					if ( vertexNormals.length == 3 && needsSmoothNormals ) {

						for ( i = 0; i < 3; i ++ ) {
745

746
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
747

748 749 750
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
751

752
							offset_normal += 3;
M
Mr.doob 已提交
753

754
						}
M
Mr.doob 已提交
755

756
					} else {
757

758
						for ( i = 0; i < 3; i ++ ) {
759

760 761 762
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
763

764
							offset_normal += 3;
M
Mr.doob 已提交
765

766
						}
M
Mr.doob 已提交
767 768

					}
M
Mr.doob 已提交
769

770 771
				}

A
alteredq 已提交
772
				if ( dirtyUvs && uv !== undefined && uvType ) {
773

M
Mr.doob 已提交
774 775
					for ( i = 0; i < 3; i ++ ) {

776
						uvi = uv[ i ];
M
Mr.doob 已提交
777

778 779
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
780

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

M
Mr.doob 已提交
783
					}
784 785 786

				}

A
alteredq 已提交
787
				if ( dirtyUvs && uv2 !== undefined && uvType ) {
788 789 790 791 792 793 794 795 796 797 798 799 800 801

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

						uv2i = uv2[ i ];

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

						offset_uv2 += 2;

					}

				}

802
				if( dirtyElements ) {
M
Mr.doob 已提交
803

804 805 806
					faceArray[ offset_face ] = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
M
Mr.doob 已提交
807

808
					offset_face += 3;
M
Mr.doob 已提交
809

810 811
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
812

813 814
					lineArray[ offset_line + 2 ] = vertexIndex;
					lineArray[ offset_line + 3 ] = vertexIndex + 2;
M
Mr.doob 已提交
815

816 817
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
818

819
					offset_line += 6;
820

821
					vertexIndex += 3;
M
Mr.doob 已提交
822

823
				}
M
Mr.doob 已提交
824

825 826 827

			} else if ( face instanceof THREE.Face4 ) {

828
				if ( dirtyVertices ) {
M
Mr.doob 已提交
829

830 831 832 833
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
					v4 = vertices[ face.d ].position;
M
Mr.doob 已提交
834

835 836 837
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
838

839 840 841
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
842

843 844 845
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
846

847 848 849
					vertexArray[ offset + 9 ] = v4.x;
					vertexArray[ offset + 10 ] = v4.y;
					vertexArray[ offset + 11 ] = v4.z;
M
Mr.doob 已提交
850

851
					offset += 12;
M
Mr.doob 已提交
852

853
				}
854

855
				if ( dirtyMorphTargets ) {
856
					
857
					for( vk = 0, vkl = morphTargets.length; vk < vkl; vk++ ) {
858
						
859 860 861 862
						v1 = morphTargets[ vk ].vertices[ face.a ].position;
						v2 = morphTargets[ vk ].vertices[ face.b ].position;
						v3 = morphTargets[ vk ].vertices[ face.c ].position;
						v4 = morphTargets[ vk ].vertices[ face.d ].position;
863
	
864
						vka = morphTargetsArrays[ vk ];
865
	
866 867 868
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
869
	
870 871 872
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
873
	
874 875 876
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
877
	
878 879 880
						vka[ offset_morphTarget + 9 ] = v4.x;
						vka[ offset_morphTarget + 10 ] = v4.y;
						vka[ offset_morphTarget + 11 ] = v4.z;
881 882
					}

883
					offset_morphTarget += 12;
884 885 886
					
				}

A
alteredq 已提交
887 888 889
				if ( obj_skinWeights.length ) {

					// weights
890

A
alteredq 已提交
891 892 893 894
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
					sw4 = obj_skinWeights[ face.d ];
895

A
alteredq 已提交
896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916
					skinWeightArray[ offset_skin ]     = sw1.x;
					skinWeightArray[ offset_skin + 1 ] = sw1.y;
					skinWeightArray[ offset_skin + 2 ] = sw1.z;
					skinWeightArray[ offset_skin + 3 ] = sw1.w;

					skinWeightArray[ offset_skin + 4 ] = sw2.x;
					skinWeightArray[ offset_skin + 5 ] = sw2.y;
					skinWeightArray[ offset_skin + 6 ] = sw2.z;
					skinWeightArray[ offset_skin + 7 ] = sw2.w;

					skinWeightArray[ offset_skin + 8 ]  = sw3.x;
					skinWeightArray[ offset_skin + 9 ]  = sw3.y;
					skinWeightArray[ offset_skin + 10 ] = sw3.z;
					skinWeightArray[ offset_skin + 11 ] = sw3.w;

					skinWeightArray[ offset_skin + 12 ] = sw4.x;
					skinWeightArray[ offset_skin + 13 ] = sw4.y;
					skinWeightArray[ offset_skin + 14 ] = sw4.z;
					skinWeightArray[ offset_skin + 15 ] = sw4.w;

					// indices
917

A
alteredq 已提交
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
					si1 = obj_skinIndices[ face.a ];
					si2 = obj_skinIndices[ face.b ];
					si3 = obj_skinIndices[ face.c ];
					si4 = obj_skinIndices[ face.d ];

					skinIndexArray[ offset_skin ]     = si1.x;
					skinIndexArray[ offset_skin + 1 ] = si1.y;
					skinIndexArray[ offset_skin + 2 ] = si1.z;
					skinIndexArray[ offset_skin + 3 ] = si1.w;

					skinIndexArray[ offset_skin + 4 ] = si2.x;
					skinIndexArray[ offset_skin + 5 ] = si2.y;
					skinIndexArray[ offset_skin + 6 ] = si2.z;
					skinIndexArray[ offset_skin + 7 ] = si2.w;

					skinIndexArray[ offset_skin + 8 ]  = si3.x;
					skinIndexArray[ offset_skin + 9 ]  = si3.y;
					skinIndexArray[ offset_skin + 10 ] = si3.z;
					skinIndexArray[ offset_skin + 11 ] = si3.w;

					skinIndexArray[ offset_skin + 12 ] = si4.x;
					skinIndexArray[ offset_skin + 13 ] = si4.y;
					skinIndexArray[ offset_skin + 14 ] = si4.z;
					skinIndexArray[ offset_skin + 15 ] = si4.w;

					// vertices A
944

A
alteredq 已提交
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
					sa1 = obj_skinVerticesA[ face.a ];
					sa2 = obj_skinVerticesA[ face.b ];
					sa3 = obj_skinVerticesA[ face.c ];
					sa4 = obj_skinVerticesA[ face.d ];

					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

					skinVertexAArray[ offset_skin + 4 ] = sa2.x;
					skinVertexAArray[ offset_skin + 5 ] = sa2.y;
					skinVertexAArray[ offset_skin + 6 ] = sa2.z;
					skinVertexAArray[ offset_skin + 7 ] = 1;

					skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
					skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
					skinVertexAArray[ offset_skin + 10 ] = sa3.z;
					skinVertexAArray[ offset_skin + 11 ] = 1;

					skinVertexAArray[ offset_skin + 12 ] = sa4.x;
					skinVertexAArray[ offset_skin + 13 ] = sa4.y;
					skinVertexAArray[ offset_skin + 14 ] = sa4.z;
					skinVertexAArray[ offset_skin + 15 ] = 1;

					// vertices B
971

A
alteredq 已提交
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
					sb1 = obj_skinVerticesB[ face.a ];
					sb2 = obj_skinVerticesB[ face.b ];
					sb3 = obj_skinVerticesB[ face.c ];
					sb4 = obj_skinVerticesB[ face.d ];

					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

					skinVertexBArray[ offset_skin + 4 ] = sb2.x;
					skinVertexBArray[ offset_skin + 5 ] = sb2.y;
					skinVertexBArray[ offset_skin + 6 ] = sb2.z;
					skinVertexBArray[ offset_skin + 7 ] = 1;

					skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
					skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
					skinVertexBArray[ offset_skin + 10 ] = sb3.z;
					skinVertexBArray[ offset_skin + 11 ] = 1;

					skinVertexBArray[ offset_skin + 12 ]  = sb4.x;
					skinVertexBArray[ offset_skin + 13 ]  = sb4.y;
					skinVertexBArray[ offset_skin + 14 ] = sb4.z;
					skinVertexBArray[ offset_skin + 15 ] = 1;

997 998
					offset_skin += 16;

A
alteredq 已提交
999
				}
1000

1001 1002 1003
				if ( dirtyColors && vertexColorType ) {

					if ( vertexColors.length == 4 && vertexColorType == THREE.VertexColors ) {
1004

1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];
						c4 = vertexColors[ 3 ];

					} else {
						
						c1 = faceColor;
						c2 = faceColor;
						c3 = faceColor;
						c4 = faceColor;

					}
1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029

					colorArray[ offset_color ]     = c1.r;
					colorArray[ offset_color + 1 ] = c1.g;
					colorArray[ offset_color + 2 ] = c1.b;

					colorArray[ offset_color + 3 ] = c2.r;
					colorArray[ offset_color + 4 ] = c2.g;
					colorArray[ offset_color + 5 ] = c2.b;

					colorArray[ offset_color + 6 ] = c3.r;
					colorArray[ offset_color + 7 ] = c3.g;
					colorArray[ offset_color + 8 ] = c3.b;
1030

1031 1032 1033
					colorArray[ offset_color + 9 ]  = c4.r;
					colorArray[ offset_color + 10 ] = c4.g;
					colorArray[ offset_color + 11 ] = c4.b;
1034

1035 1036
					offset_color += 12;

1037 1038
				}

1039
				if ( dirtyTangents && geometry.hasTangents ) {
1040

1041 1042 1043 1044
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
					t4 = vertexTangents[ 3 ];
1045

1046 1047 1048 1049
					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 已提交
1050

1051 1052 1053 1054
					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 已提交
1055

1056 1057 1058 1059
					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 已提交
1060

1061 1062 1063 1064
					tangentArray[ offset_tangent + 12 ] = t4.x;
					tangentArray[ offset_tangent + 13 ] = t4.y;
					tangentArray[ offset_tangent + 14 ] = t4.z;
					tangentArray[ offset_tangent + 15 ] = t4.w;
M
Mr.doob 已提交
1065

1066
					offset_tangent += 16;
M
Mr.doob 已提交
1067

1068
				}
M
Mr.doob 已提交
1069

A
alteredq 已提交
1070
				if( dirtyNormals && normalType ) {
M
Mr.doob 已提交
1071

1072
					if ( vertexNormals.length == 4 && needsSmoothNormals ) {
1073

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

1076
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
1077

1078 1079 1080
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
1081

1082
							offset_normal += 3;
M
Mr.doob 已提交
1083

1084
						}
M
Mr.doob 已提交
1085

1086
					} else {
1087

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

1090 1091 1092
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1093

1094
							offset_normal += 3;
M
Mr.doob 已提交
1095

1096
						}
M
Mr.doob 已提交
1097 1098

					}
M
Mr.doob 已提交
1099

1100 1101
				}

A
alteredq 已提交
1102
				if ( dirtyUvs && uv !== undefined && uvType ) {
1103

M
Mr.doob 已提交
1104 1105
					for ( i = 0; i < 4; i ++ ) {

1106
						uvi = uv[ i ];
M
Mr.doob 已提交
1107

1108 1109
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1110

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

M
Mr.doob 已提交
1113
					}
1114 1115

				}
1116

A
alteredq 已提交
1117
				if ( dirtyUvs && uv2 !== undefined && uvType ) {
1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130

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

						uv2i = uv2[ i ];

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

						offset_uv2 += 2;

					}

				}
M
Mr.doob 已提交
1131

1132
				if ( dirtyElements ) {
M
Mr.doob 已提交
1133

1134
					faceArray[ offset_face ]     = vertexIndex;
1135 1136
				   faceArray[ offset_face + 1 ] = vertexIndex + 1;
				   faceArray[ offset_face + 2 ] = vertexIndex + 3;
M
Mr.doob 已提交
1137

1138 1139 1140
				   faceArray[ offset_face + 3 ] = vertexIndex + 1;
				   faceArray[ offset_face + 4 ] = vertexIndex + 2;
				   faceArray[ offset_face + 5 ] = vertexIndex + 3;
M
Mr.doob 已提交
1141

1142
					offset_face += 6;
M
Mr.doob 已提交
1143

1144 1145
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
1146

1147
					lineArray[ offset_line + 2 ] = vertexIndex;
1148
					lineArray[ offset_line + 3 ] = vertexIndex + 3;
M
Mr.doob 已提交
1149

1150 1151
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
1152

1153 1154
					lineArray[ offset_line + 6 ] = vertexIndex + 2;
					lineArray[ offset_line + 7 ] = vertexIndex + 3;
M
Mr.doob 已提交
1155

1156
					offset_line += 8;
M
Mr.doob 已提交
1157

1158
					vertexIndex += 4;
M
Mr.doob 已提交
1159

1160
				}
M
Mr.doob 已提交
1161

1162
			}
M
Mr.doob 已提交
1163

1164 1165
		}

1166
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1167

1168
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
1169
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1170

1171
		}
M
Mr.doob 已提交
1172

1173
		if ( dirtyMorphTargets ) {
1174
			
1175
			for( vk = 0, vkl = morphTargets.length; vk < vkl; vk++ ) {
1176
		
1177 1178
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLMorphTargetsBuffers[ vk ] );
				_gl.bufferData( _gl.ARRAY_BUFFER, morphTargetsArrays[ vk ], hint );
1179 1180 1181 1182
				
			}
		}

1183
		if ( dirtyColors && offset_color > 0 ) {
1184

1185
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLColorBuffer );
1186 1187 1188
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}
1189

1190
		if ( dirtyNormals ) {
M
Mr.doob 已提交
1191

1192
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLNormalBuffer );
1193
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
1194

1195 1196
		}

1197
		if ( dirtyTangents && geometry.hasTangents ) {
1198

1199
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLTangentBuffer );
1200
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
M
Mr.doob 已提交
1201

1202
		}
1203

1204
		if ( dirtyUvs && offset_uv > 0 ) {
M
Mr.doob 已提交
1205

1206
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUVBuffer );
1207
			_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
M
Mr.doob 已提交
1208

1209
		}
M
Mr.doob 已提交
1210

1211 1212
		if ( dirtyUvs && offset_uv2 > 0 ) {

1213
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUV2Buffer );
1214 1215 1216 1217
			_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );

		}

1218
		if ( dirtyElements ) {
M
Mr.doob 已提交
1219

1220
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLFaceBuffer );
1221
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
1222

1223
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLLineBuffer );
1224
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
M
Mr.doob 已提交
1225

1226
		}
1227

1228
		if ( offset_skin > 0 ) {
1229

1230
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexABuffer );
A
alteredq 已提交
1231 1232
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );

1233
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexBBuffer );
A
alteredq 已提交
1234 1235
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );

1236
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinIndicesBuffer );
A
alteredq 已提交
1237 1238
			_gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );

1239
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinWeightsBuffer );
A
alteredq 已提交
1240
			_gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
1241

A
alteredq 已提交
1242
		}
1243 1244

	};
1245

1246
	function setLineBuffers ( geometry, hint ) {
M
Mr.doob 已提交
1247

1248
		var v, c, vertex, offset,
1249
			vertices = geometry.vertices,
1250
			colors = geometry.colors,
1251
			vl = vertices.length,
1252
			cl = colors.length,
M
Mr.doob 已提交
1253 1254

			vertexArray = geometry.__vertexArray,
1255
			colorArray = geometry.__colorArray,
1256 1257

			dirtyVertices = geometry.__dirtyVertices,
1258
			dirtyColors = geometry.__dirtyColors;
M
Mr.doob 已提交
1259

1260
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1261

1262
			for ( v = 0; v < vl; v++ ) {
M
Mr.doob 已提交
1263

1264
				vertex = vertices[ v ].position;
M
Mr.doob 已提交
1265

1266
				offset = v * 3;
M
Mr.doob 已提交
1267

1268 1269 1270
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
M
Mr.doob 已提交
1271

1272 1273
			}

A
alteredq 已提交
1274 1275 1276
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

1277
		}
M
Mr.doob 已提交
1278

1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297
		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 );

		}

1298
	};
M
Mr.doob 已提交
1299

1300
	function setRibbonBuffers ( geometry, hint ) {
A
alteredq 已提交
1301 1302 1303 1304 1305 1306 1307 1308 1309

		var v, c, vertex, offset,
			vertices = geometry.vertices,
			colors = geometry.colors,
			vl = vertices.length,
			cl = colors.length,

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

			dirtyVertices = geometry.__dirtyVertices,
A
alteredq 已提交
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
			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 );

		}

	};
1353

1354
	function setParticleBuffers ( geometry, hint, object ) {
1355

A
alteredq 已提交
1356
		var v, c, vertex, offset,
1357 1358 1359
			vertices = geometry.vertices,
			vl = vertices.length,

A
alteredq 已提交
1360 1361
			colors = geometry.colors,
			cl = colors.length,
1362

1363
			vertexArray = geometry.__vertexArray,
A
alteredq 已提交
1364
			colorArray = geometry.__colorArray,
1365

1366
			sortArray = geometry.__sortArray,
1367

1368 1369 1370
			dirtyVertices = geometry.__dirtyVertices,
			dirtyElements = geometry.__dirtyElements,
			dirtyColors = geometry.__dirtyColors;
1371

1372
		if ( object.sortParticles ) {
1373

1374
			_projScreenMatrix.multiplySelf( object.matrixWorld );
1375

1376 1377 1378
			for ( v = 0; v < vl; v++ ) {

				vertex = vertices[ v ].position;
1379

1380 1381
				_vector3.copy( vertex );
				_projScreenMatrix.multiplyVector3( _vector3 );
1382

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

1385
			}
1386

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

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

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

1393
				offset = v * 3;
1394

1395 1396 1397
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
1398

1399
			}
1400

A
alteredq 已提交
1401
			for ( c = 0; c < cl; c++ ) {
1402

A
alteredq 已提交
1403
				offset = c * 3;
1404

A
alteredq 已提交
1405 1406 1407 1408 1409
				color = colors[ sortArray[c][1] ];

				colorArray[ offset ]     = color.r;
				colorArray[ offset + 1 ] = color.g;
				colorArray[ offset + 2 ] = color.b;
1410

1411
			}
1412 1413


1414
		} else {
1415

1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428
			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;

				}
1429 1430

			}
1431

A
alteredq 已提交
1432
			if ( dirtyColors ) {
1433

A
alteredq 已提交
1434 1435 1436 1437 1438 1439 1440 1441 1442 1443
				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;

1444
				}
1445

A
alteredq 已提交
1446
			}
1447 1448

		}
1449

A
alteredq 已提交
1450
		if ( dirtyVertices || object.sortParticles ) {
1451

A
alteredq 已提交
1452 1453
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
1454

A
alteredq 已提交
1455
		}
1456

A
alteredq 已提交
1457
		if ( dirtyColors || object.sortParticles ) {
1458

A
alteredq 已提交
1459 1460
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLColorBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
1461

A
alteredq 已提交
1462
		}
1463

1464
	};
M
Mr.doob 已提交
1465

1466
	function setMaterialShaders ( material, shaders ) {
1467

1468 1469
		material.fragmentShader = shaders.fragmentShader;
		material.vertexShader = shaders.vertexShader;
1470
		material.uniforms = Uniforms.clone( shaders.uniforms );
1471

M
Mr.doob 已提交
1472
	};
1473

1474
	function refreshUniformsCommon ( uniforms, material ) {
M
Mr.doob 已提交
1475

1476
		// premultiply alpha
A
alteredq 已提交
1477
		uniforms.diffuse.value.setRGB( material.color.r * material.opacity, material.color.g * material.opacity, material.color.b * material.opacity );
M
Mr.doob 已提交
1478

1479
		// pure color
A
alteredq 已提交
1480
		//uniforms.color.value.setHex( material.color.hex );
M
Mr.doob 已提交
1481

A
alteredq 已提交
1482 1483
		uniforms.opacity.value = material.opacity;
		uniforms.map.texture = material.map;
1484

1485
		uniforms.lightMap.texture = material.lightMap;
1486

1487
		uniforms.envMap.texture = material.envMap;
A
alteredq 已提交
1488
		uniforms.reflectivity.value = material.reflectivity;
1489
		uniforms.refractionRatio.value = material.refractionRatio;
A
alteredq 已提交
1490
		uniforms.combine.value = material.combine;
1491
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
1492

1493
	};
1494

1495
	function refreshUniformsLine ( uniforms, material ) {
1496

A
alteredq 已提交
1497 1498
		uniforms.diffuse.value.setRGB( material.color.r * material.opacity, material.color.g * material.opacity, material.color.b * material.opacity );
		uniforms.opacity.value = material.opacity;
1499 1500

	};
M
Mr.doob 已提交
1501

1502
	function refreshUniformsParticle ( uniforms, material ) {
1503

A
alteredq 已提交
1504 1505 1506
		uniforms.psColor.value.setRGB( material.color.r * material.opacity, material.color.g * material.opacity, material.color.b * material.opacity );
		uniforms.opacity.value = material.opacity;
		uniforms.size.value = material.size;
M
Mr.doob 已提交
1507
		uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
A
alteredq 已提交
1508
		uniforms.map.texture = material.map;
1509

A
alteredq 已提交
1510
	};
1511

1512
	function refreshUniformsFog ( uniforms, fog ) {
1513

A
alteredq 已提交
1514
		uniforms.fogColor.value.setHex( fog.color.hex );
1515

A
alteredq 已提交
1516
		if ( fog instanceof THREE.Fog ) {
1517

A
alteredq 已提交
1518 1519
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
1520

A
alteredq 已提交
1521
		} else if ( fog instanceof THREE.FogExp2 ) {
1522

A
alteredq 已提交
1523
			uniforms.fogDensity.value = fog.density;
1524 1525

		}
1526

1527 1528
	};

1529
	function refreshUniformsPhong ( uniforms, material ) {
M
Mr.doob 已提交
1530

A
alteredq 已提交
1531 1532 1533 1534 1535
		//uniforms.ambient.value.setHex( material.ambient.hex );
		//uniforms.specular.value.setHex( material.specular.hex );
		uniforms.ambient.value.setRGB( material.ambient.r, material.ambient.g, material.ambient.b );
		uniforms.specular.value.setRGB( material.specular.r, material.specular.g, material.specular.b );
		uniforms.shininess.value = material.shininess;
M
Mr.doob 已提交
1536

1537
	};
M
Mr.doob 已提交
1538 1539


1540
	function refreshUniformsLights ( uniforms, lights ) {
M
Mr.doob 已提交
1541

A
alteredq 已提交
1542 1543 1544 1545 1546 1547
		uniforms.enableLighting.value = lights.directional.length + lights.point.length;
		uniforms.ambientLightColor.value = lights.ambient;
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
M
Mr.doob 已提交
1548

A
alteredq 已提交
1549
	};
M
Mr.doob 已提交
1550

1551
	this.initMaterial = function ( material, lights, fog, object ) {
M
Mr.doob 已提交
1552

M
Mikael Emtinger 已提交
1553
		var u, a, identifiers, i, parameters, maxLightCount, maxBones;
1554

A
alteredq 已提交
1555
		if ( material instanceof THREE.MeshDepthMaterial ) {
1556

A
alteredq 已提交
1557
			setMaterialShaders( material, THREE.ShaderLib[ 'depth' ] );
1558

A
alteredq 已提交
1559
		} else if ( material instanceof THREE.MeshNormalMaterial ) {
1560

A
alteredq 已提交
1561
			setMaterialShaders( material, THREE.ShaderLib[ 'normal' ] );
1562

A
alteredq 已提交
1563
		} else if ( material instanceof THREE.MeshBasicMaterial ) {
1564

A
alteredq 已提交
1565
			setMaterialShaders( material, THREE.ShaderLib[ 'basic' ] );
1566

A
alteredq 已提交
1567
		} else if ( material instanceof THREE.MeshLambertMaterial ) {
M
Mr.doob 已提交
1568

A
alteredq 已提交
1569
			setMaterialShaders( material, THREE.ShaderLib[ 'lambert' ] );
M
Mr.doob 已提交
1570

A
alteredq 已提交
1571
		} else if ( material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
1572

A
alteredq 已提交
1573
			setMaterialShaders( material, THREE.ShaderLib[ 'phong' ] );
M
Mr.doob 已提交
1574

A
alteredq 已提交
1575
		} else if ( material instanceof THREE.LineBasicMaterial ) {
M
Mr.doob 已提交
1576

A
alteredq 已提交
1577
			setMaterialShaders( material, THREE.ShaderLib[ 'basic' ] );
1578

A
alteredq 已提交
1579
		} else if ( material instanceof THREE.ParticleBasicMaterial ) {
1580

A
alteredq 已提交
1581
			setMaterialShaders( material, THREE.ShaderLib[ 'particle_basic' ] );
1582

A
alteredq 已提交
1583
		}
1584

A
alteredq 已提交
1585 1586
		// heuristics to create shader parameters according to lights in the scene
		// (not to blow over maxLights budget)
M
Mr.doob 已提交
1587

A
alteredq 已提交
1588
		maxLightCount = allocateLights( lights, 4 );
M
Mr.doob 已提交
1589

1590 1591
		maxBones = allocateBones( object );
		
1592
		parameters = { fog: fog, map: material.map, envMap: material.envMap, lightMap: material.lightMap, vertexColors: material.vertexColors,
A
alteredq 已提交
1593
					   sizeAttenuation: material.sizeAttenuation,
1594
					   skinning: material.skinning,
1595
					   morphTargets: material.morphTargets,
1596 1597
					   maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
					   maxBones: maxBones };
1598

1599
		material.program = buildProgram( material.fragmentShader, material.vertexShader, parameters );
M
Mr.doob 已提交
1600

M
Mikael Emtinger 已提交
1601 1602 1603

		// load uniforms

1604
		identifiers = [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
1605
						'cameraInverseMatrix', 'boneGlobalMatrices', 'morphTargetInfluences'
A
alteredq 已提交
1606
						];
A
alteredq 已提交
1607

M
Mikael Emtinger 已提交
1608

A
alteredq 已提交
1609
		for( u in material.uniforms ) {
1610

A
alteredq 已提交
1611 1612
			identifiers.push(u);
		}
M
Mr.doob 已提交
1613

A
alteredq 已提交
1614
		cacheUniformLocations( material.program, identifiers );
1615
		
M
Mikael Emtinger 已提交
1616 1617

		// load attributes
1618 1619 1620 1621 1622 1623 1624 1625 1626
		
		identifiers = [ "position", "normal", "uv", "uv2", "tangent", "color",
					    "skinVertexA", "skinVertexB", "skinIndex", "skinWeight" ];
		
		for( i = 0; i < this.maxMorphTargets; i++ ) {
			
			identifiers.push( "morphTarget" + i );
		}
		
M
Mikael Emtinger 已提交
1627 1628 1629 1630 1631
		for( a in material.attributes ) {
			
			identifiers.push( a );
		}
		
1632 1633
		cacheAttributeLocations( material.program, identifiers );

1634

A
alteredq 已提交
1635
		var attributes = material.program.attributes;
1636

A
alteredq 已提交
1637
		_gl.enableVertexAttribArray( attributes.position );
1638

A
alteredq 已提交
1639
		if ( attributes.color >= 0 ) 	_gl.enableVertexAttribArray( attributes.color );
1640
		if ( attributes.normal >= 0 ) 	_gl.enableVertexAttribArray( attributes.normal );
A
alteredq 已提交
1641
		if ( attributes.tangent >= 0 ) 	_gl.enableVertexAttribArray( attributes.tangent );
1642 1643 1644

		if ( material.skinning &&
			 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
A
alteredq 已提交
1645
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
1646

A
alteredq 已提交
1647 1648 1649 1650
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
1651

A
alteredq 已提交
1652
		}
1653
		
1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665
		if ( material.morphTargets ) {
			
			material.numSupportedMorphTargets = 0;
			
			if( attributes.morphTarget0 >= 0 ) { _gl.enableVertexAttribArray( attributes.morphTarget0 ); material.numSupportedMorphTargets++ }
			if( attributes.morphTarget1 >= 0 ) { _gl.enableVertexAttribArray( attributes.morphTarget1 ); material.numSupportedMorphTargets++ }
			if( attributes.morphTarget2 >= 0 ) { _gl.enableVertexAttribArray( attributes.morphTarget2 ); material.numSupportedMorphTargets++ }
			if( attributes.morphTarget3 >= 0 ) { _gl.enableVertexAttribArray( attributes.morphTarget3 ); material.numSupportedMorphTargets++ }
			if( attributes.morphTarget4 >= 0 ) { _gl.enableVertexAttribArray( attributes.morphTarget4 ); material.numSupportedMorphTargets++ }
			if( attributes.morphTarget5 >= 0 ) { _gl.enableVertexAttribArray( attributes.morphTarget5 ); material.numSupportedMorphTargets++ }
			if( attributes.morphTarget6 >= 0 ) { _gl.enableVertexAttribArray( attributes.morphTarget6 ); material.numSupportedMorphTargets++ }
			if( attributes.morphTarget7 >= 0 ) { _gl.enableVertexAttribArray( attributes.morphTarget7 ); material.numSupportedMorphTargets++ }
1666
			 	
1667 1668 1669 1670 1671 1672 1673 1674
			object.__webGLMorphTargetInfluences = new Float32Array( this.maxMorphTargets );
			
			for( var i = 0; i < this.maxMorphTargets; i++ ) {
				
				object.__webGLMorphTargetInfluences[ i ] = 0;
				
			}
			
1675
		}
M
Mr.doob 已提交
1676

1677
	};
1678

1679
	function setProgram( camera, lights, fog, material, object ) {
1680

1681
		if ( !material.program ) _this.initMaterial( material, lights, fog, object );
M
Mr.doob 已提交
1682

1683
		var program = material.program,
A
alteredq 已提交
1684 1685
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
1686

M
Mr.doob 已提交
1687
		if( program != _oldProgram ) {
M
Mr.doob 已提交
1688

M
Mr.doob 已提交
1689 1690
			_gl.useProgram( program );
			_oldProgram = program;
1691

M
Mr.doob 已提交
1692
		}
1693

1694 1695
		_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );

A
alteredq 已提交
1696
		// refresh uniforms common to several materials
1697 1698

		if ( fog && (
A
alteredq 已提交
1699 1700
			 material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
1701
			 material instanceof THREE.MeshPhongMaterial ||
A
alteredq 已提交
1702 1703 1704
			 material instanceof THREE.LineBasicMaterial ||
			 material instanceof THREE.ParticleBasicMaterial )
			) {
1705

A
alteredq 已提交
1706
			refreshUniformsFog( m_uniforms, fog );
1707 1708

		}
M
Mr.doob 已提交
1709

M
Mr.doob 已提交
1710
		if ( material instanceof THREE.MeshPhongMaterial ||
1711 1712
			 material instanceof THREE.MeshLambertMaterial ||
			 material.lights ) {
1713

A
alteredq 已提交
1714
			setupLights( program, lights );
A
alteredq 已提交
1715
			refreshUniformsLights( m_uniforms, _lights );
M
Mr.doob 已提交
1716 1717 1718

		}

1719 1720 1721
		if ( material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
			 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
1722

A
alteredq 已提交
1723
			refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
1724

A
alteredq 已提交
1725
		}
M
Mr.doob 已提交
1726

A
alteredq 已提交
1727
		// refresh single material specific uniforms
1728

1729
		if ( material instanceof THREE.LineBasicMaterial ) {
M
Mr.doob 已提交
1730

A
alteredq 已提交
1731
			refreshUniformsLine( m_uniforms, material );
1732

A
alteredq 已提交
1733
		} else if ( material instanceof THREE.ParticleBasicMaterial ) {
1734

A
alteredq 已提交
1735
			refreshUniformsParticle( m_uniforms, material );
1736

A
alteredq 已提交
1737
		} else if ( material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
1738

A
alteredq 已提交
1739
			refreshUniformsPhong( m_uniforms, material );
M
Mr.doob 已提交
1740

A
alteredq 已提交
1741
		} else if ( material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
1742

1743 1744
			m_uniforms.mNear.value = camera.near;
			m_uniforms.mFar.value = camera.far;
A
alteredq 已提交
1745
			m_uniforms.opacity.value = material.opacity;
1746

A
alteredq 已提交
1747
		} else if ( material instanceof THREE.MeshNormalMaterial ) {
1748

A
alteredq 已提交
1749
			m_uniforms.opacity.value = material.opacity;
1750
		}
1751

A
alteredq 已提交
1752
		// load common uniforms
1753

A
alteredq 已提交
1754 1755
		loadUniformsGeneric( program, m_uniforms );
		loadUniformsMatrices( p_uniforms, object );
1756

A
alteredq 已提交
1757 1758
		// load material specific uniforms
		// (shader material also gets them for the sake of genericity)
1759

A
alteredq 已提交
1760 1761
		if ( material instanceof THREE.MeshShaderMaterial ||
			 material instanceof THREE.MeshPhongMaterial ||
1762
			 material.envMap ) {
1763

A
alteredq 已提交
1764
			_gl.uniform3f( p_uniforms.cameraPosition, camera.position.x, camera.position.y, camera.position.z );
1765

1766
		}
1767

A
alteredq 已提交
1768
		if ( material instanceof THREE.MeshShaderMaterial ||
1769
			 material.envMap ||
1770
			 material.skinning ) {
1771

A
alteredq 已提交
1772
			_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
1773

A
alteredq 已提交
1774
		}
1775

A
alteredq 已提交
1776 1777
		if ( material instanceof THREE.MeshPhongMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
A
alteredq 已提交
1778
			 material instanceof THREE.MeshShaderMaterial ||
1779 1780
			 material.skinning ) {

A
alteredq 已提交
1781
			_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
1782

A
alteredq 已提交
1783
		}
1784

1785
		if ( material.skinning ) {
1786

1787
			loadUniformsSkinning( p_uniforms, object );
1788

A
alteredq 已提交
1789
		}
1790
		
A
alteredq 已提交
1791
		return program;
1792

A
alteredq 已提交
1793
	};
1794

1795
	function renderBuffer ( camera, lights, fog, material, geometryGroup, object ) {
A
alteredq 已提交
1796

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

A
alteredq 已提交
1799 1800
		var program, attributes, linewidth, primitives;

A
alteredq 已提交
1801
		program = setProgram( camera, lights, fog, material, object );
1802

1803
		attributes = program.attributes;
M
Mr.doob 已提交
1804

1805
		// vertices
M
Mr.doob 已提交
1806

1807
		if ( !material.morphTargets ) {
1808 1809 1810 1811 1812
			
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
			
		} else {
M
Mikael Emtinger 已提交
1813 1814
		
			setupMorphTargets( material, geometryGroup, object );
1815 1816 1817
			
		}

A
alteredq 已提交
1818 1819 1820 1821
		// colors

		if ( attributes.color >= 0 ) {

1822
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLColorBuffer );
1823
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
1824 1825 1826

		}

1827
		// normals
M
Mr.doob 已提交
1828

1829
		if ( attributes.normal >= 0 ) {
1830

1831
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLNormalBuffer );
1832
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
1833

1834
		}
1835

1836 1837 1838
		// tangents

		if ( attributes.tangent >= 0 ) {
1839

1840
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLTangentBuffer );
1841
			_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
1842

1843
		}
1844

1845
		// uvs
M
Mr.doob 已提交
1846

M
Mr.doob 已提交
1847 1848
		if ( attributes.uv >= 0 ) {

1849
			if ( geometryGroup.__webGLUVBuffer ) {
1850

1851
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUVBuffer );
1852
				_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
1853

1854
				_gl.enableVertexAttribArray( attributes.uv );
1855

1856
			} else {
1857

1858
				_gl.disableVertexAttribArray( attributes.uv );
M
Mr.doob 已提交
1859

1860
			}
1861 1862 1863

		}

1864 1865
		if ( attributes.uv2 >= 0 ) {

1866
			if ( geometryGroup.__webGLUV2Buffer ) {
1867

1868
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUV2Buffer );
1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880
				_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );

				_gl.enableVertexAttribArray( attributes.uv2 );

			} else {

				_gl.disableVertexAttribArray( attributes.uv2 );

			}

		}

1881
		if ( material.skinning &&
1882
			 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
A
alteredq 已提交
1883
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
1884

1885
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexABuffer );
A
alteredq 已提交
1886 1887
			_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );

1888
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexBBuffer );
A
alteredq 已提交
1889 1890
			_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );

1891
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinIndicesBuffer );
A
alteredq 已提交
1892 1893
			_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );

1894
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinWeightsBuffer );
A
alteredq 已提交
1895
			_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
1896

A
alteredq 已提交
1897
		}
1898

1899
		// render mesh
M
Mr.doob 已提交
1900

1901
		if ( object instanceof THREE.Mesh ) {
1902

1903
			// wireframe
1904

1905
			if ( material.wireframe ) {
M
Mr.doob 已提交
1906

1907
				_gl.lineWidth( material.wireframeLinewidth );
1908 1909
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webGLLineCount, _gl.UNSIGNED_SHORT, 0 );
1910

1911
			// triangles
1912

1913
			} else {
1914

1915 1916
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
1917
			}
1918

1919
		// render lines
1920

1921
		} else if ( object instanceof THREE.Line ) {
1922

1923
			primitives = ( object.type == THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
M
Mr.doob 已提交
1924

1925
			_gl.lineWidth( material.linewidth );
1926
			_gl.drawArrays( primitives, 0, geometryGroup.__webGLLineCount );
1927

1928
		// render particles
1929

1930
		} else if ( object instanceof THREE.ParticleSystem ) {
1931

1932
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webGLParticleCount );
1933

A
alteredq 已提交
1934
		// render ribbon
1935

A
alteredq 已提交
1936
		} else if ( object instanceof THREE.Ribbon ) {
1937

1938
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webGLVertexCount );
1939

1940 1941 1942 1943
		}

	};

M
Mikael Emtinger 已提交
1944

M
Mikael Emtinger 已提交
1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027
	function setupMorphTargets( material, geometryGroup, object ) {
		
		// set base
		
		var attributes = material.program.attributes;
		
		if(  object.morphTargetBase !== -1 ) {
			
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLMorphTargetsBuffers[ object.morphTargetBase ] );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
			
		} else {
			
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
			
		}
		
		
		if( object.morphTargetForcedOrder.length ) {

			// set forced order
			
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;
			
			while( m < material.numSupportedMorphTargets && m < order.length ) {
			
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLMorphTargetsBuffers[ order[ m ] ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
				
				object.__webGLMorphTargetInfluences[ m ] = influences[ order[ m ]];

				m++;
			}			
			
		} else {
			
			// find most influencing
			
			var used = [];
			var candidateInfluence = -1;
			var candidate = 0;
			var influences = object.morphTargetInfluences;
			var i, il = influences.length;
			var m = 0;
	
			if( object.morphTargetBase !== -1 ) {
				
				used[ object.morphTargetBase ] = true;
				
			}
	
			while( m < material.numSupportedMorphTargets ) {
				
				for( i = 0; i < il; i++ ) {
					
					if( !used[ i ] && influences[ i ] > candidateInfluence ) {
						
						candidate = i;
						candidateInfluence = influences[ candidate ];
					}
				}
				
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLMorphTargetsBuffers[ candidate ] );
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
				
				object.__webGLMorphTargetInfluences[ m ] = candidateInfluence;
	
				used[ candidate ] = 1;
				candidateInfluence = -1;
				m++;
			}
		}


		// load updated influences uniform
		
		_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webGLMorphTargetInfluences );
	}


2028
	function renderBufferImmediate ( object, program ) {
2029

A
alteredq 已提交
2030 2031
		if ( ! object.__webGLVertexBuffer ) object.__webGLVertexBuffer = _gl.createBuffer();
		if ( ! object.__webGLNormalBuffer ) object.__webGLNormalBuffer = _gl.createBuffer();
2032

A
alteredq 已提交
2033
		if ( object.hasPos ) {
2034

A
alteredq 已提交
2035 2036 2037 2038
		  _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 );
2039

A
alteredq 已提交
2040
		}
2041

A
alteredq 已提交
2042
		if ( object.hasNormal ) {
2043

A
alteredq 已提交
2044 2045 2046 2047
		  _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webGLNormalBuffer );
		  _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 );
2048

A
alteredq 已提交
2049
		}
2050

A
alteredq 已提交
2051
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );
2052

A
alteredq 已提交
2053
		object.count = 0;
2054

A
alteredq 已提交
2055
	};
2056

2057
	function setObjectFaces ( object ) {
2058

2059
		if ( _oldDoubleSided != object.doubleSided ) {
2060

2061
			if( object.doubleSided ) {
2062

2063
				_gl.disable( _gl.CULL_FACE );
2064

2065
			} else {
2066

A
alteredq 已提交
2067
				_gl.enable( _gl.CULL_FACE );
2068

A
alteredq 已提交
2069
			}
2070

2071
			_oldDoubleSided = object.doubleSided;
2072

2073
		}
2074

2075
		if ( _oldFlipSided != object.flipSided ) {
2076

2077 2078 2079 2080
			if( object.flipSided ) {

				_gl.frontFace( _gl.CW );

2081
			} else {
2082 2083 2084 2085

				_gl.frontFace( _gl.CCW );

			}
2086

2087
			_oldFlipSided = object.flipSided;
2088 2089

		}
2090

2091
	};
2092

2093
	function setDepthTest ( test ) {
2094

A
alteredq 已提交
2095 2096 2097
		if ( _oldDepth != test ) {

			if( test ) {
2098

A
alteredq 已提交
2099
				_gl.enable( _gl.DEPTH_TEST );
2100

A
alteredq 已提交
2101
			} else {
2102

A
alteredq 已提交
2103
				_gl.disable( _gl.DEPTH_TEST );
2104

A
alteredq 已提交
2105
			}
2106

A
alteredq 已提交
2107 2108 2109
			_oldDepth = test;

		}
2110

A
alteredq 已提交
2111
	};
2112

2113
	function computeFrustum ( m ) {
2114 2115 2116 2117 2118 2119 2120 2121 2122

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

		var i, plane;
2123

A
alteredq 已提交
2124
		for ( i = 0; i < 6; i ++ ) {
2125 2126 2127 2128 2129 2130 2131

			plane = _frustum[ i ];
			plane.divideScalar( Math.sqrt( plane.x * plane.x + plane.y * plane.y + plane.z * plane.z ) );

		}

	};
2132

2133
	function isInFrustum ( object ) {
2134

2135
		var distance, matrix = object.matrixWorld,
2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147
		radius = - object.geometry.boundingSphere.radius * Math.max( object.scale.x, Math.max( object.scale.y, object.scale.z ) );

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

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

		}

		return true;

	};
2148

2149
	function addToFixedArray ( where, what ) {
2150

2151 2152
		where.list[ where.count ] = what;
		where.count += 1;
2153

2154
	};
2155

2156
	function unrollImmediateBufferMaterials ( globject ) {
2157

2158 2159 2160 2161 2162 2163 2164
		var i, l, m, ml, material,
			object = globject.object,
			opaque = globject.opaque,
			transparent = globject.transparent;

		transparent.count = 0;
		opaque.count = 0;
2165

2166 2167 2168
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

			material = object.materials[ m ];
2169

2170 2171 2172 2173
			if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending )
				addToFixedArray( transparent, material );
			else
				addToFixedArray( opaque, material );
2174

2175
		}
2176

2177
	};
2178

2179
	function unrollBufferMaterials ( globject ) {
2180

2181 2182 2183 2184 2185 2186 2187 2188
		var i, l, m, ml, material, meshMaterial,
			object = globject.object,
			buffer = globject.buffer,
			opaque = globject.opaque,
			transparent = globject.transparent;

		transparent.count = 0;
		opaque.count = 0;
2189

2190 2191 2192 2193 2194 2195 2196 2197 2198
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

			meshMaterial = object.materials[ m ];

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

				for ( i = 0, l = buffer.materials.length; i < l; i++ ) {

					material = buffer.materials[ i ];
2199

2200
					if ( material ) {
2201

2202 2203 2204 2205
						if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending )
							addToFixedArray( transparent, material );
						else
							addToFixedArray( opaque, material );
2206

2207 2208 2209 2210 2211 2212 2213
					}

				}

			} else {

				material = meshMaterial;
2214

2215 2216
				if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending ) {

2217
					addToFixedArray( transparent, material );
2218 2219 2220

				} else {

2221 2222
					addToFixedArray( opaque, material );

2223 2224
				}

2225 2226 2227
			}

		}
2228

2229
	};
2230 2231


2232
	function painterSort ( a, b ) {
2233

2234
		return b.z - a.z;
2235 2236

	};
2237

2238
	this.render = function ( scene, camera, renderTarget, forceClear ) {
2239

A
alteredq 已提交
2240
		var i, program, opaque, transparent, material,
2241
			o, ol, oil, webglObject, object, buffer,
A
alteredq 已提交
2242
			lights = scene.lights,
N
Nicholas Kinsey 已提交
2243
			fog = scene.fog;
2244

M
Mr.doob 已提交
2245
		camera.matrixAutoUpdate && camera.updateMatrix();
2246

2247
		scene.update( undefined, false, camera );
M
Mr.doob 已提交
2248

M
Mr.doob 已提交
2249
		camera.matrixWorldInverse.flattenToArray( _viewMatrixArray );
2250
		camera.projectionMatrix.flattenToArray( _projectionMatrixArray );
M
Mr.doob 已提交
2251

M
Mr.doob 已提交
2252
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
2253
		computeFrustum( _projScreenMatrix );
2254

A
alteredq 已提交
2255
		this.initWebGLObjects( scene );
M
Mr.doob 已提交
2256

A
alteredq 已提交
2257
		setRenderTarget( renderTarget );
M
Mr.doob 已提交
2258

A
alteredq 已提交
2259
		if ( this.autoClear || forceClear ) {
M
Mr.doob 已提交
2260

2261
			this.clear();
M
Mr.doob 已提交
2262

2263 2264
		}

2265
		// set matrices
2266

2267
		ol = scene.__webglObjects.length;
2268

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

2271 2272
			webglObject = scene.__webglObjects[ o ];
			object = webglObject.object;
M
Mr.doob 已提交
2273

2274
			if ( object.visible ) {
2275 2276

				if ( ! ( object instanceof THREE.Mesh ) || isInFrustum( object ) ) {
2277

2278
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
2279

2280
					setupMatrices( object, camera );
2281

2282
					unrollBufferMaterials( webglObject );
2283

2284
					webglObject.render = true;
2285

2286
					if ( this.sortObjects ) {
2287

2288 2289 2290
						_vector3.copy( object.position );
						_projScreenMatrix.multiplyVector3( _vector3 );

2291
						webglObject.z = _vector3.z;
2292

2293
					}
2294

2295
				} else {
2296

2297
					webglObject.render = false;
2298

2299
				}
2300

2301
			} else {
2302

2303
				webglObject.render = false;
2304

2305
			}
2306

2307
		}
2308

2309
		if ( this.sortObjects ) {
2310

2311
			scene.__webglObjects.sort( painterSort );
2312

2313
		}
2314

2315
		oil = scene.__webglObjectsImmediate.length;
2316

2317
		for ( o = 0; o < oil; o++ ) {
2318

2319 2320
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2321

2322
			if ( object.visible ) {
2323 2324 2325

				if( object.matrixAutoUpdate ) {

2326
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
2327

A
alteredq 已提交
2328
				}
2329

2330
				setupMatrices( object, camera );
2331

2332
				unrollImmediateBufferMaterials( webglObject );
2333

2334
			}
2335

2336
		}
A
alteredq 已提交
2337

2338 2339
		// opaque pass

2340
		setBlending( THREE.NormalBlending );
2341

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

2344
			webglObject = scene.__webglObjects[ o ];
2345

2346
			if ( webglObject.render ) {
2347

2348 2349 2350
				object = webglObject.object;
				buffer = webglObject.buffer;
				opaque = webglObject.opaque;
2351

2352
				setObjectFaces( object );
2353

2354
				for( i = 0; i < opaque.count; i++ ) {
2355

2356
					material = opaque.list[ i ];
2357

2358
					setDepthTest( material.depthTest );
A
alteredq 已提交
2359
					renderBuffer( camera, lights, fog, material, buffer, object );
2360

2361
				}
2362 2363 2364 2365 2366

			}

		}

A
alteredq 已提交
2367
		// opaque pass (immediate simulator)
2368

2369
		for ( o = 0; o < oil; o++ ) {
2370

2371 2372
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2373

A
alteredq 已提交
2374
			if ( object.visible ) {
2375

2376
				opaque = webglObject.opaque;
2377

2378
				setObjectFaces( object );
2379

2380
				for( i = 0; i < opaque.count; i++ ) {
2381

2382
					material = opaque.list[ i ];
2383

2384
					setDepthTest( material.depthTest );
2385

A
alteredq 已提交
2386
					program = setProgram( camera, lights, fog, material, object );
2387
					object.render( function( object ) { renderBufferImmediate( object, program ); } );
2388

2389
				}
2390

A
alteredq 已提交
2391
			}
2392

A
alteredq 已提交
2393 2394
		}

2395 2396
		// transparent pass

2397
		for ( o = 0; o < ol; o++ ) {
2398

2399
			webglObject = scene.__webglObjects[ o ];
2400

2401
			if ( webglObject.render ) {
2402

2403 2404 2405
				object = webglObject.object;
				buffer = webglObject.buffer;
				transparent = webglObject.transparent;
2406

2407
				setObjectFaces( object );
2408

2409
				for( i = 0; i < transparent.count; i++ ) {
2410

2411
					material = transparent.list[ i ];
2412

2413
					setBlending( material.blending );
2414
					setDepthTest( material.depthTest );
2415

A
alteredq 已提交
2416
					renderBuffer( camera, lights, fog, material, buffer, object );
2417

2418
				}
2419

2420
			}
M
Mr.doob 已提交
2421

M
Mr.doob 已提交
2422
		}
M
Mr.doob 已提交
2423

2424
		// transparent pass (immediate simulator)
2425

2426
		for ( o = 0; o < oil; o++ ) {
2427

2428 2429
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2430

2431
			if ( object.visible ) {
2432

2433
				transparent = webglObject.transparent;
2434

2435
				setObjectFaces( object );
2436

2437
				for( i = 0; i < transparent.count; i++ ) {
2438

2439
					material = transparent.list[ i ];
2440

2441
					setBlending( material.blending );
2442
					setDepthTest( material.depthTest );
2443

A
alteredq 已提交
2444
					program = setProgram( camera, lights, fog, material, object );
2445
					object.render( function( object ) { renderBufferImmediate( object, program ); } );
2446

2447
				}
2448

2449
			}
2450

2451
		}
2452

2453
		// Generate mipmap if we're using any kind of mipmap filtering
M
Mr.doob 已提交
2454

2455
		if ( renderTarget && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {
M
Mr.doob 已提交
2456

2457
			updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
2458

2459
		}
2460

M
Mr.doob 已提交
2461
	};
M
Mr.doob 已提交
2462

2463
	function setupMatrices ( object, camera ) {
2464

2465 2466
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
		THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
2467

2468
	};
2469

A
alteredq 已提交
2470
	this.initWebGLObjects = function ( scene ) {
2471

2472
		if ( !scene.__webglObjects ) {
2473

2474 2475
			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
2476 2477 2478

		}

M
Mr.doob 已提交
2479
		while ( scene.__objectsAdded.length ) {
2480

M
Mr.doob 已提交
2481 2482
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
2483 2484 2485

		}

M
Mr.doob 已提交
2486
		while ( scene.__objectsRemoved.length ) {
2487

M
Mr.doob 已提交
2488 2489
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
2490 2491

		}
2492

A
alteredq 已提交
2493
		// update must be called after objects adding / removal
M
Mr.doob 已提交
2494

A
alteredq 已提交
2495 2496
		for ( var o = 0, ol = scene.__webglObjects.length; o < ol; o ++ ) {

M
Mr.doob 已提交
2497
			updateObject( scene.__webglObjects[ o ].object, scene );
A
alteredq 已提交
2498 2499 2500

		}

2501
	};
2502

2503
	function addObject ( object, scene ) {
2504

2505
		var g, geometry, geometryGroup;
M
Mr.doob 已提交
2506

2507
		if ( object._modelViewMatrix == undefined ) {
2508

2509
			object._modelViewMatrix = new THREE.Matrix4();
2510

2511 2512 2513
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
2514

2515
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
2516

2517
		}
A
alteredq 已提交
2518

2519
		if ( object instanceof THREE.Mesh ) {
A
alteredq 已提交
2520

2521 2522 2523 2524 2525 2526 2527 2528
			geometry = object.geometry;

			if ( geometry.geometryGroups == undefined ) {

				sortFacesByMaterial( geometry );

			}

2529
			// create separate VBOs per geometry chunk
A
alteredq 已提交
2530

2531
			for ( g in geometry.geometryGroups ) {
A
alteredq 已提交
2532

2533
				geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
2534

2535
				// initialise VBO on the first access
M
Mr.doob 已提交
2536

2537
				if ( ! geometryGroup.__webGLVertexBuffer ) {
M
Mr.doob 已提交
2538

2539 2540
					createMeshBuffers( geometryGroup );
					initMeshBuffers( geometryGroup, object );
A
alteredq 已提交
2541

2542
					geometry.__dirtyVertices = true;
2543
					geometry.__dirtyMorphTargets = true;
2544 2545 2546 2547 2548
					geometry.__dirtyElements = true;
					geometry.__dirtyUvs = true;
					geometry.__dirtyNormals = true;
					geometry.__dirtyTangents = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
2549

2550
				}
2551

2552
				// create separate wrapper per each use of VBO
2553

M
Mr.doob 已提交
2554
				addBuffer( scene.__webglObjects, geometryGroup, object );
M
Mr.doob 已提交
2555

2556
			}
M
Mr.doob 已提交
2557

A
alteredq 已提交
2558 2559
		} else if ( object instanceof THREE.Ribbon ) {

2560 2561
			geometry = object.geometry;

A
alteredq 已提交
2562 2563 2564 2565 2566 2567 2568 2569 2570 2571
			if( ! geometry.__webGLVertexBuffer ) {

				createRibbonBuffers( geometry );
				initRibbonBuffers( geometry );

				geometry.__dirtyVertices = true;
				geometry.__dirtyColors = true;

			}

M
Mr.doob 已提交
2572
			addBuffer( scene.__webglObjects, geometry, object );
A
alteredq 已提交
2573

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

2576 2577
			geometry = object.geometry;

2578
			if( ! geometry.__webGLVertexBuffer ) {
M
Mr.doob 已提交
2579

2580 2581
				createLineBuffers( geometry );
				initLineBuffers( geometry );
M
Mr.doob 已提交
2582

2583 2584
				geometry.__dirtyVertices = true;
				geometry.__dirtyColors = true;
M
Mr.doob 已提交
2585

2586
			}
M
Mr.doob 已提交
2587

M
Mr.doob 已提交
2588
			addBuffer( scene.__webglObjects, geometry, object );
2589

A
alteredq 已提交
2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600
		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

			if ( ! geometry.__webGLVertexBuffer ) {

				createParticleBuffers( geometry );
				initParticleBuffers( geometry );

				geometry.__dirtyVertices = true;
				geometry.__dirtyColors = true;
2601

2602
			}
2603

M
Mr.doob 已提交
2604
			addBuffer( scene.__webglObjects, geometry, object );
M
Mr.doob 已提交
2605

A
alteredq 已提交
2606 2607 2608 2609 2610 2611 2612 2613 2614 2615
		} else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes ) {

			addBufferImmediate( scene.__webglObjectsImmediate, object );

		}/*else if ( object instanceof THREE.Particle ) {

		}*/

	};

2616
	function updateObject ( object, scene ) {
A
alteredq 已提交
2617

M
Mr.doob 已提交
2618
		var g, geometry, geometryGroup;
A
alteredq 已提交
2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629

		if ( object instanceof THREE.Mesh ) {

			geometry = object.geometry;

			// check all geometry groups

			for ( g in geometry.geometryGroups ) {

				geometryGroup = geometry.geometryGroups[ g ];

2630
				if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
A
alteredq 已提交
2631 2632 2633 2634 2635 2636 2637 2638 2639
					geometry.__dirtyUvs || geometry.__dirtyNormals ||
					geometry.__dirtyColors || geometry.__dirtyTangents ) {

					setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW );

				}

			}

2640
			geometry.__dirtyVertices = false;
2641
			geometry.__dirtyMorphTargets = false;
A
alteredq 已提交
2642 2643 2644 2645
			geometry.__dirtyElements = false;
			geometry.__dirtyUvs = false;
			geometry.__dirtyNormals = false;
			geometry.__dirtyTangents = false;
2646
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
2647

A
alteredq 已提交
2648
		} else if ( object instanceof THREE.Ribbon ) {
M
Mr.doob 已提交
2649

2650 2651
			geometry = object.geometry;

A
alteredq 已提交
2652
			if( geometry.__dirtyVertices || geometry.__dirtyColors ) {
M
Mr.doob 已提交
2653

A
alteredq 已提交
2654
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
2655

A
alteredq 已提交
2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667
			}

			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

		} else if ( object instanceof THREE.Line ) {

			geometry = object.geometry;

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

				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
2668

2669
			}
2670

A
alteredq 已提交
2671 2672 2673 2674 2675 2676 2677
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

2678
			if ( geometry.__dirtyVertices || geometry.__dirtyColors || object.sortParticles ) {
M
Mr.doob 已提交
2679

2680
				setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
M
Mr.doob 已提交
2681

2682
			}
M
Mr.doob 已提交
2683

2684 2685
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
2686

2687
		}/* else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes ) {
2688

A
alteredq 已提交
2689
			// it updates itself in render callback
2690 2691

		} else if ( object instanceof THREE.Particle ) {
2692 2693

		}*/
2694

2695
	};
2696

2697
	function removeObject ( object, scene ) {
M
Mr.doob 已提交
2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714

		var o, ol, zobject;

		for ( o = scene.__webglObjects.length - 1; o >= 0; o-- ) {

			zobject = scene.__webglObjects[ o ].object;

			if ( object == zobject ) {

				scene.__webglObjects.splice( o, 1 );

			}

		}

	};

2715
	function sortFacesByMaterial ( geometry ) {
2716 2717 2718 2719 2720 2721 2722

		// TODO
		// Should optimize by grouping faces with ColorFill / ColorStroke materials
		// which could then use vertex color attributes instead of each being
		// in its separate VBO

		var i, l, f, fl, face, material, materials, vertices, mhash, ghash, hash_map = {};
2723
		var numMorphTargets = geometry.morphTargets !== undefined ? geometry.morphTargets.length : 0;
2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765

		geometry.geometryGroups = {};

		function materialHash( material ) {

			var hash_array = [];

			for ( i = 0, l = material.length; i < l; i++ ) {

				if ( material[ i ] == undefined ) {

					hash_array.push( "undefined" );

				} else {

					hash_array.push( material[ i ].id );

				}

			}

			return hash_array.join( '_' );

		}

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

			face = geometry.faces[ f ];
			materials = face.materials;

			mhash = materialHash( materials );

			if ( hash_map[ mhash ] == undefined ) {

				hash_map[ mhash ] = { 'hash': mhash, 'counter': 0 };

			}

			ghash = hash_map[ mhash ].hash + '_' + hash_map[ mhash ].counter;

			if ( geometry.geometryGroups[ ghash ] == undefined ) {

2766
				geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778

			}

			vertices = face instanceof THREE.Face3 ? 3 : 4;

			if ( geometry.geometryGroups[ ghash ].vertices + vertices > 65535 ) {

				hash_map[ mhash ].counter += 1;
				ghash = hash_map[ mhash ].hash + '_' + hash_map[ mhash ].counter;

				if ( geometry.geometryGroups[ ghash ] == undefined ) {

2779
					geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791

				}

			}

			geometry.geometryGroups[ ghash ].faces.push( f );
			geometry.geometryGroups[ ghash ].vertices += vertices;

		}

	};

2792
	function addBuffer ( objlist, buffer, object ) {
2793

2794 2795 2796 2797
		objlist.push( { buffer: buffer, object: object,
				opaque: { list: [], count: 0 },
				transparent: { list: [], count: 0 }
			} );
M
Mr.doob 已提交
2798

2799
	};
2800

2801
	function addBufferImmediate ( objlist, object ) {
2802

2803 2804 2805 2806
		objlist.push( { object: object,
				opaque: { list: [], count: 0 },
				transparent: { list: [], count: 0 }
			} );
2807

2808
	};
2809

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

2812
		if ( cullFace ) {
M
Mr.doob 已提交
2813

2814
			if ( !frontFace || frontFace == "ccw" ) {
M
Mr.doob 已提交
2815

2816
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
2817

2818
			} else {
M
Mr.doob 已提交
2819

2820
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
2821

2822
			}
M
Mr.doob 已提交
2823

2824
			if( cullFace == "back" ) {
M
Mr.doob 已提交
2825

2826
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
2827

2828
			} else if( cullFace == "front" ) {
M
Mr.doob 已提交
2829

2830
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
2831

2832
			} else {
M
Mr.doob 已提交
2833

2834
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
2835

2836
			}
M
Mr.doob 已提交
2837

2838
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
2839

2840
		} else {
M
Mr.doob 已提交
2841

2842
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
2843

2844 2845 2846
		}

	};
N
Nicolas Garcia Belmonte 已提交
2847

2848
	this.supportsVertexTextures = function () {
2849

2850
		return maxVertexTextures() > 0;
2851

2852
	};
2853

2854
	function maxVertexTextures () {
2855

2856 2857 2858
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
2859

2860
	function initGL ( antialias, clearColor, clearAlpha ) {
N
Nicolas Garcia Belmonte 已提交
2861 2862 2863

		try {

2864
			if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { antialias: antialias } ) ) ) {
N
Nicolas Garcia Belmonte 已提交
2865

2866
				throw 'Error creating WebGL context.';
N
Nicolas Garcia Belmonte 已提交
2867

2868 2869 2870
			}

		} catch ( e ) {
N
Nicolas Garcia Belmonte 已提交
2871

2872
			console.error( e );
N
Nicolas Garcia Belmonte 已提交
2873 2874 2875 2876 2877 2878 2879 2880 2881

		}

		_gl.clearColor( 0, 0, 0, 1 );
		_gl.clearDepth( 1 );

		_gl.enable( _gl.DEPTH_TEST );
		_gl.depthFunc( _gl.LEQUAL );

2882 2883
		_gl.frontFace( _gl.CCW );
		_gl.cullFace( _gl.BACK );
2884
		_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
2885

N
Nicolas Garcia Belmonte 已提交
2886
		_gl.enable( _gl.BLEND );
2887
		_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
2888
		_gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
2889

A
alteredq 已提交
2890
		_cullEnabled = true;
N
Nicolas Garcia Belmonte 已提交
2891

2892
	};
M
Mr.doob 已提交
2893

2894
	function buildProgram ( fragmentShader, vertexShader, parameters ) {
2895
		
M
Mr.doob 已提交
2896
		var program = _gl.createProgram(),
M
Mr.doob 已提交
2897

M
Mr.doob 已提交
2898 2899 2900 2901
		prefix_fragment = [
			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",
M
Mr.doob 已提交
2902

2903 2904
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
2905

2906 2907
			parameters.fog ? "#define USE_FOG" : "",
			parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "",
2908

2909
			parameters.map ? "#define USE_MAP" : "",
2910 2911 2912
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
2913

2914
			"uniform mat4 viewMatrix;",
2915
			"uniform vec3 cameraPosition;",
M
Mr.doob 已提交
2916 2917
			""
		].join("\n"),
2918

M
Mr.doob 已提交
2919
		prefix_vertex = [
2920
			maxVertexTextures() > 0 ? "#define VERTEX_TEXTURES" : "",
2921

2922 2923 2924
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

2925 2926
			"#define MAX_BONES " + parameters.maxBones,

2927
			parameters.map ? "#define USE_MAP" : "",
2928 2929 2930
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
2931
			parameters.skinning ? "#define USE_SKINNING" : "",
2932
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
2933

2934

2935 2936
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
2937 2938 2939
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
2940 2941
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
2942
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
2943 2944 2945

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
2946
			"attribute vec3 position;",
2947 2948 2949 2950 2951 2952 2953 2954
			"attribute vec3 morphTarget0;",
			"attribute vec3 morphTarget1;",
			"attribute vec3 morphTarget2;",
			"attribute vec3 morphTarget3;",
			"attribute vec3 morphTarget4;",
			"attribute vec3 morphTarget5;",
			"attribute vec3 morphTarget6;",
			"attribute vec3 morphTarget7;",
M
Mr.doob 已提交
2955
			"attribute vec3 normal;",
A
alteredq 已提交
2956
			"attribute vec3 color;",
M
Mr.doob 已提交
2957
			"attribute vec2 uv;",
2958
			"attribute vec2 uv2;",
2959

A
alteredq 已提交
2960 2961 2962 2963
			"attribute vec4 skinVertexA;",
			"attribute vec4 skinVertexB;",
			"attribute vec4 skinIndex;",
			"attribute vec4 skinWeight;",
M
Mr.doob 已提交
2964 2965
			""
		].join("\n");
2966

2967 2968
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
2969

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

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

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

N
Nicolas Garcia Belmonte 已提交
2976
		}
2977

2978 2979
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
2980

M
Mr.doob 已提交
2981
		program.uniforms = {};
2982
		program.attributes = {};
M
Mr.doob 已提交
2983

M
Mr.doob 已提交
2984
		return program;
M
Mr.doob 已提交
2985

M
Mr.doob 已提交
2986
	};
M
Mr.doob 已提交
2987

2988
	function loadUniformsSkinning ( uniforms, object ) {
2989

M
Mr.doob 已提交
2990
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray );
A
alteredq 已提交
2991
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
2992

2993
	};
2994
		
2995

2996
	function loadUniformsMatrices ( uniforms, object ) {
2997

A
alteredq 已提交
2998 2999 3000 3001
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
		_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );

	};
3002

3003
	function loadUniformsGeneric ( program, uniforms ) {
M
Mr.doob 已提交
3004

3005
		var u, uniform, value, type, location, texture;
M
Mr.doob 已提交
3006

M
Mr.doob 已提交
3007
		for( u in uniforms ) {
M
Mr.doob 已提交
3008

3009 3010
			location = program.uniforms[u];
			if ( !location ) continue;
M
Mr.doob 已提交
3011

3012
			uniform = uniforms[u];
M
Mr.doob 已提交
3013

3014 3015
			type = uniform.type;
			value = uniform.value;
M
Mr.doob 已提交
3016

M
Mr.doob 已提交
3017
			if( type == "i" ) {
M
Mr.doob 已提交
3018

M
Mr.doob 已提交
3019
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
3020

M
Mr.doob 已提交
3021
			} else if( type == "f" ) {
M
Mr.doob 已提交
3022

M
Mr.doob 已提交
3023
				_gl.uniform1f( location, value );
3024

A
alteredq 已提交
3025 3026 3027
			} else if( type == "fv1" ) {

				_gl.uniform1fv( location, value );
M
Mr.doob 已提交
3028

3029 3030 3031 3032
			} else if( type == "fv" ) {

				_gl.uniform3fv( location, value );

3033 3034 3035 3036
			} else if( type == "v2" ) {

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

3037 3038 3039
			} else if( type == "v3" ) {

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

3041 3042 3043
			} else if( type == "c" ) {

				_gl.uniform3f( location, value.r, value.g, value.b );
M
Mr.doob 已提交
3044

M
Mr.doob 已提交
3045
			} else if( type == "t" ) {
M
Mr.doob 已提交
3046

M
Mr.doob 已提交
3047
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
3048

3049
				texture = uniform.texture;
M
Mr.doob 已提交
3050

3051
				if ( !texture ) continue;
M
Mr.doob 已提交
3052

3053
				if ( texture.image instanceof Array && texture.image.length == 6 ) {
M
Mr.doob 已提交
3054

3055
					setCubeTexture( texture, value );
M
Mr.doob 已提交
3056

3057
				} else {
M
Mr.doob 已提交
3058

3059
					setTexture( texture, value );
M
Mr.doob 已提交
3060

3061
				}
M
Mr.doob 已提交
3062

3063
			}
M
Mr.doob 已提交
3064

3065
		}
M
Mr.doob 已提交
3066

3067
	};
M
Mr.doob 已提交
3068

3069
	function setBlending ( blending ) {
A
alteredq 已提交
3070 3071

		if ( blending != _oldBlending ) {
3072

A
alteredq 已提交
3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095
			switch ( blending ) {

				case THREE.AdditiveBlending:

					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ONE, _gl.ONE );

					break;

				case THREE.SubtractiveBlending:

					//_gl.blendEquation( _gl.FUNC_SUBTRACT );
					_gl.blendFunc( _gl.DST_COLOR, _gl.ZERO );

					break;

				case THREE.BillboardBlending:

					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA);

					break;

3096 3097 3098 3099 3100 3101
				case THREE.ReverseSubtractiveBlending:

					_gl.blendEquation( _gl.FUNC_REVERSE_SUBTRACT );
					_gl.blendFunc( _gl.ONE, _gl.ONE );

    				break;
A
alteredq 已提交
3102 3103 3104 3105 3106 3107
				default:

					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );

					break;
3108

A
alteredq 已提交
3109
			}
3110

A
alteredq 已提交
3111
			_oldBlending = blending;
3112

A
alteredq 已提交
3113 3114 3115
		}

	};
3116

3117
	function setTextureParameters ( textureType, texture, image ) {
3118

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

3121 3122
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
3123

3124 3125
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
3126

3127
			_gl.generateMipmap( textureType );
M
Mr.doob 已提交
3128

3129
		} else {
M
Mr.doob 已提交
3130

3131 3132 3133 3134 3135
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
			
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
3136

3137
		}
M
Mr.doob 已提交
3138

3139 3140
	};
	
3141
	function setTexture ( texture, slot ) {
3142

3143
		if ( texture.needsUpdate ) {
A
alteredq 已提交
3144

3145
			if ( !texture.__wasSetOnce ) {
M
Mr.doob 已提交
3146

3147
				texture.__webGLTexture = _gl.createTexture();
A
alteredq 已提交
3148

3149 3150
				_gl.bindTexture( _gl.TEXTURE_2D, texture.__webGLTexture );
				_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
3151

A
alteredq 已提交
3152
				texture.__wasSetOnce = true;
M
Mr.doob 已提交
3153

A
alteredq 已提交
3154
			} else {
M
Mr.doob 已提交
3155

A
alteredq 已提交
3156 3157
				_gl.bindTexture( _gl.TEXTURE_2D, texture.__webGLTexture );
				_gl.texSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
3158 3159 3160

			}

3161 3162 3163
			setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			
A
alteredq 已提交
3164
			texture.needsUpdate = false;
3165 3166 3167 3168

		}

		_gl.activeTexture( _gl.TEXTURE0 + slot );
M
Mr.doob 已提交
3169
		_gl.bindTexture( _gl.TEXTURE_2D, texture.__webGLTexture );
M
Mr.doob 已提交
3170

3171
	};
M
Mr.doob 已提交
3172

3173
	function setCubeTexture ( texture, slot ) {
3174 3175 3176 3177

		if ( texture.image.length == 6 ) {

			if ( texture.needsUpdate ) {
3178 3179
				
				if ( !texture.__wasSetOnce ) {
3180 3181 3182

					texture.image.__webGLTextureCube = _gl.createTexture();

3183
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube );
3184

3185
					for ( var i = 0; i < 6; ++i ) {
3186

3187
						_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
3188

3189 3190 3191
					}
				
					texture.__wasSetOnce = true;
3192 3193 3194

				} else {

3195
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube );
3196

3197
					for ( var i = 0; i < 6; ++i ) {
3198

3199
						_gl.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
3200

3201
					}
3202 3203 3204

				}

3205
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[0] );
3206 3207 3208
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

				texture.needsUpdate = false;
3209
				
3210 3211 3212 3213 3214 3215 3216 3217 3218
			}

			_gl.activeTexture( _gl.TEXTURE0 + slot );
			_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube );

		}

	};

3219
	function setRenderTarget ( renderTexture ) {
3220 3221

		if ( renderTexture && !renderTexture.__webGLFramebuffer ) {
M
Mr.doob 已提交
3222

3223 3224 3225 3226 3227
			renderTexture.__webGLFramebuffer = _gl.createFramebuffer();
			renderTexture.__webGLRenderbuffer = _gl.createRenderbuffer();
			renderTexture.__webGLTexture = _gl.createTexture();

			// Setup renderbuffer
M
Mr.doob 已提交
3228

3229 3230 3231 3232
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTexture.__webGLRenderbuffer );
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTexture.width, renderTexture.height );

			// Setup texture
M
Mr.doob 已提交
3233

3234
			_gl.bindTexture( _gl.TEXTURE_2D, renderTexture.__webGLTexture );
3235 3236 3237 3238
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, paramThreeToGL( renderTexture.wrapS ) );
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, paramThreeToGL( renderTexture.wrapT ) );
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( renderTexture.magFilter ) );
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( renderTexture.minFilter ) );
3239
			_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTexture.format ), renderTexture.width, renderTexture.height, 0, paramThreeToGL( renderTexture.format ), paramThreeToGL( renderTexture.type ), null );
3240 3241

			// Setup framebuffer
M
Mr.doob 已提交
3242

3243 3244
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTexture.__webGLFramebuffer );
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, renderTexture.__webGLTexture, 0 );
3245
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webGLRenderbuffer );
3246 3247

			// Release everything
M
Mr.doob 已提交
3248

3249 3250 3251
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
3252

3253 3254
		}

3255
		var framebuffer, width, height;
M
Mr.doob 已提交
3256

3257
		if ( renderTexture ) {
M
Mr.doob 已提交
3258

3259 3260 3261
			framebuffer = renderTexture.__webGLFramebuffer;
			width = renderTexture.width;
			height = renderTexture.height;
M
Mr.doob 已提交
3262

3263
		} else {
M
Mr.doob 已提交
3264

3265
			framebuffer = null;
3266 3267
			width = _viewportWidth;
			height = _viewportHeight;
M
Mr.doob 已提交
3268

3269
		}
M
Mr.doob 已提交
3270

3271
		if( framebuffer != _oldFramebuffer ) {
M
Mr.doob 已提交
3272

3273
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
3274
			_gl.viewport( _viewportX, _viewportY, width, height );
M
Mr.doob 已提交
3275

3276
			_oldFramebuffer = framebuffer;
M
Mr.doob 已提交
3277

3278
		}
3279

3280
	};
M
Mr.doob 已提交
3281

3282
	function updateRenderTargetMipmap ( renderTarget ) {
M
Mr.doob 已提交
3283

3284 3285 3286
		_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webGLTexture );
		_gl.generateMipmap( _gl.TEXTURE_2D );
		_gl.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
3287 3288

	};
3289

3290
	function cacheUniformLocations ( program, identifiers ) {
M
Mr.doob 已提交
3291

M
Mr.doob 已提交
3292
		var i, l, id;
M
Mr.doob 已提交
3293

M
Mr.doob 已提交
3294
		for( i = 0, l = identifiers.length; i < l; i++ ) {
M
Mr.doob 已提交
3295

3296 3297
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
3298

M
Mr.doob 已提交
3299
		}
M
Mr.doob 已提交
3300

M
Mr.doob 已提交
3301
	};
M
Mr.doob 已提交
3302

3303
	function cacheAttributeLocations ( program, identifiers ) {
3304

3305
		var i, l, id;
M
Mr.doob 已提交
3306

3307
		for( i = 0, l = identifiers.length; i < l; i++ ) {
M
Mr.doob 已提交
3308

3309 3310
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
3311

3312
		}
M
Mr.doob 已提交
3313

M
Mr.doob 已提交
3314
	};
M
Mr.doob 已提交
3315

3316
	function getShader ( type, string ) {
N
Nicolas Garcia Belmonte 已提交
3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334

		var shader;

		if ( type == "fragment" ) {

			shader = _gl.createShader( _gl.FRAGMENT_SHADER );

		} else if ( type == "vertex" ) {

			shader = _gl.createShader( _gl.VERTEX_SHADER );

		}

		_gl.shaderSource( shader, string );
		_gl.compileShader( shader );

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

3335
			console.error( _gl.getShaderInfoLog( shader ) );
3336
			console.error( string );
N
Nicolas Garcia Belmonte 已提交
3337 3338 3339 3340 3341
			return null;

		}

		return shader;
M
Mr.doob 已提交
3342

3343
	};
N
Nicolas Garcia Belmonte 已提交
3344

3345
	// fallback filters for non-power-of-2 textures
3346

3347
	function filterFallback ( f ) {
3348

3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
			case THREE.LinearMipMapLinearFilter: return _gl.LINEAR; break;

		}
		
	};
	
3363
	function paramThreeToGL ( p ) {
M
Mr.doob 已提交
3364

3365
		switch ( p ) {
M
Mr.doob 已提交
3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378

			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;

3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392
			case THREE.ByteType: return _gl.BYTE; break;
			case THREE.UnsignedByteType: return _gl.UNSIGNED_BYTE; break;
			case THREE.ShortType: return _gl.SHORT; break;
			case THREE.UnsignedShortType: return _gl.UNSIGNED_SHORT; break;
			case THREE.IntType: return _gl.INT; break;
			case THREE.UnsignedShortType: return _gl.UNSIGNED_INT; break;
			case THREE.FloatType: return _gl.FLOAT; break;

			case THREE.AlphaFormat: return _gl.ALPHA; break;
			case THREE.RGBFormat: return _gl.RGB; break;
			case THREE.RGBAFormat: return _gl.RGBA; break;
			case THREE.LuminanceFormat: return _gl.LUMINANCE; break;
			case THREE.LuminanceAlphaFormat: return _gl.LUMINANCE_ALPHA; break;

3393
		}
M
Mr.doob 已提交
3394

3395
		return 0;
M
Mr.doob 已提交
3396

3397 3398
	};

3399
	function isPowerOfTwo ( value ) {
3400 3401 3402 3403 3404

		return ( value & ( value - 1 ) ) == 0;

	};

3405
	function materialNeedsSmoothNormals ( material ) {
3406 3407 3408

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

3409
	};
M
Mr.doob 已提交
3410

3411
	function bufferNeedsSmoothNormals ( geometryGroup, object ) {
M
Mr.doob 已提交
3412

3413
		var m, ml, i, l, meshMaterial, needsSmoothNormals = false;
M
Mr.doob 已提交
3414

M
Mr.doob 已提交
3415
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {
3416

M
Mr.doob 已提交
3417
			meshMaterial = object.materials[ m ];
3418 3419 3420

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

3421
				for ( i = 0, l = geometryGroup.materials.length; i < l; i++ ) {
3422

3423
					if ( materialNeedsSmoothNormals( geometryGroup.materials[ i ] ) ) {
3424

3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445
						needsSmoothNormals = true;
						break;

					}

				}

			} else {

				if ( materialNeedsSmoothNormals( meshMaterial ) ) {

					needsSmoothNormals = true;
					break;

				}

			}

			if ( needsSmoothNormals ) break;

		}
M
Mr.doob 已提交
3446

3447
		return needsSmoothNormals;
M
Mr.doob 已提交
3448

3449
	};
M
Mr.doob 已提交
3450

3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524
	function unrollGroupMaterials( geometryGroup, object ) {
		
		var m, ml, i, il,
			material, meshMaterial,
			materials = [];
		
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

			meshMaterial = object.materials[ m ];

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

				for ( i = 0, l = geometryGroup.materials.length; i < l; i++ ) {

					material = geometryGroup.materials[ i ];

					if ( material ) {
						
						materials.push( material );

					}

				}

			} else {

				material = meshMaterial;

				if ( material ) {

					materials.push( material );

				}

			}

		}
		
		return materials;

	};
	
	function bufferGuessVertexColorType ( materials, geometryGroup, object ) {
		
		var i, m, ml = materials.length;
			
		// use vertexColor type from the first material in unrolled materials
		
		for ( i = 0; i < ml; i++ ) {
			
			m = materials[ i ];
			
			if ( m.vertexColors ) {
				
				return m.vertexColors;

			}
			
		}
		
		return false;
		
	};

	function bufferGuessNormalType ( materials, geometryGroup, object ) {
		
		var i, m, ml = materials.length;
			
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
		
		for ( i = 0; i < ml; i++ ) {
			
			m = materials[ i ];
			
A
alteredq 已提交
3525
			if ( ( m instanceof THREE.MeshBasicMaterial && !m.envMap ) || m instanceof THREE.MeshDepthMaterial ) continue;
3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552
			
			if ( materialNeedsSmoothNormals( m ) ) {
				
				return THREE.SmoothShading;

			} else {

				return THREE.FlatShading;

			}

		}
		
		return false;
		
	};

	function bufferGuessUVType ( materials, geometryGroup, object ) {
		
		var i, m, ml = materials.length;
			
		// material must use some texture to require uvs
		
		for ( i = 0; i < ml; i++ ) {
			
			m = materials[ i ];
			
A
alteredq 已提交
3553
			if ( m.map || m.lightMap || m instanceof THREE.MeshShaderMaterial ) {
3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564
				
				return true;
				
			}
			
		}
		
		return false;
		
	};
	
3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587
	function allocateBones ( object ) {
		
		// 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)
		
		var maxBones = 50;
		
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
			
			maxBones = object.bones.length;

		}

		return maxBones;
		
	};
	
	function allocateLights ( lights, maxLights ) {
3588

3589 3590
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
3591

3592
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
3593

3594
			light = lights[ l ];
3595

3596 3597
			if ( light instanceof THREE.DirectionalLight ) dirLights++;
			if ( light instanceof THREE.PointLight ) pointLights++;
3598

3599
		}
3600

3601
		if ( ( pointLights + dirLights ) <= maxLights ) {
3602

3603 3604
			maxDirLights = dirLights;
			maxPointLights = pointLights;
3605

3606
		} else {
3607

3608 3609
			maxDirLights = Math.ceil( maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = maxLights - maxDirLights;
3610 3611 3612

		}

3613
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
3614 3615

	};
M
Mr.doob 已提交
3616

A
alteredq 已提交
3617
	/* DEBUG
3618
	function getGLParams() {
M
Mr.doob 已提交
3619

3620
		var params  = {
M
Mr.doob 已提交
3621

3622 3623
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
3624

3625 3626 3627
			'MAX_TEXTURE_IMAGE_UNITS': _gl.getParameter( _gl.MAX_TEXTURE_IMAGE_UNITS ),
			'MAX_VERTEX_TEXTURE_IMAGE_UNITS': _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ),
			'MAX_COMBINED_TEXTURE_IMAGE_UNITS' : _gl.getParameter( _gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS ),
M
Mr.doob 已提交
3628

3629 3630 3631
			'MAX_VERTEX_UNIFORM_VECTORS': _gl.getParameter( _gl.MAX_VERTEX_UNIFORM_VECTORS ),
			'MAX_FRAGMENT_UNIFORM_VECTORS': _gl.getParameter( _gl.MAX_FRAGMENT_UNIFORM_VECTORS )
		}
M
Mr.doob 已提交
3632

3633 3634
		return params;
	};
M
Mr.doob 已提交
3635

3636
	function dumpObject( obj ) {
M
Mr.doob 已提交
3637

3638 3639
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
3640

3641
			str += p + ": " + obj[p] + "\n";
M
Mr.doob 已提交
3642

3643
		}
M
Mr.doob 已提交
3644

3645 3646
		return str;
	}
A
alteredq 已提交
3647
	*/
3648
};
3649