WebGLRenderer.js 87.1 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, normalType, 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,
A
alteredq 已提交
442
			uvType, vertexColorType, normalType,
443
			uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4,
444
			c1, c2, c3, c4,
A
alteredq 已提交
445 446 447 448
			sw1, sw2, sw3, sw4,
			si1, si2, si3, si4,
			sa1, sa2, sa3, sa4,
			sb1, sb2, sb3, sb4,
449
			m, ml, i,
450
			vn, uvi, uv2i,
451
			vk, vkl, vka,
M
Mr.doob 已提交
452

453
		vertexIndex = 0,
454

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

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

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

478 479
		morphTargetsArrays = geometryGroup.__morphTargetsArrays,

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

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

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

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

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

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

		morphTargets = geometry.morphTargets;
		
515

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

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

				uv = obj_uvs[ fi ];

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

			}
M
Mr.doob 已提交
532

533
			vertexNormals = face.vertexNormals;
534
			faceNormal = face.normal;
535 536 537
			
			vertexColors = face.vertexColors;
			faceColor = face.color;
538 539 540

			if ( face instanceof THREE.Face3 ) {

541
				if ( dirtyVertices ) {
M
Mr.doob 已提交
542

543 544 545
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
M
Mr.doob 已提交
546

547 548 549
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
550

551 552 553
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
554

555 556 557
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
M
Mr.doob 已提交
558

559
					offset += 9;
M
Mr.doob 已提交
560

561
				}
562

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

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

586
					offset_morphTarget += 9;
587 588 589
					
				}

A
alteredq 已提交
590 591 592
				if ( obj_skinWeights.length ) {

					// weights
593

A
alteredq 已提交
594 595 596
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
597

A
alteredq 已提交
598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613
					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
614

A
alteredq 已提交
615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634
					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
635

A
alteredq 已提交
636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655
					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
656

A
alteredq 已提交
657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676
					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;
677

A
alteredq 已提交
678
				}
679

680 681 682
				if ( dirtyColors && vertexColorType ) {

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

684 685 686 687 688 689 690 691 692 693 694
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];

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

					}
695 696 697 698 699 700 701 702 703 704 705 706

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

708 709 710 711
					offset_color += 9;

				}

712
				if ( dirtyTangents && geometry.hasTangents ) {
713

714 715 716
					t1 = vertices[ face.a ].tangent;
					t2 = vertices[ face.b ].tangent;
					t3 = vertices[ face.c ].tangent;
717

718 719 720 721
					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 已提交
722

723 724 725 726
					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 已提交
727

728 729 730 731
					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 已提交
732

733
					offset_tangent += 12;
M
Mr.doob 已提交
734

735 736
				}

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

739 740 741
					if ( vertexNormals.length == 3 && needsSmoothNormals ) {

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

743
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
744

745 746 747
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
748

749
							offset_normal += 3;
M
Mr.doob 已提交
750

751
						}
M
Mr.doob 已提交
752

753
					} else {
754

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

757 758 759
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
760

761
							offset_normal += 3;
M
Mr.doob 已提交
762

763
						}
M
Mr.doob 已提交
764 765

					}
M
Mr.doob 已提交
766

767 768
				}

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

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

773
						uvi = uv[ i ];
M
Mr.doob 已提交
774

775 776
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
777

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

M
Mr.doob 已提交
780
					}
781 782 783

				}

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

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

						uv2i = uv2[ i ];

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

						offset_uv2 += 2;

					}

				}

799
				if( dirtyElements ) {
M
Mr.doob 已提交
800

801 802 803
					faceArray[ offset_face ] = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
M
Mr.doob 已提交
804

805
					offset_face += 3;
M
Mr.doob 已提交
806

807 808
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
809

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

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

816
					offset_line += 6;
817

818
					vertexIndex += 3;
M
Mr.doob 已提交
819

820
				}
M
Mr.doob 已提交
821

822 823 824

			} else if ( face instanceof THREE.Face4 ) {

825
				if ( dirtyVertices ) {
M
Mr.doob 已提交
826

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

832 833 834
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
835

836 837 838
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
839

840 841 842
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
843

844 845 846
					vertexArray[ offset + 9 ] = v4.x;
					vertexArray[ offset + 10 ] = v4.y;
					vertexArray[ offset + 11 ] = v4.z;
M
Mr.doob 已提交
847

848
					offset += 12;
M
Mr.doob 已提交
849

850
				}
851

852
				if ( dirtyMorphTargets ) {
853
					
854
					for( vk = 0, vkl = morphTargets.length; vk < vkl; vk++ ) {
855
						
856 857 858 859
						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;
860
	
861
						vka = morphTargetsArrays[ vk ];
862
	
863 864 865
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
866
	
867 868 869
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
870
	
871 872 873
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
874
	
875 876 877
						vka[ offset_morphTarget + 9 ] = v4.x;
						vka[ offset_morphTarget + 10 ] = v4.y;
						vka[ offset_morphTarget + 11 ] = v4.z;
878 879
					}

880
					offset_morphTarget += 12;
881 882 883
					
				}

A
alteredq 已提交
884 885 886
				if ( obj_skinWeights.length ) {

					// weights
887

A
alteredq 已提交
888 889 890 891
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
					sw4 = obj_skinWeights[ face.d ];
892

A
alteredq 已提交
893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913
					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
914

A
alteredq 已提交
915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940
					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
941

A
alteredq 已提交
942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967
					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
968

A
alteredq 已提交
969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993
					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;

994 995
					offset_skin += 16;

A
alteredq 已提交
996
				}
997

998 999 1000
				if ( dirtyColors && vertexColorType ) {

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

1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];
						c4 = vertexColors[ 3 ];

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

					}
1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026

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

1028 1029 1030
					colorArray[ offset_color + 9 ]  = c4.r;
					colorArray[ offset_color + 10 ] = c4.g;
					colorArray[ offset_color + 11 ] = c4.b;
1031

1032 1033
					offset_color += 12;

1034 1035
				}

1036
				if ( dirtyTangents && geometry.hasTangents ) {
1037

1038 1039 1040 1041
					t1 = vertices[ face.a ].tangent;
					t2 = vertices[ face.b ].tangent;
					t3 = vertices[ face.c ].tangent;
					t4 = vertices[ face.d ].tangent;
1042

1043 1044 1045 1046
					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 已提交
1047

1048 1049 1050 1051
					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 已提交
1052

1053 1054 1055 1056
					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 已提交
1057

1058 1059 1060 1061
					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 已提交
1062

1063
					offset_tangent += 16;
M
Mr.doob 已提交
1064

1065
				}
M
Mr.doob 已提交
1066

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

1069
					if ( vertexNormals.length == 4 && needsSmoothNormals ) {
1070

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

1073
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
1074

1075 1076 1077
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
1078

1079
							offset_normal += 3;
M
Mr.doob 已提交
1080

1081
						}
M
Mr.doob 已提交
1082

1083
					} else {
1084

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

1087 1088 1089
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1090

1091
							offset_normal += 3;
M
Mr.doob 已提交
1092

1093
						}
M
Mr.doob 已提交
1094 1095

					}
M
Mr.doob 已提交
1096

1097 1098
				}

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

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

1103
						uvi = uv[ i ];
M
Mr.doob 已提交
1104

1105 1106
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1107

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

M
Mr.doob 已提交
1110
					}
1111 1112

				}
1113

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

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

1129
				if ( dirtyElements ) {
M
Mr.doob 已提交
1130

1131 1132 1133
					faceArray[ offset_face ]     = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
M
Mr.doob 已提交
1134

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

1139
					offset_face += 6;
M
Mr.doob 已提交
1140

1141 1142
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
1143

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

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

1150 1151
					lineArray[ offset_line + 6 ] = vertexIndex + 2;
					lineArray[ offset_line + 7 ] = vertexIndex + 3;
M
Mr.doob 已提交
1152

1153
					offset_line += 8;
M
Mr.doob 已提交
1154

1155
					vertexIndex += 4;
M
Mr.doob 已提交
1156

1157
				}
M
Mr.doob 已提交
1158

1159
			}
M
Mr.doob 已提交
1160

1161 1162
		}

1163
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1164

1165
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
1166
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1167

1168
		}
M
Mr.doob 已提交
1169

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

1180
		if ( dirtyColors && offset_color > 0 ) {
1181

1182
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLColorBuffer );
1183 1184 1185
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}
1186

1187
		if ( dirtyNormals ) {
M
Mr.doob 已提交
1188

1189
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLNormalBuffer );
1190
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
1191

1192 1193
		}

1194
		if ( dirtyTangents && geometry.hasTangents ) {
1195

1196
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLTangentBuffer );
1197
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
M
Mr.doob 已提交
1198

1199
		}
1200

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

1203
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUVBuffer );
1204
			_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
M
Mr.doob 已提交
1205

1206
		}
M
Mr.doob 已提交
1207

1208 1209
		if ( dirtyUvs && offset_uv2 > 0 ) {

1210
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUV2Buffer );
1211 1212 1213 1214
			_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );

		}

1215
		if ( dirtyElements ) {
M
Mr.doob 已提交
1216

1217
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLFaceBuffer );
1218
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
1219

1220
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLLineBuffer );
1221
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
M
Mr.doob 已提交
1222

1223
		}
1224

1225
		if ( offset_skin > 0 ) {
1226

1227
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexABuffer );
A
alteredq 已提交
1228 1229
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );

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

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

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

A
alteredq 已提交
1239
		}
1240 1241

	};
1242

1243
	function setLineBuffers ( geometry, hint ) {
M
Mr.doob 已提交
1244

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

			vertexArray = geometry.__vertexArray,
1252
			colorArray = geometry.__colorArray,
1253 1254

			dirtyVertices = geometry.__dirtyVertices,
1255
			dirtyColors = geometry.__dirtyColors;
M
Mr.doob 已提交
1256

1257
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1258

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

1261
				vertex = vertices[ v ].position;
M
Mr.doob 已提交
1262

1263
				offset = v * 3;
M
Mr.doob 已提交
1264

1265 1266 1267
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
M
Mr.doob 已提交
1268

1269 1270
			}

A
alteredq 已提交
1271 1272 1273
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

1274
		}
M
Mr.doob 已提交
1275

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

		}

1295
	};
M
Mr.doob 已提交
1296

1297
	function setRibbonBuffers ( geometry, hint ) {
A
alteredq 已提交
1298 1299 1300 1301 1302 1303 1304 1305 1306

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

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

			dirtyVertices = geometry.__dirtyVertices,
A
alteredq 已提交
1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349
			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 );

		}

	};
1350

1351
	function setParticleBuffers ( geometry, hint, object ) {
1352

A
alteredq 已提交
1353
		var v, c, vertex, offset,
1354 1355 1356
			vertices = geometry.vertices,
			vl = vertices.length,

A
alteredq 已提交
1357 1358
			colors = geometry.colors,
			cl = colors.length,
1359

1360
			vertexArray = geometry.__vertexArray,
A
alteredq 已提交
1361
			colorArray = geometry.__colorArray,
1362

1363
			sortArray = geometry.__sortArray,
1364

1365 1366 1367
			dirtyVertices = geometry.__dirtyVertices,
			dirtyElements = geometry.__dirtyElements,
			dirtyColors = geometry.__dirtyColors;
1368

1369
		if ( object.sortParticles ) {
1370

1371
			_projScreenMatrix.multiplySelf( object.matrixWorld );
1372

1373 1374 1375
			for ( v = 0; v < vl; v++ ) {

				vertex = vertices[ v ].position;
1376

1377 1378
				_vector3.copy( vertex );
				_projScreenMatrix.multiplyVector3( _vector3 );
1379

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

1382
			}
1383

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

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

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

1390
				offset = v * 3;
1391

1392 1393 1394
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
1395

1396
			}
1397

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

A
alteredq 已提交
1400
				offset = c * 3;
1401

A
alteredq 已提交
1402 1403 1404 1405 1406
				color = colors[ sortArray[c][1] ];

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

1408
			}
1409 1410


1411
		} else {
1412

1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425
			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;

				}
1426 1427

			}
1428

A
alteredq 已提交
1429
			if ( dirtyColors ) {
1430

A
alteredq 已提交
1431 1432 1433 1434 1435 1436 1437 1438 1439 1440
				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;

1441
				}
1442

A
alteredq 已提交
1443
			}
1444 1445

		}
1446

A
alteredq 已提交
1447
		if ( dirtyVertices || object.sortParticles ) {
1448

A
alteredq 已提交
1449 1450
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
1451

A
alteredq 已提交
1452
		}
1453

A
alteredq 已提交
1454
		if ( dirtyColors || object.sortParticles ) {
1455

A
alteredq 已提交
1456 1457
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLColorBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
1458

A
alteredq 已提交
1459
		}
1460

1461
	};
M
Mr.doob 已提交
1462

1463
	function setMaterialShaders ( material, shaders ) {
1464

1465 1466
		material.fragmentShader = shaders.fragmentShader;
		material.vertexShader = shaders.vertexShader;
1467
		material.uniforms = Uniforms.clone( shaders.uniforms );
1468

M
Mr.doob 已提交
1469
	};
1470

1471
	function refreshUniformsCommon ( uniforms, material ) {
M
Mr.doob 已提交
1472

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

1476
		// pure color
A
alteredq 已提交
1477
		//uniforms.color.value.setHex( material.color.hex );
M
Mr.doob 已提交
1478

A
alteredq 已提交
1479 1480
		uniforms.opacity.value = material.opacity;
		uniforms.map.texture = material.map;
1481

1482
		uniforms.lightMap.texture = material.lightMap;
1483

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

1490
	};
1491

1492
	function refreshUniformsLine ( uniforms, material ) {
1493

A
alteredq 已提交
1494 1495
		uniforms.diffuse.value.setRGB( material.color.r * material.opacity, material.color.g * material.opacity, material.color.b * material.opacity );
		uniforms.opacity.value = material.opacity;
1496 1497

	};
M
Mr.doob 已提交
1498

1499
	function refreshUniformsParticle ( uniforms, material ) {
1500

A
alteredq 已提交
1501 1502 1503
		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 已提交
1504
		uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
A
alteredq 已提交
1505
		uniforms.map.texture = material.map;
1506

A
alteredq 已提交
1507
	};
1508

1509
	function refreshUniformsFog ( uniforms, fog ) {
1510

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

A
alteredq 已提交
1513
		if ( fog instanceof THREE.Fog ) {
1514

A
alteredq 已提交
1515 1516
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
1517

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

A
alteredq 已提交
1520
			uniforms.fogDensity.value = fog.density;
1521 1522

		}
1523

1524 1525
	};

1526
	function refreshUniformsPhong ( uniforms, material ) {
M
Mr.doob 已提交
1527

A
alteredq 已提交
1528 1529 1530 1531 1532
		//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 已提交
1533

1534
	};
M
Mr.doob 已提交
1535 1536


1537
	function refreshUniformsLights ( uniforms, lights ) {
M
Mr.doob 已提交
1538

A
alteredq 已提交
1539 1540 1541 1542 1543 1544
		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 已提交
1545

A
alteredq 已提交
1546
	};
M
Mr.doob 已提交
1547

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

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

A
alteredq 已提交
1552
		if ( material instanceof THREE.MeshDepthMaterial ) {
1553

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

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

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

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

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

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

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

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

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

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

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

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

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

A
alteredq 已提交
1580
		}
1581

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

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

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

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

M
Mikael Emtinger 已提交
1598 1599 1600

		// load uniforms

1601
		identifiers = [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
1602
						'cameraInverseMatrix', 'boneGlobalMatrices', 'morphTargetInfluences'
A
alteredq 已提交
1603
						];
A
alteredq 已提交
1604

M
Mikael Emtinger 已提交
1605

A
alteredq 已提交
1606
		for( u in material.uniforms ) {
1607

A
alteredq 已提交
1608 1609
			identifiers.push(u);
		}
M
Mr.doob 已提交
1610

A
alteredq 已提交
1611
		cacheUniformLocations( material.program, identifiers );
1612
		
M
Mikael Emtinger 已提交
1613 1614

		// load attributes
1615 1616 1617 1618 1619 1620 1621 1622 1623
		
		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 已提交
1624 1625 1626 1627 1628
		for( a in material.attributes ) {
			
			identifiers.push( a );
		}
		
1629 1630
		cacheAttributeLocations( material.program, identifiers );

1631

A
alteredq 已提交
1632
		var attributes = material.program.attributes;
1633

A
alteredq 已提交
1634
		_gl.enableVertexAttribArray( attributes.position );
1635

A
alteredq 已提交
1636
		if ( attributes.color >= 0 ) 	_gl.enableVertexAttribArray( attributes.color );
1637
		if ( attributes.normal >= 0 ) 	_gl.enableVertexAttribArray( attributes.normal );
A
alteredq 已提交
1638
		if ( attributes.tangent >= 0 ) 	_gl.enableVertexAttribArray( attributes.tangent );
1639 1640 1641

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

A
alteredq 已提交
1644 1645 1646 1647
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
1648

A
alteredq 已提交
1649
		}
1650
		
1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662
		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++ }
1663
			 	
1664 1665 1666 1667 1668 1669 1670 1671
			object.__webGLMorphTargetInfluences = new Float32Array( this.maxMorphTargets );
			
			for( var i = 0; i < this.maxMorphTargets; i++ ) {
				
				object.__webGLMorphTargetInfluences[ i ] = 0;
				
			}
			
1672
		}
M
Mr.doob 已提交
1673

1674
	};
1675

1676
	function setProgram( camera, lights, fog, material, object ) {
1677

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

1680
		var program = material.program,
A
alteredq 已提交
1681 1682
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
1683

M
Mr.doob 已提交
1684
		if( program != _oldProgram ) {
M
Mr.doob 已提交
1685

M
Mr.doob 已提交
1686 1687
			_gl.useProgram( program );
			_oldProgram = program;
1688

M
Mr.doob 已提交
1689
		}
1690

1691 1692
		_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );

A
alteredq 已提交
1693
		// refresh uniforms common to several materials
1694 1695

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

A
alteredq 已提交
1703
			refreshUniformsFog( m_uniforms, fog );
1704 1705

		}
M
Mr.doob 已提交
1706

M
Mr.doob 已提交
1707
		if ( material instanceof THREE.MeshPhongMaterial ||
1708 1709
			 material instanceof THREE.MeshLambertMaterial ||
			 material.lights ) {
1710

A
alteredq 已提交
1711
			setupLights( program, lights );
A
alteredq 已提交
1712
			refreshUniformsLights( m_uniforms, _lights );
M
Mr.doob 已提交
1713 1714 1715

		}

1716 1717 1718
		if ( material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
			 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
1719

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

A
alteredq 已提交
1722
		}
M
Mr.doob 已提交
1723

A
alteredq 已提交
1724
		// refresh single material specific uniforms
1725

1726
		if ( material instanceof THREE.LineBasicMaterial ) {
M
Mr.doob 已提交
1727

A
alteredq 已提交
1728
			refreshUniformsLine( m_uniforms, material );
1729

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

A
alteredq 已提交
1732
			refreshUniformsParticle( m_uniforms, material );
1733

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

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

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

1740 1741
			m_uniforms.mNear.value = camera.near;
			m_uniforms.mFar.value = camera.far;
A
alteredq 已提交
1742
			m_uniforms.opacity.value = material.opacity;
1743

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

A
alteredq 已提交
1746
			m_uniforms.opacity.value = material.opacity;
1747
		}
1748

A
alteredq 已提交
1749
		// load common uniforms
1750

A
alteredq 已提交
1751 1752
		loadUniformsGeneric( program, m_uniforms );
		loadUniformsMatrices( p_uniforms, object );
1753

A
alteredq 已提交
1754 1755
		// load material specific uniforms
		// (shader material also gets them for the sake of genericity)
1756

A
alteredq 已提交
1757 1758
		if ( material instanceof THREE.MeshShaderMaterial ||
			 material instanceof THREE.MeshPhongMaterial ||
1759
			 material.envMap ) {
1760

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

1763
		}
1764

A
alteredq 已提交
1765
		if ( material instanceof THREE.MeshShaderMaterial ||
1766
			 material.envMap ||
1767
			 material.skinning ) {
1768

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

A
alteredq 已提交
1771
		}
1772

A
alteredq 已提交
1773 1774
		if ( material instanceof THREE.MeshPhongMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
A
alteredq 已提交
1775
			 material instanceof THREE.MeshShaderMaterial ||
1776 1777
			 material.skinning ) {

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

A
alteredq 已提交
1780
		}
1781

1782
		if ( material.skinning ) {
1783

1784
			loadUniformsSkinning( p_uniforms, object );
1785

A
alteredq 已提交
1786
		}
1787
		
A
alteredq 已提交
1788
		return program;
1789

A
alteredq 已提交
1790
	};
1791

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

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

A
alteredq 已提交
1796 1797
		var program, attributes, linewidth, primitives;

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

1800
		attributes = program.attributes;
M
Mr.doob 已提交
1801

1802
		// vertices
M
Mr.doob 已提交
1803

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

A
alteredq 已提交
1815 1816 1817 1818
		// colors

		if ( attributes.color >= 0 ) {

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

		}

1824
		// normals
M
Mr.doob 已提交
1825

1826
		if ( attributes.normal >= 0 ) {
1827

1828
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLNormalBuffer );
1829
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
1830

1831
		}
1832

1833 1834 1835
		// tangents

		if ( attributes.tangent >= 0 ) {
1836

1837
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLTangentBuffer );
1838
			_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
1839

1840
		}
1841

1842
		// uvs
M
Mr.doob 已提交
1843

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

1846
			if ( geometryGroup.__webGLUVBuffer ) {
1847

1848
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUVBuffer );
1849
				_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
1850

1851
				_gl.enableVertexAttribArray( attributes.uv );
1852

1853
			} else {
1854

1855
				_gl.disableVertexAttribArray( attributes.uv );
M
Mr.doob 已提交
1856

1857
			}
1858 1859 1860

		}

1861 1862
		if ( attributes.uv2 >= 0 ) {

1863
			if ( geometryGroup.__webGLUV2Buffer ) {
1864

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

				_gl.enableVertexAttribArray( attributes.uv2 );

			} else {

				_gl.disableVertexAttribArray( attributes.uv2 );

			}

		}

1878
		if ( material.skinning &&
1879
			 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
A
alteredq 已提交
1880
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
1881

1882
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexABuffer );
A
alteredq 已提交
1883 1884
			_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );

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

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

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

A
alteredq 已提交
1894
		}
1895

1896
		// render mesh
M
Mr.doob 已提交
1897

1898
		if ( object instanceof THREE.Mesh ) {
1899

1900
			// wireframe
1901

1902
			if ( material.wireframe ) {
M
Mr.doob 已提交
1903

1904
				_gl.lineWidth( material.wireframeLinewidth );
1905 1906
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webGLLineCount, _gl.UNSIGNED_SHORT, 0 );
1907

1908
			// triangles
1909

1910
			} else {
1911

1912 1913
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
1914
			}
1915

1916
		// render lines
1917

1918
		} else if ( object instanceof THREE.Line ) {
1919

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

1922
			_gl.lineWidth( material.linewidth );
1923
			_gl.drawArrays( primitives, 0, geometryGroup.__webGLLineCount );
1924

1925
		// render particles
1926

1927
		} else if ( object instanceof THREE.ParticleSystem ) {
1928

1929
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webGLParticleCount );
1930

A
alteredq 已提交
1931
		// render ribbon
1932

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

1935
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webGLVertexCount );
1936

1937 1938 1939 1940
		}

	};

M
Mikael Emtinger 已提交
1941

M
Mikael Emtinger 已提交
1942 1943 1944 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
	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 );
	}


2025
	function renderBufferImmediate ( object, program ) {
2026

A
alteredq 已提交
2027 2028
		if ( ! object.__webGLVertexBuffer ) object.__webGLVertexBuffer = _gl.createBuffer();
		if ( ! object.__webGLNormalBuffer ) object.__webGLNormalBuffer = _gl.createBuffer();
2029

A
alteredq 已提交
2030
		if ( object.hasPos ) {
2031

A
alteredq 已提交
2032 2033 2034 2035
		  _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 );
2036

A
alteredq 已提交
2037
		}
2038

A
alteredq 已提交
2039
		if ( object.hasNormal ) {
2040

A
alteredq 已提交
2041 2042 2043 2044
		  _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 );
2045

A
alteredq 已提交
2046
		}
2047

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

A
alteredq 已提交
2050
		object.count = 0;
2051

A
alteredq 已提交
2052
	};
2053

2054
	function setObjectFaces ( object ) {
2055

2056
		if ( _oldDoubleSided != object.doubleSided ) {
2057

2058
			if( object.doubleSided ) {
2059

2060
				_gl.disable( _gl.CULL_FACE );
2061

2062
			} else {
2063

A
alteredq 已提交
2064
				_gl.enable( _gl.CULL_FACE );
2065

A
alteredq 已提交
2066
			}
2067

2068
			_oldDoubleSided = object.doubleSided;
2069

2070
		}
2071

2072
		if ( _oldFlipSided != object.flipSided ) {
2073

2074 2075 2076 2077
			if( object.flipSided ) {

				_gl.frontFace( _gl.CW );

2078
			} else {
2079 2080 2081 2082

				_gl.frontFace( _gl.CCW );

			}
2083

2084
			_oldFlipSided = object.flipSided;
2085 2086

		}
2087

2088
	};
2089

2090
	function setDepthTest ( test ) {
2091

A
alteredq 已提交
2092 2093 2094
		if ( _oldDepth != test ) {

			if( test ) {
2095

A
alteredq 已提交
2096
				_gl.enable( _gl.DEPTH_TEST );
2097

A
alteredq 已提交
2098
			} else {
2099

A
alteredq 已提交
2100
				_gl.disable( _gl.DEPTH_TEST );
2101

A
alteredq 已提交
2102
			}
2103

A
alteredq 已提交
2104 2105 2106
			_oldDepth = test;

		}
2107

A
alteredq 已提交
2108
	};
2109

2110
	function computeFrustum ( m ) {
2111 2112 2113 2114 2115 2116 2117 2118 2119

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

A
alteredq 已提交
2121
		for ( i = 0; i < 6; i ++ ) {
2122 2123 2124 2125 2126 2127 2128

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

		}

	};
2129

2130
	function isInFrustum ( object ) {
2131

2132
		var distance, matrix = object.matrixWorld,
2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144
		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;

	};
2145

2146
	function addToFixedArray ( where, what ) {
2147

2148 2149
		where.list[ where.count ] = what;
		where.count += 1;
2150

2151
	};
2152

2153
	function unrollImmediateBufferMaterials ( globject ) {
2154

2155 2156 2157 2158 2159 2160 2161
		var i, l, m, ml, material,
			object = globject.object,
			opaque = globject.opaque,
			transparent = globject.transparent;

		transparent.count = 0;
		opaque.count = 0;
2162

2163 2164 2165
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

			material = object.materials[ m ];
2166

2167 2168 2169 2170
			if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending )
				addToFixedArray( transparent, material );
			else
				addToFixedArray( opaque, material );
2171

2172
		}
2173

2174
	};
2175

2176
	function unrollBufferMaterials ( globject ) {
2177

2178 2179 2180 2181 2182 2183 2184 2185
		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;
2186

2187 2188 2189 2190 2191 2192 2193 2194 2195
		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 ];
2196

2197
					if ( material ) {
2198

2199 2200 2201 2202
						if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending )
							addToFixedArray( transparent, material );
						else
							addToFixedArray( opaque, material );
2203

2204 2205 2206 2207 2208 2209 2210
					}

				}

			} else {

				material = meshMaterial;
2211

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

2214
					addToFixedArray( transparent, material );
2215 2216 2217

				} else {

2218 2219
					addToFixedArray( opaque, material );

2220 2221
				}

2222 2223 2224
			}

		}
2225

2226
	};
2227 2228


2229
	function painterSort ( a, b ) {
2230

2231
		return b.z - a.z;
2232 2233

	};
2234

2235
	this.render = function ( scene, camera, renderTarget, forceClear ) {
2236

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

M
Mr.doob 已提交
2242
		camera.matrixAutoUpdate && camera.updateMatrix();
2243

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

M
Mr.doob 已提交
2246
		camera.matrixWorldInverse.flattenToArray( _viewMatrixArray );
2247
		camera.projectionMatrix.flattenToArray( _projectionMatrixArray );
M
Mr.doob 已提交
2248

M
Mr.doob 已提交
2249
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
2250
		computeFrustum( _projScreenMatrix );
2251

A
alteredq 已提交
2252
		this.initWebGLObjects( scene );
M
Mr.doob 已提交
2253

A
alteredq 已提交
2254
		setRenderTarget( renderTarget );
M
Mr.doob 已提交
2255

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

2258
			this.clear();
M
Mr.doob 已提交
2259

2260 2261
		}

2262
		// set matrices
2263

2264
		ol = scene.__webglObjects.length;
2265

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

2268 2269
			webglObject = scene.__webglObjects[ o ];
			object = webglObject.object;
M
Mr.doob 已提交
2270

2271
			if ( object.visible ) {
2272 2273

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

2275
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
2276

2277
					setupMatrices( object, camera );
2278

2279
					unrollBufferMaterials( webglObject );
2280

2281
					webglObject.render = true;
2282

2283
					if ( this.sortObjects ) {
2284

2285 2286 2287
						_vector3.copy( object.position );
						_projScreenMatrix.multiplyVector3( _vector3 );

2288
						webglObject.z = _vector3.z;
2289

2290
					}
2291

2292
				} else {
2293

2294
					webglObject.render = false;
2295

2296
				}
2297

2298
			} else {
2299

2300
				webglObject.render = false;
2301

2302
			}
2303

2304
		}
2305

2306
		if ( this.sortObjects ) {
2307

2308
			scene.__webglObjects.sort( painterSort );
2309

2310
		}
2311

2312
		oil = scene.__webglObjectsImmediate.length;
2313

2314
		for ( o = 0; o < oil; o++ ) {
2315

2316 2317
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2318

2319
			if ( object.visible ) {
2320 2321 2322

				if( object.matrixAutoUpdate ) {

2323
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
2324

A
alteredq 已提交
2325
				}
2326

2327
				setupMatrices( object, camera );
2328

2329
				unrollImmediateBufferMaterials( webglObject );
2330

2331
			}
2332

2333
		}
A
alteredq 已提交
2334

2335 2336
		// opaque pass

2337
		setBlending( THREE.NormalBlending );
2338

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

2341
			webglObject = scene.__webglObjects[ o ];
2342

2343
			if ( webglObject.render ) {
2344

2345 2346 2347
				object = webglObject.object;
				buffer = webglObject.buffer;
				opaque = webglObject.opaque;
2348

2349
				setObjectFaces( object );
2350

2351
				for( i = 0; i < opaque.count; i++ ) {
2352

2353
					material = opaque.list[ i ];
2354

2355
					setDepthTest( material.depthTest );
A
alteredq 已提交
2356
					renderBuffer( camera, lights, fog, material, buffer, object );
2357

2358
				}
2359 2360 2361 2362 2363

			}

		}

A
alteredq 已提交
2364
		// opaque pass (immediate simulator)
2365

2366
		for ( o = 0; o < oil; o++ ) {
2367

2368 2369
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2370

A
alteredq 已提交
2371
			if ( object.visible ) {
2372

2373
				opaque = webglObject.opaque;
2374

2375
				setObjectFaces( object );
2376

2377
				for( i = 0; i < opaque.count; i++ ) {
2378

2379
					material = opaque.list[ i ];
2380

2381
					setDepthTest( material.depthTest );
2382

A
alteredq 已提交
2383
					program = setProgram( camera, lights, fog, material, object );
2384
					object.render( function( object ) { renderBufferImmediate( object, program ); } );
2385

2386
				}
2387

A
alteredq 已提交
2388
			}
2389

A
alteredq 已提交
2390 2391
		}

2392 2393
		// transparent pass

2394
		for ( o = 0; o < ol; o++ ) {
2395

2396
			webglObject = scene.__webglObjects[ o ];
2397

2398
			if ( webglObject.render ) {
2399

2400 2401 2402
				object = webglObject.object;
				buffer = webglObject.buffer;
				transparent = webglObject.transparent;
2403

2404
				setObjectFaces( object );
2405

2406
				for( i = 0; i < transparent.count; i++ ) {
2407

2408
					material = transparent.list[ i ];
2409

2410
					setBlending( material.blending );
2411
					setDepthTest( material.depthTest );
2412

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

2415
				}
2416

2417
			}
M
Mr.doob 已提交
2418

M
Mr.doob 已提交
2419
		}
M
Mr.doob 已提交
2420

2421
		// transparent pass (immediate simulator)
2422

2423
		for ( o = 0; o < oil; o++ ) {
2424

2425 2426
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2427

2428
			if ( object.visible ) {
2429

2430
				transparent = webglObject.transparent;
2431

2432
				setObjectFaces( object );
2433

2434
				for( i = 0; i < transparent.count; i++ ) {
2435

2436
					material = transparent.list[ i ];
2437

2438
					setBlending( material.blending );
2439
					setDepthTest( material.depthTest );
2440

A
alteredq 已提交
2441
					program = setProgram( camera, lights, fog, material, object );
2442
					object.render( function( object ) { renderBufferImmediate( object, program ); } );
2443

2444
				}
2445

2446
			}
2447

2448
		}
2449

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

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

2454
			updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
2455

2456
		}
2457

M
Mr.doob 已提交
2458
	};
M
Mr.doob 已提交
2459

2460
	function setupMatrices ( object, camera ) {
2461

2462 2463
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
		THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
2464

2465
	};
2466

A
alteredq 已提交
2467
	this.initWebGLObjects = function ( scene ) {
2468

2469
		if ( !scene.__webglObjects ) {
2470

2471 2472
			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
2473 2474 2475

		}

M
Mr.doob 已提交
2476
		while ( scene.__objectsAdded.length ) {
2477

M
Mr.doob 已提交
2478 2479
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
2480 2481 2482

		}

M
Mr.doob 已提交
2483
		while ( scene.__objectsRemoved.length ) {
2484

M
Mr.doob 已提交
2485 2486
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
2487 2488

		}
2489

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

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

M
Mr.doob 已提交
2494
			updateObject( scene.__webglObjects[ o ].object, scene );
A
alteredq 已提交
2495 2496 2497

		}

2498
	};
2499

2500
	function addObject ( object, scene ) {
2501

2502
		var g, geometry, geometryGroup;
M
Mr.doob 已提交
2503

2504
		if ( object._modelViewMatrix == undefined ) {
2505

2506
			object._modelViewMatrix = new THREE.Matrix4();
2507

2508 2509 2510
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
2511

2512
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
2513

2514
		}
A
alteredq 已提交
2515

2516
		if ( object instanceof THREE.Mesh ) {
A
alteredq 已提交
2517

2518 2519 2520 2521 2522 2523 2524 2525
			geometry = object.geometry;

			if ( geometry.geometryGroups == undefined ) {

				sortFacesByMaterial( geometry );

			}

2526
			// create separate VBOs per geometry chunk
A
alteredq 已提交
2527

2528
			for ( g in geometry.geometryGroups ) {
A
alteredq 已提交
2529

2530
				geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
2531

2532
				// initialise VBO on the first access
M
Mr.doob 已提交
2533

2534
				if ( ! geometryGroup.__webGLVertexBuffer ) {
M
Mr.doob 已提交
2535

2536 2537
					createMeshBuffers( geometryGroup );
					initMeshBuffers( geometryGroup, object );
A
alteredq 已提交
2538

2539
					geometry.__dirtyVertices = true;
2540
					geometry.__dirtyMorphTargets = true;
2541 2542 2543 2544 2545
					geometry.__dirtyElements = true;
					geometry.__dirtyUvs = true;
					geometry.__dirtyNormals = true;
					geometry.__dirtyTangents = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
2546

2547
				}
2548

2549
				// create separate wrapper per each use of VBO
2550

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

2553
			}
M
Mr.doob 已提交
2554

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

2557 2558
			geometry = object.geometry;

A
alteredq 已提交
2559 2560 2561 2562 2563 2564 2565 2566 2567 2568
			if( ! geometry.__webGLVertexBuffer ) {

				createRibbonBuffers( geometry );
				initRibbonBuffers( geometry );

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

			}

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

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

2573 2574
			geometry = object.geometry;

2575
			if( ! geometry.__webGLVertexBuffer ) {
M
Mr.doob 已提交
2576

2577 2578
				createLineBuffers( geometry );
				initLineBuffers( geometry );
M
Mr.doob 已提交
2579

2580 2581
				geometry.__dirtyVertices = true;
				geometry.__dirtyColors = true;
M
Mr.doob 已提交
2582

2583
			}
M
Mr.doob 已提交
2584

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

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

			geometry = object.geometry;

			if ( ! geometry.__webGLVertexBuffer ) {

				createParticleBuffers( geometry );
				initParticleBuffers( geometry );

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

2599
			}
2600

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

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

			addBufferImmediate( scene.__webglObjectsImmediate, object );

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

		}*/

	};

2613
	function updateObject ( object, scene ) {
A
alteredq 已提交
2614

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

		if ( object instanceof THREE.Mesh ) {

			geometry = object.geometry;

			// check all geometry groups

			for ( g in geometry.geometryGroups ) {

				geometryGroup = geometry.geometryGroups[ g ];

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

					setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW );

				}

			}

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

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

2647 2648
			geometry = object.geometry;

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

A
alteredq 已提交
2651
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
2652

A
alteredq 已提交
2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664
			}

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

2666
			}
2667

A
alteredq 已提交
2668 2669 2670 2671 2672 2673 2674
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

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

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

2679
			}
M
Mr.doob 已提交
2680

2681 2682
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
2683

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

A
alteredq 已提交
2686
			// it updates itself in render callback
2687 2688

		} else if ( object instanceof THREE.Particle ) {
2689 2690

		}*/
2691

2692
	};
2693

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

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

			}

		}

	};

2712
	function sortFacesByMaterial ( geometry ) {
2713 2714 2715 2716 2717 2718 2719

		// 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 = {};
2720
		var numMorphTargets = geometry.morphTargets !== undefined ? geometry.morphTargets.length : 0;
2721 2722 2723 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

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

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

			}

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

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

				}

			}

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

		}

	};

2789
	function addBuffer ( objlist, buffer, object ) {
2790

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

2796
	};
2797

2798
	function addBufferImmediate ( objlist, object ) {
2799

2800 2801 2802 2803
		objlist.push( { object: object,
				opaque: { list: [], count: 0 },
				transparent: { list: [], count: 0 }
			} );
2804

2805
	};
2806

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

2809
		if ( cullFace ) {
M
Mr.doob 已提交
2810

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

2813
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
2814

2815
			} else {
M
Mr.doob 已提交
2816

2817
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
2818

2819
			}
M
Mr.doob 已提交
2820

2821
			if( cullFace == "back" ) {
M
Mr.doob 已提交
2822

2823
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
2824

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

2827
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
2828

2829
			} else {
M
Mr.doob 已提交
2830

2831
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
2832

2833
			}
M
Mr.doob 已提交
2834

2835
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
2836

2837
		} else {
M
Mr.doob 已提交
2838

2839
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
2840

2841 2842 2843
		}

	};
N
Nicolas Garcia Belmonte 已提交
2844

2845
	this.supportsVertexTextures = function () {
2846

2847
		return maxVertexTextures() > 0;
2848

2849
	};
2850

2851
	function maxVertexTextures () {
2852

2853 2854 2855
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
2856

2857
	function initGL ( antialias, clearColor, clearAlpha ) {
N
Nicolas Garcia Belmonte 已提交
2858 2859 2860

		try {

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

2863
				throw 'Error creating WebGL context.';
N
Nicolas Garcia Belmonte 已提交
2864

2865 2866 2867
			}

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

2869
			console.error( e );
N
Nicolas Garcia Belmonte 已提交
2870 2871 2872 2873 2874 2875 2876 2877 2878

		}

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

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

2879 2880
		_gl.frontFace( _gl.CCW );
		_gl.cullFace( _gl.BACK );
2881
		_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
2882

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

A
alteredq 已提交
2887
		_cullEnabled = true;
N
Nicolas Garcia Belmonte 已提交
2888

2889
	};
M
Mr.doob 已提交
2890

2891
	function buildProgram ( fragmentShader, vertexShader, parameters ) {
2892
		
M
Mr.doob 已提交
2893
		var program = _gl.createProgram(),
M
Mr.doob 已提交
2894

M
Mr.doob 已提交
2895 2896 2897 2898
		prefix_fragment = [
			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",
M
Mr.doob 已提交
2899

2900 2901
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
2902

2903 2904
			parameters.fog ? "#define USE_FOG" : "",
			parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "",
2905

2906
			parameters.map ? "#define USE_MAP" : "",
2907 2908 2909
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
2910

2911
			"uniform mat4 viewMatrix;",
2912
			"uniform vec3 cameraPosition;",
M
Mr.doob 已提交
2913 2914
			""
		].join("\n"),
2915

M
Mr.doob 已提交
2916
		prefix_vertex = [
2917
			maxVertexTextures() > 0 ? "#define VERTEX_TEXTURES" : "",
2918

2919 2920 2921
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

2922 2923
			"#define MAX_BONES " + parameters.maxBones,

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

2931

2932 2933
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

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

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
2943
			"attribute vec3 position;",
2944 2945 2946 2947 2948 2949 2950 2951
			"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 已提交
2952
			"attribute vec3 normal;",
A
alteredq 已提交
2953
			"attribute vec3 color;",
M
Mr.doob 已提交
2954
			"attribute vec2 uv;",
2955
			"attribute vec2 uv2;",
2956

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

2964 2965
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
2966

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

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

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

N
Nicolas Garcia Belmonte 已提交
2973
		}
2974

2975 2976
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
2977

M
Mr.doob 已提交
2978
		program.uniforms = {};
2979
		program.attributes = {};
M
Mr.doob 已提交
2980

M
Mr.doob 已提交
2981
		return program;
M
Mr.doob 已提交
2982

M
Mr.doob 已提交
2983
	};
M
Mr.doob 已提交
2984

2985
	function loadUniformsSkinning ( uniforms, object ) {
2986

M
Mr.doob 已提交
2987
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray );
A
alteredq 已提交
2988
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
2989

2990
	};
2991
		
2992

2993
	function loadUniformsMatrices ( uniforms, object ) {
2994

A
alteredq 已提交
2995 2996 2997 2998
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
		_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );

	};
2999

3000
	function loadUniformsGeneric ( program, uniforms ) {
M
Mr.doob 已提交
3001

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

M
Mr.doob 已提交
3004
		for( u in uniforms ) {
M
Mr.doob 已提交
3005

3006 3007
			location = program.uniforms[u];
			if ( !location ) continue;
M
Mr.doob 已提交
3008

3009
			uniform = uniforms[u];
M
Mr.doob 已提交
3010

3011 3012
			type = uniform.type;
			value = uniform.value;
M
Mr.doob 已提交
3013

M
Mr.doob 已提交
3014
			if( type == "i" ) {
M
Mr.doob 已提交
3015

M
Mr.doob 已提交
3016
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
3017

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

M
Mr.doob 已提交
3020
				_gl.uniform1f( location, value );
3021

A
alteredq 已提交
3022 3023 3024
			} else if( type == "fv1" ) {

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

3026 3027 3028 3029
			} else if( type == "fv" ) {

				_gl.uniform3fv( location, value );

3030 3031 3032 3033
			} else if( type == "v2" ) {

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

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

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

3038 3039 3040
			} else if( type == "c" ) {

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

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

M
Mr.doob 已提交
3044
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
3045

3046
				texture = uniform.texture;
M
Mr.doob 已提交
3047

3048
				if ( !texture ) continue;
M
Mr.doob 已提交
3049

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

3052
					setCubeTexture( texture, value );
M
Mr.doob 已提交
3053

3054
				} else {
M
Mr.doob 已提交
3055

3056
					setTexture( texture, value );
M
Mr.doob 已提交
3057

3058
				}
M
Mr.doob 已提交
3059

3060
			}
M
Mr.doob 已提交
3061

3062
		}
M
Mr.doob 已提交
3063

3064
	};
M
Mr.doob 已提交
3065

3066
	function setBlending ( blending ) {
A
alteredq 已提交
3067 3068

		if ( blending != _oldBlending ) {
3069

A
alteredq 已提交
3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092
			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;

3093 3094 3095 3096 3097 3098
				case THREE.ReverseSubtractiveBlending:

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

    				break;
A
alteredq 已提交
3099 3100 3101 3102 3103 3104
				default:

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

					break;
3105

A
alteredq 已提交
3106
			}
3107

A
alteredq 已提交
3108
			_oldBlending = blending;
3109

A
alteredq 已提交
3110 3111 3112
		}

	};
3113

3114
	function setTextureParameters ( textureType, texture, image ) {
3115

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

3118 3119
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
3120

3121 3122
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
3123

3124
			_gl.generateMipmap( textureType );
M
Mr.doob 已提交
3125

3126
		} else {
M
Mr.doob 已提交
3127

3128 3129 3130 3131 3132
			_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 已提交
3133

3134
		}
M
Mr.doob 已提交
3135

3136 3137
	};
	
3138
	function setTexture ( texture, slot ) {
3139

3140
		if ( texture.needsUpdate ) {
A
alteredq 已提交
3141

3142
			if ( !texture.__wasSetOnce ) {
M
Mr.doob 已提交
3143

3144
				texture.__webGLTexture = _gl.createTexture();
A
alteredq 已提交
3145

3146 3147
				_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 已提交
3148

A
alteredq 已提交
3149
				texture.__wasSetOnce = true;
M
Mr.doob 已提交
3150

A
alteredq 已提交
3151
			} else {
M
Mr.doob 已提交
3152

A
alteredq 已提交
3153 3154
				_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 已提交
3155 3156 3157

			}

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

		}

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

3168
	};
M
Mr.doob 已提交
3169

3170
	function setCubeTexture ( texture, slot ) {
3171 3172 3173 3174

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

			if ( texture.needsUpdate ) {
3175 3176
				
				if ( !texture.__wasSetOnce ) {
3177 3178 3179

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

3180
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube );
3181

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

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

3186 3187 3188
					}
				
					texture.__wasSetOnce = true;
3189 3190 3191

				} else {

3192
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube );
3193

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

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

3198
					}
3199 3200 3201

				}

3202
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[0] );
3203 3204 3205
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

				texture.needsUpdate = false;
3206
				
3207 3208 3209 3210 3211 3212 3213 3214 3215
			}

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

		}

	};

3216
	function setRenderTarget ( renderTexture ) {
3217 3218

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

3220 3221 3222 3223 3224
			renderTexture.__webGLFramebuffer = _gl.createFramebuffer();
			renderTexture.__webGLRenderbuffer = _gl.createRenderbuffer();
			renderTexture.__webGLTexture = _gl.createTexture();

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

3226 3227 3228 3229
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTexture.__webGLRenderbuffer );
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTexture.width, renderTexture.height );

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

3231
			_gl.bindTexture( _gl.TEXTURE_2D, renderTexture.__webGLTexture );
3232 3233 3234 3235
			_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 ) );
3236
			_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTexture.format ), renderTexture.width, renderTexture.height, 0, paramThreeToGL( renderTexture.format ), paramThreeToGL( renderTexture.type ), null );
3237 3238

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

3240 3241
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTexture.__webGLFramebuffer );
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, renderTexture.__webGLTexture, 0 );
3242
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webGLRenderbuffer );
3243 3244

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

3246 3247 3248
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
3249

3250 3251
		}

3252
		var framebuffer, width, height;
M
Mr.doob 已提交
3253

3254
		if ( renderTexture ) {
M
Mr.doob 已提交
3255

3256 3257 3258
			framebuffer = renderTexture.__webGLFramebuffer;
			width = renderTexture.width;
			height = renderTexture.height;
M
Mr.doob 已提交
3259

3260
		} else {
M
Mr.doob 已提交
3261

3262
			framebuffer = null;
3263 3264
			width = _viewportWidth;
			height = _viewportHeight;
M
Mr.doob 已提交
3265

3266
		}
M
Mr.doob 已提交
3267

3268
		if( framebuffer != _oldFramebuffer ) {
M
Mr.doob 已提交
3269

3270
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
3271
			_gl.viewport( _viewportX, _viewportY, width, height );
M
Mr.doob 已提交
3272

3273
			_oldFramebuffer = framebuffer;
M
Mr.doob 已提交
3274

3275
		}
3276

3277
	};
M
Mr.doob 已提交
3278

3279
	function updateRenderTargetMipmap ( renderTarget ) {
M
Mr.doob 已提交
3280

3281 3282 3283
		_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webGLTexture );
		_gl.generateMipmap( _gl.TEXTURE_2D );
		_gl.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
3284 3285

	};
3286

3287
	function cacheUniformLocations ( program, identifiers ) {
M
Mr.doob 已提交
3288

M
Mr.doob 已提交
3289
		var i, l, id;
M
Mr.doob 已提交
3290

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

3293 3294
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
3295

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

M
Mr.doob 已提交
3298
	};
M
Mr.doob 已提交
3299

3300
	function cacheAttributeLocations ( program, identifiers ) {
3301

3302
		var i, l, id;
M
Mr.doob 已提交
3303

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

3306 3307
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
3308

3309
		}
M
Mr.doob 已提交
3310

M
Mr.doob 已提交
3311
	};
M
Mr.doob 已提交
3312

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

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

3332
			console.error( _gl.getShaderInfoLog( shader ) );
3333
			console.error( string );
N
Nicolas Garcia Belmonte 已提交
3334 3335 3336 3337 3338
			return null;

		}

		return shader;
M
Mr.doob 已提交
3339

3340
	};
N
Nicolas Garcia Belmonte 已提交
3341

3342
	// fallback filters for non-power-of-2 textures
3343

3344
	function filterFallback ( f ) {
3345

3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359
		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;

		}
		
	};
	
3360
	function paramThreeToGL ( p ) {
M
Mr.doob 已提交
3361

3362
		switch ( p ) {
M
Mr.doob 已提交
3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375

			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;

3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389
			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;

3390
		}
M
Mr.doob 已提交
3391

3392
		return 0;
M
Mr.doob 已提交
3393

3394 3395
	};

3396
	function isPowerOfTwo ( value ) {
3397 3398 3399 3400 3401

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

	};

3402
	function materialNeedsSmoothNormals ( material ) {
3403 3404 3405

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

3406
	};
M
Mr.doob 已提交
3407

3408
	function bufferNeedsSmoothNormals ( geometryGroup, object ) {
M
Mr.doob 已提交
3409

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

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

M
Mr.doob 已提交
3414
			meshMaterial = object.materials[ m ];
3415 3416 3417

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

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

3420
					if ( materialNeedsSmoothNormals( geometryGroup.materials[ i ] ) ) {
3421

3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442
						needsSmoothNormals = true;
						break;

					}

				}

			} else {

				if ( materialNeedsSmoothNormals( meshMaterial ) ) {

					needsSmoothNormals = true;
					break;

				}

			}

			if ( needsSmoothNormals ) break;

		}
M
Mr.doob 已提交
3443

3444
		return needsSmoothNormals;
M
Mr.doob 已提交
3445

3446
	};
M
Mr.doob 已提交
3447

3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521
	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 ];
			
3522
			if ( m instanceof THREE.MeshBasicMaterial || m instanceof THREE.MeshDepthMaterial ) continue;
3523 3524 3525 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 3553 3554 3555 3556 3557 3558 3559 3560 3561
			
			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 ];
			
			if ( m.map || m.lightMap ) {
				
				return true;
				
			}
			
		}
		
		return false;
		
	};
	
3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584
	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 ) {
3585

3586 3587
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
3588

3589
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
3590

3591
			light = lights[ l ];
3592

3593 3594
			if ( light instanceof THREE.DirectionalLight ) dirLights++;
			if ( light instanceof THREE.PointLight ) pointLights++;
3595

3596
		}
3597

3598
		if ( ( pointLights + dirLights ) <= maxLights ) {
3599

3600 3601
			maxDirLights = dirLights;
			maxPointLights = pointLights;
3602

3603
		} else {
3604

3605 3606
			maxDirLights = Math.ceil( maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = maxLights - maxDirLights;
3607 3608 3609

		}

3610
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
3611 3612

	};
M
Mr.doob 已提交
3613

A
alteredq 已提交
3614
	/* DEBUG
3615
	function getGLParams() {
M
Mr.doob 已提交
3616

3617
		var params  = {
M
Mr.doob 已提交
3618

3619 3620
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
3621

3622 3623 3624
			'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 已提交
3625

3626 3627 3628
			'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 已提交
3629

3630 3631
		return params;
	};
M
Mr.doob 已提交
3632

3633
	function dumpObject( obj ) {
M
Mr.doob 已提交
3634

3635 3636
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
3637

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

3640
		}
M
Mr.doob 已提交
3641

3642 3643
		return str;
	}
A
alteredq 已提交
3644
	*/
3645
};
3646