WebGLRenderer.js 94.7 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,
M
Mikael Emtinger 已提交
35
	_cullEnabled = true,
36

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

42
	// camera matrices caches
43 44

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

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

57
	_vector3 = new THREE.Vector4(),
58

A
alteredq 已提交
59 60 61 62 63 64 65 66 67 68
	// 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() }

	},

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

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

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

77 78 79
		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 已提交
80

81
	}
M
Mr.doob 已提交
82

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

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

90 91
	this.context = _gl;

M
Mikael Emtinger 已提交
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127

	// create shadow polygons

	var _shadow   = {};
	var vertices = [];
	var faces    = [];
	
	vertices[ 0 * 3 + 0 ] = -2; vertices[ 0 * 3 + 1 ] = -1; vertices[ 0 * 3 + 2 ] = -1;
	vertices[ 1 * 3 + 0 ] =  2; vertices[ 1 * 3 + 1 ] = -1; vertices[ 1 * 3 + 2 ] = -1;
	vertices[ 2 * 3 + 0 ] =  2; vertices[ 2 * 3 + 1 ] =  1; vertices[ 2 * 3 + 2 ] = -1;
	vertices[ 3 * 3 + 0 ] = -2; vertices[ 3 * 3 + 1 ] =  1; vertices[ 3 * 3 + 2 ] = -1;
	
	faces[ 0 ] = 0; faces[ 1 ] = 1; faces[ 2 ] = 2;
	faces[ 3 ] = 0; faces[ 4 ] = 2; faces[ 5 ] = 3;


	_shadow.vertexBuffer  = _gl.createBuffer();
	_shadow.elementBuffer = _gl.createBuffer();
	
	_gl.bindBuffer( _gl.ARRAY_BUFFER, _shadow.vertexBuffer );
	_gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( vertices ), _gl.STATIC_DRAW );

	_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _shadow.elementBuffer );
	_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( faces ), _gl.STATIC_DRAW );
	

	_shadow.program = _gl.createProgram();

	_gl.attachShader( _shadow.program, getShader( "fragment", THREE.ShaderLib.shadowPost.fragmentShader ));
	_gl.attachShader( _shadow.program, getShader( "vertex",   THREE.ShaderLib.shadowPost.vertexShader   ));

	_gl.linkProgram( _shadow.program );

	_shadow.vertexLocation     = _gl.getAttribLocation ( _shadow.program, "position"         );
	_shadow.projectionLocation = _gl.getUniformLocation( _shadow.program, "projectionMatrix" );

M
Mr.doob 已提交
128

N
Nicolas Garcia Belmonte 已提交
129 130 131 132
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
133

134 135 136
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
137

138
	this.setViewport = function ( x, y, width, height ) {
139

140 141
		_viewportX = x;
		_viewportY = y;
142

143 144
		_viewportWidth = width;
		_viewportHeight = height;
145

146
		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
147

N
Nicolas Garcia Belmonte 已提交
148
	};
149

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

152
		_gl.scissor( x, y, width, height );
153

154
	};
155

156
	this.enableScissorTest = function ( enable ) {
157

158 159 160 161
		if ( enable )
			_gl.enable( _gl.SCISSOR_TEST );
		else
			_gl.disable( _gl.SCISSOR_TEST );
162

163
	};
164

165
	this.enableDepthBufferWrite = function ( enable ) {
166

167 168 169
		_gl.depthMask( enable );

	};
170

171
	this.setClearColorHex = function ( hex, alpha ) {
172

173 174
		var color = new THREE.Color( hex );
		_gl.clearColor( color.r, color.g, color.b, alpha );
175

176
	};
A
alteredq 已提交
177

178
	this.setClearColor = function ( color, alpha ) {
A
alteredq 已提交
179 180 181 182

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

	};
183

N
Nicolas Garcia Belmonte 已提交
184 185
	this.clear = function () {

M
Mikael Emtinger 已提交
186
		_gl.clear( _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT | _gl.STENCIL_BUFFER_BIT );
N
Nicolas Garcia Belmonte 已提交
187 188 189

	};

M
Mr.doob 已提交
190

A
alteredq 已提交
191
	function setupLights ( program, lights ) {
192

193
		var l, ll, light, r = 0, g = 0, b = 0,
194
			color, position, intensity,
M
Mr.doob 已提交
195

A
alteredq 已提交
196
			zlights = _lights,
M
Mr.doob 已提交
197

198 199
			dcolors    = zlights.directional.colors,
			dpositions = zlights.directional.positions,
200

201 202
			pcolors    = zlights.point.colors,
			ppositions = zlights.point.positions,
203

204
			dlength = 0,
205
			plength = 0,
206

207 208
			doffset = 0,
			poffset = 0;
M
Mr.doob 已提交
209

210
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
211

212
			light = lights[ l ];
213 214 215
			color = light.color;
			position = light.position;
			intensity = light.intensity;
216 217 218

			if ( light instanceof THREE.AmbientLight ) {

219 220 221
				r += color.r;
				g += color.g;
				b += color.b;
M
Mr.doob 已提交
222

223
			} else if ( light instanceof THREE.DirectionalLight ) {
224

225
				doffset = dlength * 3;
226

227 228 229
				dcolors[ doffset ]     = color.r * intensity;
				dcolors[ doffset + 1 ] = color.g * intensity;
				dcolors[ doffset + 2 ] = color.b * intensity;
230

231 232 233
				dpositions[ doffset ]     = position.x;
				dpositions[ doffset + 1 ] = position.y;
				dpositions[ doffset + 2 ] = position.z;
234

235
				dlength += 1;
M
Mr.doob 已提交
236

237 238
			} else if( light instanceof THREE.PointLight ) {

239
				poffset = plength * 3;
240

241 242 243
				pcolors[ poffset ]     = color.r * intensity;
				pcolors[ poffset + 1 ] = color.g * intensity;
				pcolors[ poffset + 2 ] = color.b * intensity;
244

245 246 247
				ppositions[ poffset ]     = position.x;
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
M
Mr.doob 已提交
248

249
				plength += 1;
M
Mr.doob 已提交
250

251 252 253
			}

		}
254

255 256
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
257

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

261 262
		zlights.point.length = plength;
		zlights.directional.length = dlength;
M
Mr.doob 已提交
263

264 265 266
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
M
Mr.doob 已提交
267

268
	};
M
Mr.doob 已提交
269

270
	function createParticleBuffers ( geometry ) {
M
Mr.doob 已提交
271

272
		geometry.__webGLVertexBuffer = _gl.createBuffer();
273
		geometry.__webGLColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
274

275
	};
M
Mr.doob 已提交
276

277
	function createLineBuffers ( geometry ) {
M
Mr.doob 已提交
278

279
		geometry.__webGLVertexBuffer = _gl.createBuffer();
280
		geometry.__webGLColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
281

282
	};
283

A
alteredq 已提交
284 285 286 287 288 289 290
	function createRibbonBuffers ( geometry ) {

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

	};

291
	function createMeshBuffers ( geometryGroup ) {
M
Mr.doob 已提交
292

293 294 295 296 297 298
		geometryGroup.__webGLVertexBuffer = _gl.createBuffer();
		geometryGroup.__webGLNormalBuffer = _gl.createBuffer();
		geometryGroup.__webGLTangentBuffer = _gl.createBuffer();
		geometryGroup.__webGLColorBuffer = _gl.createBuffer();
		geometryGroup.__webGLUVBuffer = _gl.createBuffer();
		geometryGroup.__webGLUV2Buffer = _gl.createBuffer();
299

300 301 302 303
		geometryGroup.__webGLSkinVertexABuffer = _gl.createBuffer();
		geometryGroup.__webGLSkinVertexBBuffer = _gl.createBuffer();
		geometryGroup.__webGLSkinIndicesBuffer = _gl.createBuffer();
		geometryGroup.__webGLSkinWeightsBuffer = _gl.createBuffer();
304

305 306
		geometryGroup.__webGLFaceBuffer = _gl.createBuffer();
		geometryGroup.__webGLLineBuffer = _gl.createBuffer();
307 308
		
		
309
		if( geometryGroup.numMorphTargets ) {
310
			
311 312
			var m, ml;
			geometryGroup.__webGLMorphTargetsBuffers = []; 
313
			
314
			for( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m++ ) {
315
				
316
				geometryGroup.__webGLMorphTargetsBuffers.push( _gl.createBuffer());	
317 318 319
			}

		}
M
Mr.doob 已提交
320

321
	};
322

323
	function initLineBuffers ( geometry ) {
M
Mr.doob 已提交
324

325 326 327
		var nvertices = geometry.vertices.length;

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

330
		geometry.__webGLLineCount = nvertices;
M
Mr.doob 已提交
331

332
	};
M
Mr.doob 已提交
333

334
	function initRibbonBuffers ( geometry ) {
A
alteredq 已提交
335 336 337 338 339 340 341 342 343

		var nvertices = geometry.vertices.length;

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

		geometry.__webGLVertexCount = nvertices;

	};
344

345
	function initParticleBuffers ( geometry ) {
346 347 348 349

		var nvertices = geometry.vertices.length;

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

352
		geometry.__sortArray = [];
353 354 355 356 357

		geometry.__webGLParticleCount = nvertices;

	};

358
	function initMeshBuffers ( geometryGroup, object ) {
M
Mr.doob 已提交
359

M
Mikael Emtinger 已提交
360
		var f, fl, fi, face,
361 362 363 364 365 366 367 368 369 370
		
			nvertices = 0, ntris = 0, nlines = 0,
			
			uvType,
			vertexColorType,
			normalType,
			materials,
		
			geometry = object.geometry,
			obj_faces = geometry.faces,
371
			chunk_faces = geometryGroup.faces;
M
Mr.doob 已提交
372

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

375 376
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
M
Mr.doob 已提交
377

378
			if ( face instanceof THREE.Face3 ) {
M
Mr.doob 已提交
379

380 381 382
				nvertices += 3;
				ntris += 1;
				nlines += 3;
M
Mr.doob 已提交
383

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

386 387
				nvertices += 4;
				ntris += 2;
388
				nlines += 4;
M
Mr.doob 已提交
389

390
			}
M
Mr.doob 已提交
391

392
		}
393
		
A
alteredq 已提交
394
		materials = unrollGroupMaterials( geometryGroup, object );		
395 396 397
		
		uvType = bufferGuessUVType( materials, geometryGroup, object );
		normalType = bufferGuessNormalType( materials, geometryGroup, object );
A
alteredq 已提交
398 399
		vertexColorType = bufferGuessVertexColorType( materials, geometryGroup, object );

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

402 403 404
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
		
		if ( normalType ) {
M
Mr.doob 已提交
405

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

408 409 410 411 412
		}
		
		if ( geometry.hasTangents ) {
		
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
413

414 415 416 417 418
		}
		
		if ( vertexColorType ) {
		
			geometryGroup.__colorArray = new Float32Array( nvertices * 3 );
M
Mr.doob 已提交
419

420
		}
M
Mr.doob 已提交
421

422
		if ( uvType ) {
A
alteredq 已提交
423
			
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446
			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 );

		}

M
Mikael Emtinger 已提交
447
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 + ( object.geometry.edgeFaces ? object.geometry.edgeFaces.length * 2 * 3 : 0 ));
448
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
449

450
		if( geometryGroup.numMorphTargets ) {
451
			
452 453
			var m, ml;
			geometryGroup.__morphTargetsArrays = []; 
454
			
455
			for( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m++ ) {
456
				
457
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ));
458 459 460
			}

		}
461 462 463 464 465 466 467
		
		geometryGroup.__needsSmoothNormals = ( normalType == THREE.SmoothShading );
		
		geometryGroup.__uvType = uvType;
		geometryGroup.__vertexColorType = vertexColorType;
		geometryGroup.__normalType = normalType;

M
Mikael Emtinger 已提交
468
		geometryGroup.__webGLFaceCount = ntris * 3 + ( object.geometry.edgeFaces ? object.geometry.edgeFaces.length * 2 * 3 : 0 );
469
		geometryGroup.__webGLLineCount = nlines * 2;		
470

471
	};
M
Mr.doob 已提交
472

473
	function setMeshBuffers ( geometryGroup, object, hint ) {
474

475 476 477
		var f, fl, fi, face, 
			vertexNormals, faceNormal, normal,
			vertexColors, faceColor,
478
			vertexTangents,
A
alteredq 已提交
479
			uvType, vertexColorType, normalType,
480
			uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4,
481
			c1, c2, c3, c4,
A
alteredq 已提交
482 483 484 485
			sw1, sw2, sw3, sw4,
			si1, si2, si3, si4,
			sa1, sa2, sa3, sa4,
			sb1, sb2, sb3, sb4,
486
			m, ml, i,
487
			vn, uvi, uv2i,
488
			vk, vkl, vka,
M
Mr.doob 已提交
489

490
		vertexIndex = 0,
491

492 493
		offset = 0,
		offset_uv = 0,
494
		offset_uv2 = 0,
495 496 497 498
		offset_face = 0,
		offset_normal = 0,
		offset_tangent = 0,
		offset_line = 0,
499
		offset_color = 0,
A
alteredq 已提交
500
		offset_skin = 0,
501
		offset_morphTarget = 0,
M
Mr.doob 已提交
502

503 504 505 506 507 508
		vertexArray = geometryGroup.__vertexArray,
		uvArray = geometryGroup.__uvArray,
		uv2Array = geometryGroup.__uv2Array,
		normalArray = geometryGroup.__normalArray,
		tangentArray = geometryGroup.__tangentArray,
		colorArray = geometryGroup.__colorArray,
509

510 511 512 513
		skinVertexAArray = geometryGroup.__skinVertexAArray,
		skinVertexBArray = geometryGroup.__skinVertexBArray,
		skinIndexArray = geometryGroup.__skinIndexArray,
		skinWeightArray = geometryGroup.__skinWeightArray,
M
Mr.doob 已提交
514

515 516
		morphTargetsArrays = geometryGroup.__morphTargetsArrays,

517 518
		faceArray = geometryGroup.__faceArray,
		lineArray = geometryGroup.__lineArray,
M
Mr.doob 已提交
519

520
		needsSmoothNormals = geometryGroup.__needsSmoothNormals,
521 522
		
		vertexColorType = geometryGroup.__vertexColorType,
A
alteredq 已提交
523 524
		uvType = geometryGroup.__uvType,
		normalType = geometryGroup.__normalType,
525

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

528
		dirtyVertices = geometry.__dirtyVertices,
529 530 531
		dirtyElements = geometry.__dirtyElements,
		dirtyUvs = geometry.__dirtyUvs,
		dirtyNormals = geometry.__dirtyNormals,
532
		dirtyTangents = geometry.__dirtyTangents,
533
		dirtyColors = geometry.__dirtyColors,
534
		dirtyMorphTargets = geometry.__dirtyMorphTargets,
M
Mr.doob 已提交
535

536
		vertices = geometry.vertices,
537
		chunk_faces = geometryGroup.faces,
538
		obj_faces = geometry.faces,
539 540 541 542
		
		obj_uvs  = geometry.faceVertexUvs[ 0 ],
		obj_uvs2 = geometry.faceVertexUvs[ 1 ],
		
A
alteredq 已提交
543
		obj_colors = geometry.colors,
544

A
alteredq 已提交
545 546 547
		obj_skinVerticesA = geometry.skinVerticesA,
		obj_skinVerticesB = geometry.skinVerticesB,
		obj_skinIndices = geometry.skinIndices,
548
		obj_skinWeights = geometry.skinWeights,
M
Mikael Emtinger 已提交
549
		obj_edgeFaces = geometry.edgeFaces,
550 551 552

		morphTargets = geometry.morphTargets;
		
553

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

556 557
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
A
alteredq 已提交
558 559 560 561 562 563 564 565 566 567 568 569
			
			if( obj_uvs ) {

				uv = obj_uvs[ fi ];

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

			}
M
Mr.doob 已提交
570

571
			vertexNormals = face.vertexNormals;
572
			faceNormal = face.normal;
573 574 575
			
			vertexColors = face.vertexColors;
			faceColor = face.color;
576 577
			
			vertexTangents = face.vertexTangents;
578 579 580

			if ( face instanceof THREE.Face3 ) {

581
				if ( dirtyVertices ) {
M
Mr.doob 已提交
582

583 584 585
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
M
Mr.doob 已提交
586

587 588 589
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
590

591 592 593
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
594

595 596 597
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
M
Mr.doob 已提交
598

599
					offset += 9;
M
Mr.doob 已提交
600

601
				}
602

603
				if ( dirtyMorphTargets ) {
604
					
605
					for( vk = 0, vkl = morphTargets.length; vk < vkl; vk++ ) {
606
						
607 608 609
						v1 = morphTargets[ vk ].vertices[ face.a ].position;
						v2 = morphTargets[ vk ].vertices[ face.b ].position;
						v3 = morphTargets[ vk ].vertices[ face.c ].position;
610

611
						vka = morphTargetsArrays[ vk ];
612
	
613 614 615
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
616
	
617 618 619
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
620
	
621 622 623
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
624 625
					}

626
					offset_morphTarget += 9;
627 628 629
					
				}

A
alteredq 已提交
630 631 632
				if ( obj_skinWeights.length ) {

					// weights
633

A
alteredq 已提交
634 635 636
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
637

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

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

A
alteredq 已提交
676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695
					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
696

A
alteredq 已提交
697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716
					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;
717

A
alteredq 已提交
718
				}
719

720 721 722
				if ( dirtyColors && vertexColorType ) {

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

724 725 726 727 728 729 730 731 732 733 734
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];

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

					}
735 736 737 738 739 740 741 742 743 744 745 746

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

748 749 750 751
					offset_color += 9;

				}

752
				if ( dirtyTangents && geometry.hasTangents ) {
753

754 755 756
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
757

758 759 760 761
					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 已提交
762

763 764 765 766
					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 已提交
767

768 769 770 771
					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 已提交
772

773
					offset_tangent += 12;
M
Mr.doob 已提交
774

775 776
				}

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

779 780 781
					if ( vertexNormals.length == 3 && needsSmoothNormals ) {

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

783
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
784

785 786 787
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
788

789
							offset_normal += 3;
M
Mr.doob 已提交
790

791
						}
M
Mr.doob 已提交
792

793
					} else {
794

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

797 798 799
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
800

801
							offset_normal += 3;
M
Mr.doob 已提交
802

803
						}
M
Mr.doob 已提交
804 805

					}
M
Mr.doob 已提交
806

807 808
				}

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

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

813
						uvi = uv[ i ];
M
Mr.doob 已提交
814

815 816
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
817

818
						offset_uv += 2;
M
Mr.doob 已提交
819

M
Mr.doob 已提交
820
					}
821 822 823

				}

A
alteredq 已提交
824
				if ( dirtyUvs && uv2 !== undefined && uvType ) {
825 826 827 828 829 830 831 832 833 834 835 836 837 838

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

						uv2i = uv2[ i ];

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

						offset_uv2 += 2;

					}

				}

839
				if( dirtyElements ) {
M
Mr.doob 已提交
840

841 842 843
					faceArray[ offset_face ] = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
M
Mr.doob 已提交
844

845
					offset_face += 3;
M
Mr.doob 已提交
846

847 848
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
849

850 851
					lineArray[ offset_line + 2 ] = vertexIndex;
					lineArray[ offset_line + 3 ] = vertexIndex + 2;
M
Mr.doob 已提交
852

853 854
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
855

856
					offset_line += 6;
857

858
					vertexIndex += 3;
M
Mr.doob 已提交
859

860
				}
M
Mr.doob 已提交
861

862 863 864

			} else if ( face instanceof THREE.Face4 ) {

865
				if ( dirtyVertices ) {
M
Mr.doob 已提交
866

867 868 869 870
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
					v4 = vertices[ face.d ].position;
M
Mr.doob 已提交
871

872 873 874
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
875

876 877 878
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
879

880 881 882
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
883

884 885 886
					vertexArray[ offset + 9 ] = v4.x;
					vertexArray[ offset + 10 ] = v4.y;
					vertexArray[ offset + 11 ] = v4.z;
M
Mr.doob 已提交
887

888
					offset += 12;
M
Mr.doob 已提交
889

890
				}
891

892
				if ( dirtyMorphTargets ) {
893
					
894
					for( vk = 0, vkl = morphTargets.length; vk < vkl; vk++ ) {
895
						
896 897 898 899
						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;
900
	
901
						vka = morphTargetsArrays[ vk ];
902
	
903 904 905
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
906
	
907 908 909
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
910
	
911 912 913
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
914
	
915 916 917
						vka[ offset_morphTarget + 9 ] = v4.x;
						vka[ offset_morphTarget + 10 ] = v4.y;
						vka[ offset_morphTarget + 11 ] = v4.z;
918 919
					}

920
					offset_morphTarget += 12;
921 922 923
					
				}

A
alteredq 已提交
924 925 926
				if ( obj_skinWeights.length ) {

					// weights
927

A
alteredq 已提交
928 929 930 931
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
					sw4 = obj_skinWeights[ face.d ];
932

A
alteredq 已提交
933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953
					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
954

A
alteredq 已提交
955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980
					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
981

A
alteredq 已提交
982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007
					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
1008

A
alteredq 已提交
1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033
					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;

1034 1035
					offset_skin += 16;

A
alteredq 已提交
1036
				}
1037

1038 1039 1040
				if ( dirtyColors && vertexColorType ) {

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

1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];
						c4 = vertexColors[ 3 ];

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

					}
1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066

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

1068 1069 1070
					colorArray[ offset_color + 9 ]  = c4.r;
					colorArray[ offset_color + 10 ] = c4.g;
					colorArray[ offset_color + 11 ] = c4.b;
1071

1072 1073
					offset_color += 12;

1074 1075
				}

1076
				if ( dirtyTangents && geometry.hasTangents ) {
1077

1078 1079 1080 1081
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
					t4 = vertexTangents[ 3 ];
1082

1083 1084 1085 1086
					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 已提交
1087

1088 1089 1090 1091
					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 已提交
1092

1093 1094 1095 1096
					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 已提交
1097

1098 1099 1100 1101
					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 已提交
1102

1103
					offset_tangent += 16;
M
Mr.doob 已提交
1104

1105
				}
M
Mr.doob 已提交
1106

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

1109
					if ( vertexNormals.length == 4 && needsSmoothNormals ) {
1110

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

1113
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
1114

1115 1116 1117
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
1118

1119
							offset_normal += 3;
M
Mr.doob 已提交
1120

1121
						}
M
Mr.doob 已提交
1122

1123
					} else {
1124

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

1127 1128 1129
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1130

1131
							offset_normal += 3;
M
Mr.doob 已提交
1132

1133
						}
M
Mr.doob 已提交
1134 1135

					}
M
Mr.doob 已提交
1136

1137 1138
				}

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

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

1143
						uvi = uv[ i ];
M
Mr.doob 已提交
1144

1145 1146
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1147

1148
						offset_uv += 2;
M
Mr.doob 已提交
1149

M
Mr.doob 已提交
1150
					}
1151 1152

				}
1153

A
alteredq 已提交
1154
				if ( dirtyUvs && uv2 !== undefined && uvType ) {
1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167

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

1169
				if ( dirtyElements ) {
M
Mr.doob 已提交
1170

1171
					faceArray[ offset_face ]     = vertexIndex;
1172 1173
				   faceArray[ offset_face + 1 ] = vertexIndex + 1;
				   faceArray[ offset_face + 2 ] = vertexIndex + 3;
M
Mr.doob 已提交
1174

1175 1176 1177
				   faceArray[ offset_face + 3 ] = vertexIndex + 1;
				   faceArray[ offset_face + 4 ] = vertexIndex + 2;
				   faceArray[ offset_face + 5 ] = vertexIndex + 3;
M
Mr.doob 已提交
1178

1179
					offset_face += 6;
M
Mr.doob 已提交
1180

1181 1182
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
1183

1184
					lineArray[ offset_line + 2 ] = vertexIndex;
1185
					lineArray[ offset_line + 3 ] = vertexIndex + 3;
M
Mr.doob 已提交
1186

1187 1188
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
1189

1190 1191
					lineArray[ offset_line + 6 ] = vertexIndex + 2;
					lineArray[ offset_line + 7 ] = vertexIndex + 3;
M
Mr.doob 已提交
1192

1193
					offset_line += 8;
M
Mr.doob 已提交
1194

1195
					vertexIndex += 4;
M
Mr.doob 已提交
1196

1197
				}
M
Mr.doob 已提交
1198

1199
			}
M
Mr.doob 已提交
1200

1201 1202
		}

M
Mikael Emtinger 已提交
1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220
		if( obj_edgeFaces ) {
			
			for( f = 0, fl = obj_edgeFaces.length; f < fl; f++ ) {
				
				faceArray[ offset_face ]     = obj_edgeFaces[ f ].a;
				faceArray[ offset_face + 1 ] = obj_edgeFaces[ f ].b;
				faceArray[ offset_face + 2 ] = obj_edgeFaces[ f ].c;

				faceArray[ offset_face + 3 ] = obj_edgeFaces[ f ].a;
				faceArray[ offset_face + 4 ] = obj_edgeFaces[ f ].c;
				faceArray[ offset_face + 5 ] = obj_edgeFaces[ f ].d;

				offset_face += 6;
			}
			
		}


1221
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1222

1223
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
1224
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1225

1226
		}
M
Mr.doob 已提交
1227

1228
		if ( dirtyMorphTargets ) {
1229
			
1230
			for( vk = 0, vkl = morphTargets.length; vk < vkl; vk++ ) {
1231
		
1232 1233
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLMorphTargetsBuffers[ vk ] );
				_gl.bufferData( _gl.ARRAY_BUFFER, morphTargetsArrays[ vk ], hint );
1234 1235 1236 1237
				
			}
		}

1238
		if ( dirtyColors && offset_color > 0 ) {
1239

1240
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLColorBuffer );
1241 1242 1243
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}
1244

1245
		if ( dirtyNormals ) {
M
Mr.doob 已提交
1246

1247
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLNormalBuffer );
1248
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
1249

1250 1251
		}

1252
		if ( dirtyTangents && geometry.hasTangents ) {
1253

1254
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLTangentBuffer );
1255
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
M
Mr.doob 已提交
1256

1257
		}
1258

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

1261
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUVBuffer );
1262
			_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
M
Mr.doob 已提交
1263

1264
		}
M
Mr.doob 已提交
1265

1266 1267
		if ( dirtyUvs && offset_uv2 > 0 ) {

1268
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUV2Buffer );
1269 1270 1271 1272
			_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );

		}

1273
		if ( dirtyElements ) {
M
Mr.doob 已提交
1274

1275
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLFaceBuffer );
1276
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
1277

1278
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLLineBuffer );
1279
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
M
Mr.doob 已提交
1280

1281
		}
1282

1283
		if ( offset_skin > 0 ) {
1284

1285
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexABuffer );
A
alteredq 已提交
1286 1287
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );

1288
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexBBuffer );
A
alteredq 已提交
1289 1290
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );

1291
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinIndicesBuffer );
A
alteredq 已提交
1292 1293
			_gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );

1294
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinWeightsBuffer );
A
alteredq 已提交
1295
			_gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
1296

A
alteredq 已提交
1297
		}
1298 1299

	};
1300

1301
	function setLineBuffers ( geometry, hint ) {
M
Mr.doob 已提交
1302

1303
		var v, c, vertex, offset,
1304
			vertices = geometry.vertices,
1305
			colors = geometry.colors,
1306
			vl = vertices.length,
1307
			cl = colors.length,
M
Mr.doob 已提交
1308 1309

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

			dirtyVertices = geometry.__dirtyVertices,
1313
			dirtyColors = geometry.__dirtyColors;
M
Mr.doob 已提交
1314

1315
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1316

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

1319
				vertex = vertices[ v ].position;
M
Mr.doob 已提交
1320

1321
				offset = v * 3;
M
Mr.doob 已提交
1322

1323 1324 1325
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
M
Mr.doob 已提交
1326

1327 1328
			}

A
alteredq 已提交
1329 1330 1331
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

1332
		}
M
Mr.doob 已提交
1333

1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352
		if ( dirtyColors ) {

			for ( c = 0; c < cl; c++ ) {

				color = colors[ c ];

				offset = c * 3;

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

			}

			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLColorBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

1353
	};
M
Mr.doob 已提交
1354

1355
	function setRibbonBuffers ( geometry, hint ) {
A
alteredq 已提交
1356 1357 1358 1359 1360 1361 1362 1363 1364

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

			vertexArray = geometry.__vertexArray,
			colorArray = geometry.__colorArray,
1365 1366

			dirtyVertices = geometry.__dirtyVertices,
A
alteredq 已提交
1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407
			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 );

		}

	};
1408

1409
	function setParticleBuffers ( geometry, hint, object ) {
1410

A
alteredq 已提交
1411
		var v, c, vertex, offset,
1412 1413 1414
			vertices = geometry.vertices,
			vl = vertices.length,

A
alteredq 已提交
1415 1416
			colors = geometry.colors,
			cl = colors.length,
1417

1418
			vertexArray = geometry.__vertexArray,
A
alteredq 已提交
1419
			colorArray = geometry.__colorArray,
1420

1421
			sortArray = geometry.__sortArray,
1422

1423 1424 1425
			dirtyVertices = geometry.__dirtyVertices,
			dirtyElements = geometry.__dirtyElements,
			dirtyColors = geometry.__dirtyColors;
1426

1427
		if ( object.sortParticles ) {
1428

1429
			_projScreenMatrix.multiplySelf( object.matrixWorld );
1430

1431 1432 1433
			for ( v = 0; v < vl; v++ ) {

				vertex = vertices[ v ].position;
1434

1435 1436
				_vector3.copy( vertex );
				_projScreenMatrix.multiplyVector3( _vector3 );
1437

1438
				sortArray[ v ] = [ _vector3.z, v ];
1439

1440
			}
1441

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

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

1446
				vertex = vertices[ sortArray[v][1] ].position;
1447

1448
				offset = v * 3;
1449

1450 1451 1452
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
1453

1454
			}
1455

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

A
alteredq 已提交
1458
				offset = c * 3;
1459

A
alteredq 已提交
1460 1461 1462 1463 1464
				color = colors[ sortArray[c][1] ];

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

1466
			}
1467 1468


1469
		} else {
1470

1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483
			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;

				}
1484 1485

			}
1486

A
alteredq 已提交
1487
			if ( dirtyColors ) {
1488

A
alteredq 已提交
1489 1490 1491 1492 1493 1494 1495 1496 1497 1498
				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;

1499
				}
1500

A
alteredq 已提交
1501
			}
1502 1503

		}
1504

A
alteredq 已提交
1505
		if ( dirtyVertices || object.sortParticles ) {
1506

A
alteredq 已提交
1507 1508
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
1509

A
alteredq 已提交
1510
		}
1511

A
alteredq 已提交
1512
		if ( dirtyColors || object.sortParticles ) {
1513

A
alteredq 已提交
1514 1515
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLColorBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
1516

A
alteredq 已提交
1517
		}
1518

1519
	};
M
Mr.doob 已提交
1520

1521
	function setMaterialShaders( material, shaders ) {
1522

1523
		material.uniforms = Uniforms.clone( shaders.uniforms );
1524 1525
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
1526

M
Mr.doob 已提交
1527
	};
1528

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

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

1534
		// pure color
A
alteredq 已提交
1535
		//uniforms.color.value.setHex( material.color.hex );
M
Mr.doob 已提交
1536

A
alteredq 已提交
1537 1538
		uniforms.opacity.value = material.opacity;
		uniforms.map.texture = material.map;
1539

1540
		uniforms.lightMap.texture = material.lightMap;
1541

1542
		uniforms.envMap.texture = material.envMap;
A
alteredq 已提交
1543
		uniforms.reflectivity.value = material.reflectivity;
1544
		uniforms.refractionRatio.value = material.refractionRatio;
A
alteredq 已提交
1545
		uniforms.combine.value = material.combine;
1546
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
1547

1548
	};
1549

1550
	function refreshUniformsLine ( uniforms, material ) {
1551

A
alteredq 已提交
1552 1553
		uniforms.diffuse.value.setRGB( material.color.r * material.opacity, material.color.g * material.opacity, material.color.b * material.opacity );
		uniforms.opacity.value = material.opacity;
1554 1555

	};
M
Mr.doob 已提交
1556

1557
	function refreshUniformsParticle ( uniforms, material ) {
1558

A
alteredq 已提交
1559 1560 1561
		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 已提交
1562
		uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
A
alteredq 已提交
1563
		uniforms.map.texture = material.map;
1564

A
alteredq 已提交
1565
	};
1566

1567
	function refreshUniformsFog ( uniforms, fog ) {
1568

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

A
alteredq 已提交
1571
		if ( fog instanceof THREE.Fog ) {
1572

A
alteredq 已提交
1573 1574
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
1575

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

A
alteredq 已提交
1578
			uniforms.fogDensity.value = fog.density;
1579 1580

		}
1581

1582 1583
	};

1584
	function refreshUniformsPhong ( uniforms, material ) {
M
Mr.doob 已提交
1585

A
alteredq 已提交
1586 1587 1588 1589 1590
		//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 已提交
1591

1592
	};
M
Mr.doob 已提交
1593 1594


1595
	function refreshUniformsLights ( uniforms, lights ) {
M
Mr.doob 已提交
1596

A
alteredq 已提交
1597 1598 1599 1600 1601 1602
		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 已提交
1603

A
alteredq 已提交
1604
	};
M
Mr.doob 已提交
1605

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

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

A
alteredq 已提交
1610
		if ( material instanceof THREE.MeshDepthMaterial ) {
1611

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

M
Mikael Emtinger 已提交
1614 1615 1616 1617
		} else if ( material instanceof THREE.ShadowVolumeDynamicMaterial ) {

			setMaterialShaders( material, THREE.ShaderLib[ 'shadowVolumeDynamic' ] );

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

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

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

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

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

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

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

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

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

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

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

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

A
alteredq 已提交
1642
		}
1643

1644
		if ( ! material.program ) {
M
Mr.doob 已提交
1645

1646 1647
			// heuristics to create shader parameters according to lights in the scene
			// (not to blow over maxLights budget)
M
Mr.doob 已提交
1648

1649
			maxLightCount = allocateLights( lights, 4 );
1650

1651
			maxBones = allocateBones( object );
M
Mr.doob 已提交
1652

1653 1654 1655 1656 1657 1658
			parameters = { fog: fog, map: material.map, envMap: material.envMap, lightMap: material.lightMap, vertexColors: material.vertexColors,
						   sizeAttenuation: material.sizeAttenuation,
						   skinning: material.skinning,
						   morphTargets: material.morphTargets,
						   maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
						   maxBones: maxBones };
M
Mikael Emtinger 已提交
1659

1660
			material.program = buildProgram( material.fragmentShader, material.vertexShader, parameters );
M
Mikael Emtinger 已提交
1661

1662
			// load uniforms
A
alteredq 已提交
1663

1664 1665 1666
			identifiers = [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
							'cameraInverseMatrix', 'boneGlobalMatrices', 'morphTargetInfluences'
							];
M
Mikael Emtinger 已提交
1667

1668

1669
			for( u in material.uniforms ) {
M
Mr.doob 已提交
1670

1671 1672
				identifiers.push(u);
			}
M
Mikael Emtinger 已提交
1673

1674
			cacheUniformLocations( material.program, identifiers );
1675

1676

1677
			// load attributes
1678

1679 1680
			identifiers = [ "position", "normal", "uv", "uv2", "tangent", "color",
						    "skinVertexA", "skinVertexB", "skinIndex", "skinWeight" ];
1681

1682
			for ( i = 0; i < this.maxMorphTargets; i++ ) {
1683

1684 1685
				identifiers.push( "morphTarget" + i );
			}
1686

1687
			for ( a in material.attributes ) {
1688

1689
				identifiers.push( a );
1690
			}
1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736

			cacheAttributeLocations( material.program, identifiers );


			var attributes = material.program.attributes;

			_gl.enableVertexAttribArray( attributes.position );

			if ( attributes.color >= 0 ) 	_gl.enableVertexAttribArray( attributes.color );
			if ( attributes.normal >= 0 ) 	_gl.enableVertexAttribArray( attributes.normal );
			if ( attributes.tangent >= 0 ) 	_gl.enableVertexAttribArray( attributes.tangent );

			if ( material.skinning &&
				 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
				 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {

				_gl.enableVertexAttribArray( attributes.skinVertexA );
				_gl.enableVertexAttribArray( attributes.skinVertexB );
				_gl.enableVertexAttribArray( attributes.skinIndex );
				_gl.enableVertexAttribArray( attributes.skinWeight );

			}

			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++ }

				object.__webGLMorphTargetInfluences = new Float32Array( this.maxMorphTargets );

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

					object.__webGLMorphTargetInfluences[ i ] = 0;

				}

			}

1737
		}
M
Mr.doob 已提交
1738

1739 1740
		material.__webglProgram = true;

1741
	};
1742

1743
	function setProgram( camera, lights, fog, material, object ) {
1744

1745 1746 1747 1748 1749
		if ( ! material.__webglProgram ) {

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

		}
M
Mr.doob 已提交
1750

1751
		var program = material.program,
A
alteredq 已提交
1752 1753
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
1754

M
Mr.doob 已提交
1755
		if( program != _oldProgram ) {
M
Mr.doob 已提交
1756

M
Mr.doob 已提交
1757 1758
			_gl.useProgram( program );
			_oldProgram = program;
1759

M
Mr.doob 已提交
1760
		}
1761

1762 1763
		_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );

A
alteredq 已提交
1764
		// refresh uniforms common to several materials
1765 1766

		if ( fog && (
A
alteredq 已提交
1767 1768
			 material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
1769
			 material instanceof THREE.MeshPhongMaterial ||
A
alteredq 已提交
1770 1771 1772
			 material instanceof THREE.LineBasicMaterial ||
			 material instanceof THREE.ParticleBasicMaterial )
			) {
1773

A
alteredq 已提交
1774
			refreshUniformsFog( m_uniforms, fog );
1775 1776

		}
M
Mr.doob 已提交
1777

M
Mr.doob 已提交
1778
		if ( material instanceof THREE.MeshPhongMaterial ||
1779 1780
			 material instanceof THREE.MeshLambertMaterial ||
			 material.lights ) {
1781

A
alteredq 已提交
1782
			setupLights( program, lights );
A
alteredq 已提交
1783
			refreshUniformsLights( m_uniforms, _lights );
M
Mr.doob 已提交
1784 1785 1786

		}

1787 1788 1789
		if ( material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
			 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
1790

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

A
alteredq 已提交
1793
		}
M
Mr.doob 已提交
1794

A
alteredq 已提交
1795
		// refresh single material specific uniforms
1796

1797
		if ( material instanceof THREE.LineBasicMaterial ) {
M
Mr.doob 已提交
1798

A
alteredq 已提交
1799
			refreshUniformsLine( m_uniforms, material );
1800

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

A
alteredq 已提交
1803
			refreshUniformsParticle( m_uniforms, material );
1804

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

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

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

1811 1812
			m_uniforms.mNear.value = camera.near;
			m_uniforms.mFar.value = camera.far;
A
alteredq 已提交
1813
			m_uniforms.opacity.value = material.opacity;
1814

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

A
alteredq 已提交
1817
			m_uniforms.opacity.value = material.opacity;
1818
		}
1819

A
alteredq 已提交
1820
		// load common uniforms
1821

A
alteredq 已提交
1822 1823
		loadUniformsGeneric( program, m_uniforms );
		loadUniformsMatrices( p_uniforms, object );
1824

A
alteredq 已提交
1825 1826
		// load material specific uniforms
		// (shader material also gets them for the sake of genericity)
1827

A
alteredq 已提交
1828 1829
		if ( material instanceof THREE.MeshShaderMaterial ||
			 material instanceof THREE.MeshPhongMaterial ||
1830
			 material.envMap ) {
1831

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

1834
		}
1835

A
alteredq 已提交
1836
		if ( material instanceof THREE.MeshShaderMaterial ||
1837
			 material.envMap ||
1838
			 material.skinning ) {
1839

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

A
alteredq 已提交
1842
		}
1843

A
alteredq 已提交
1844 1845
		if ( material instanceof THREE.MeshPhongMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
A
alteredq 已提交
1846
			 material instanceof THREE.MeshShaderMaterial ||
1847 1848
			 material.skinning ) {

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

A
alteredq 已提交
1851
		}
1852

M
Mikael Emtinger 已提交
1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866
		if( material instanceof THREE.ShadowVolumeDynamicMaterial ) {
			
			var dirLight = m_uniforms.directionalLightDirection.value;
			
			dirLight[ 0 ] = -lights.position.x;
			dirLight[ 1 ] = -lights.position.y;
			dirLight[ 2 ] = -lights.position.z;
			
			_gl.uniform3fv( p_uniforms.directionalLightDirection, dirLight );
			_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
			_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
		}


1867
		if ( material.skinning ) {
1868

1869
			loadUniformsSkinning( p_uniforms, object );
1870

A
alteredq 已提交
1871
		}
1872
		
A
alteredq 已提交
1873
		return program;
1874

A
alteredq 已提交
1875
	};
1876

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

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

A
alteredq 已提交
1881 1882
		var program, attributes, linewidth, primitives;

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

1885
		attributes = program.attributes;
M
Mr.doob 已提交
1886

1887
		// vertices
M
Mr.doob 已提交
1888

1889
		if ( !material.morphTargets ) {
1890 1891 1892 1893 1894
			
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
			
		} else {
M
Mikael Emtinger 已提交
1895 1896
		
			setupMorphTargets( material, geometryGroup, object );
1897 1898 1899
			
		}

A
alteredq 已提交
1900 1901 1902 1903
		// colors

		if ( attributes.color >= 0 ) {

1904
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLColorBuffer );
1905
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
1906 1907 1908

		}

1909
		// normals
M
Mr.doob 已提交
1910

1911
		if ( attributes.normal >= 0 ) {
1912

1913
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLNormalBuffer );
1914
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
1915

1916
		}
1917

1918 1919 1920
		// tangents

		if ( attributes.tangent >= 0 ) {
1921

1922
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLTangentBuffer );
1923
			_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
1924

1925
		}
1926

1927
		// uvs
M
Mr.doob 已提交
1928

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

1931
			if ( geometryGroup.__webGLUVBuffer ) {
1932

1933
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUVBuffer );
1934
				_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
1935

1936
				_gl.enableVertexAttribArray( attributes.uv );
1937

1938
			} else {
1939

1940
				_gl.disableVertexAttribArray( attributes.uv );
M
Mr.doob 已提交
1941

1942
			}
1943 1944 1945

		}

1946 1947
		if ( attributes.uv2 >= 0 ) {

1948
			if ( geometryGroup.__webGLUV2Buffer ) {
1949

1950
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUV2Buffer );
1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962
				_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );

				_gl.enableVertexAttribArray( attributes.uv2 );

			} else {

				_gl.disableVertexAttribArray( attributes.uv2 );

			}

		}

1963
		if ( material.skinning &&
1964
			 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
A
alteredq 已提交
1965
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
1966

1967
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexABuffer );
A
alteredq 已提交
1968 1969
			_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );

1970
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexBBuffer );
A
alteredq 已提交
1971 1972
			_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );

1973
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinIndicesBuffer );
A
alteredq 已提交
1974 1975
			_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );

1976
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinWeightsBuffer );
A
alteredq 已提交
1977
			_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
1978

A
alteredq 已提交
1979
		}
1980

1981
		// render mesh
M
Mr.doob 已提交
1982

1983
		if ( object instanceof THREE.Mesh ) {
1984

1985
			// wireframe
1986

1987
			if ( material.wireframe ) {
M
Mr.doob 已提交
1988

1989
				_gl.lineWidth( material.wireframeLinewidth );
1990 1991
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webGLLineCount, _gl.UNSIGNED_SHORT, 0 );
1992

1993
			// triangles
1994

1995
			} else {
1996

1997 1998
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
1999
			}
2000

2001
		// render lines
2002

2003
		} else if ( object instanceof THREE.Line ) {
2004

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

2007
			_gl.lineWidth( material.linewidth );
2008
			_gl.drawArrays( primitives, 0, geometryGroup.__webGLLineCount );
2009

2010
		// render particles
2011

2012
		} else if ( object instanceof THREE.ParticleSystem ) {
2013

2014
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webGLParticleCount );
2015

A
alteredq 已提交
2016
		// render ribbon
2017

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

2020
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webGLVertexCount );
2021

2022 2023 2024 2025
		}

	};

M
Mikael Emtinger 已提交
2026

M
Mikael Emtinger 已提交
2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109
	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 );
	}


2110
	function renderBufferImmediate ( object, program ) {
2111

A
alteredq 已提交
2112 2113
		if ( ! object.__webGLVertexBuffer ) object.__webGLVertexBuffer = _gl.createBuffer();
		if ( ! object.__webGLNormalBuffer ) object.__webGLNormalBuffer = _gl.createBuffer();
2114

A
alteredq 已提交
2115
		if ( object.hasPos ) {
2116

A
alteredq 已提交
2117 2118 2119 2120
		  _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 );
2121

A
alteredq 已提交
2122
		}
2123

A
alteredq 已提交
2124
		if ( object.hasNormal ) {
2125

A
alteredq 已提交
2126 2127 2128 2129
		  _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 );
2130

A
alteredq 已提交
2131
		}
2132

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

A
alteredq 已提交
2135
		object.count = 0;
2136

A
alteredq 已提交
2137
	};
2138

2139
	function setObjectFaces ( object ) {
2140

2141
		if ( _oldDoubleSided != object.doubleSided ) {
2142

2143
			if( object.doubleSided ) {
2144

2145
				_gl.disable( _gl.CULL_FACE );
2146

2147
			} else {
2148

A
alteredq 已提交
2149
				_gl.enable( _gl.CULL_FACE );
2150

A
alteredq 已提交
2151
			}
2152

2153
			_oldDoubleSided = object.doubleSided;
2154

2155
		}
2156

2157
		if ( _oldFlipSided != object.flipSided ) {
2158

2159 2160 2161 2162
			if( object.flipSided ) {

				_gl.frontFace( _gl.CW );

2163
			} else {
2164 2165 2166 2167

				_gl.frontFace( _gl.CCW );

			}
2168

2169
			_oldFlipSided = object.flipSided;
2170 2171

		}
2172

2173
	};
2174

2175
	function setDepthTest ( test ) {
2176

A
alteredq 已提交
2177 2178 2179
		if ( _oldDepth != test ) {

			if( test ) {
2180

A
alteredq 已提交
2181
				_gl.enable( _gl.DEPTH_TEST );
2182

A
alteredq 已提交
2183
			} else {
2184

A
alteredq 已提交
2185
				_gl.disable( _gl.DEPTH_TEST );
2186

A
alteredq 已提交
2187
			}
2188

A
alteredq 已提交
2189 2190 2191
			_oldDepth = test;

		}
2192

A
alteredq 已提交
2193
	};
2194

2195
	function computeFrustum ( m ) {
2196 2197 2198 2199 2200 2201 2202 2203 2204

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

A
alteredq 已提交
2206
		for ( i = 0; i < 6; i ++ ) {
2207 2208 2209 2210 2211 2212 2213

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

		}

	};
2214

2215
	function isInFrustum ( object ) {
2216

2217
		var distance, matrix = object.matrixWorld,
2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229
		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;

	};
2230

2231
	function addToFixedArray ( where, what ) {
2232

2233 2234
		where.list[ where.count ] = what;
		where.count += 1;
2235

2236
	};
2237

2238
	function unrollImmediateBufferMaterials ( globject ) {
2239

2240 2241 2242 2243 2244 2245 2246
		var i, l, m, ml, material,
			object = globject.object,
			opaque = globject.opaque,
			transparent = globject.transparent;

		transparent.count = 0;
		opaque.count = 0;
2247

2248 2249 2250
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

			material = object.materials[ m ];
2251

2252 2253 2254 2255
			if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending )
				addToFixedArray( transparent, material );
			else
				addToFixedArray( opaque, material );
2256

2257
		}
2258

2259
	};
2260

2261
	function unrollBufferMaterials ( globject ) {
2262

2263 2264 2265 2266 2267 2268 2269 2270
		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;
2271

2272 2273 2274 2275 2276 2277 2278 2279 2280
		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 ];
2281

2282
					if ( material ) {
2283

2284 2285 2286 2287
						if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending )
							addToFixedArray( transparent, material );
						else
							addToFixedArray( opaque, material );
2288

2289 2290 2291 2292 2293 2294 2295
					}

				}

			} else {

				material = meshMaterial;
2296

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

2299
					addToFixedArray( transparent, material );
2300 2301 2302

				} else {

2303 2304
					addToFixedArray( opaque, material );

2305 2306
				}

2307 2308 2309
			}

		}
2310

2311
	};
2312 2313


2314
	function painterSort ( a, b ) {
2315

2316
		return b.z - a.z;
2317 2318

	};
2319

2320
	this.render = function ( scene, camera, renderTarget, forceClear ) {
2321

A
alteredq 已提交
2322
		var i, program, opaque, transparent, material,
2323
			o, ol, oil, webglObject, object, buffer,
A
alteredq 已提交
2324
			lights = scene.lights,
N
Nicholas Kinsey 已提交
2325
			fog = scene.fog;
2326

M
Mr.doob 已提交
2327
		camera.matrixAutoUpdate && camera.updateMatrix();
2328

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

M
Mr.doob 已提交
2331
		camera.matrixWorldInverse.flattenToArray( _viewMatrixArray );
2332
		camera.projectionMatrix.flattenToArray( _projectionMatrixArray );
M
Mr.doob 已提交
2333

M
Mr.doob 已提交
2334
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
2335
		computeFrustum( _projScreenMatrix );
2336

A
alteredq 已提交
2337
		this.initWebGLObjects( scene );
M
Mr.doob 已提交
2338

A
alteredq 已提交
2339
		setRenderTarget( renderTarget );
M
Mr.doob 已提交
2340

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

2343
			this.clear();
M
Mr.doob 已提交
2344

2345
		}
M
Mikael Emtinger 已提交
2346
		
2347

2348
		// set matrices
2349

2350
		ol = scene.__webglObjects.length;
2351

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

2354 2355
			webglObject = scene.__webglObjects[ o ];
			object = webglObject.object;
M
Mr.doob 已提交
2356

2357
			if ( object.visible ) {
2358 2359

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

2361
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
2362

2363
					setupMatrices( object, camera );
2364

2365
					unrollBufferMaterials( webglObject );
2366

2367
					webglObject.render = true;
2368

2369
					if ( this.sortObjects ) {
2370

2371 2372 2373
						_vector3.copy( object.position );
						_projScreenMatrix.multiplyVector3( _vector3 );

2374
						webglObject.z = _vector3.z;
2375

2376
					}
2377

2378
				} else {
2379

2380
					webglObject.render = false;
2381

2382
				}
2383

2384
			} else {
2385

2386
				webglObject.render = false;
2387

2388
			}
2389

2390
		}
2391

2392
		if ( this.sortObjects ) {
2393

2394
			scene.__webglObjects.sort( painterSort );
2395

2396
		}
2397

2398
		oil = scene.__webglObjectsImmediate.length;
2399

2400
		for ( o = 0; o < oil; o++ ) {
2401

2402 2403
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2404

2405
			if ( object.visible ) {
2406 2407 2408

				if( object.matrixAutoUpdate ) {

2409
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
2410

A
alteredq 已提交
2411
				}
2412

2413
				setupMatrices( object, camera );
2414

2415
				unrollImmediateBufferMaterials( webglObject );
2416

2417
			}
2418

2419
		}
A
alteredq 已提交
2420

2421 2422
		// opaque pass

2423
		setBlending( THREE.NormalBlending );
2424

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

2427
			webglObject = scene.__webglObjects[ o ];
2428

2429
			if ( webglObject.render ) {
2430

2431 2432 2433
				object = webglObject.object;
				buffer = webglObject.buffer;
				opaque = webglObject.opaque;
2434

2435
				setObjectFaces( object );
2436

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

2439
					material = opaque.list[ i ];
2440

2441
					setDepthTest( material.depthTest );
A
alteredq 已提交
2442
					renderBuffer( camera, lights, fog, material, buffer, object );
2443

2444
				}
2445 2446 2447 2448 2449

			}

		}

A
alteredq 已提交
2450
		// opaque pass (immediate simulator)
2451

2452
		for ( o = 0; o < oil; o++ ) {
2453

2454 2455
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2456

A
alteredq 已提交
2457
			if ( object.visible ) {
2458

2459
				opaque = webglObject.opaque;
2460

2461
				setObjectFaces( object );
2462

2463
				for( i = 0; i < opaque.count; i++ ) {
2464

2465
					material = opaque.list[ i ];
2466

2467
					setDepthTest( material.depthTest );
2468

A
alteredq 已提交
2469
					program = setProgram( camera, lights, fog, material, object );
2470
					object.render( function( object ) { renderBufferImmediate( object, program ); } );
2471

2472
				}
2473

A
alteredq 已提交
2474
			}
2475

A
alteredq 已提交
2476 2477
		}

2478 2479
		// transparent pass

2480
		for ( o = 0; o < ol; o++ ) {
2481

2482
			webglObject = scene.__webglObjects[ o ];
2483

2484
			if ( webglObject.render ) {
2485

2486 2487 2488
				object = webglObject.object;
				buffer = webglObject.buffer;
				transparent = webglObject.transparent;
2489

2490
				setObjectFaces( object );
2491

2492
				for( i = 0; i < transparent.count; i++ ) {
2493

2494
					material = transparent.list[ i ];
2495

2496
					setBlending( material.blending );
2497
					setDepthTest( material.depthTest );
2498

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

2501
				}
2502

2503
			}
M
Mr.doob 已提交
2504

M
Mr.doob 已提交
2505
		}
M
Mr.doob 已提交
2506

2507
		// transparent pass (immediate simulator)
2508

2509
		for ( o = 0; o < oil; o++ ) {
2510

2511 2512
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2513

2514
			if ( object.visible ) {
2515

2516
				transparent = webglObject.transparent;
2517

2518
				setObjectFaces( object );
2519

2520
				for( i = 0; i < transparent.count; i++ ) {
2521

2522
					material = transparent.list[ i ];
2523

2524
					setBlending( material.blending );
2525
					setDepthTest( material.depthTest );
2526

A
alteredq 已提交
2527
					program = setProgram( camera, lights, fog, material, object );
2528
					object.render( function( object ) { renderBufferImmediate( object, program ); } );
2529

2530
				}
2531

2532
			}
2533

2534
		}
2535

M
Mikael Emtinger 已提交
2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564


		//////////////////////// stencil shadows begin //////////////////////
		// method: we're rendering the world in light, then the shadow
		//         volumes into the stencil and last a big darkening 
		//         quad over the whole thing. This is NOT how you're
		//         supposed to do stencil shadows but is much faster
		//

		if( scene.__webglShadowVolumes.length && scene.lights.length ) {
			
			// setup stencil
	
			_gl.enable( _gl.POLYGON_OFFSET_FILL );
			_gl.polygonOffset( 0.1, 1.0 );
			_gl.enable( _gl.STENCIL_TEST );
			_gl.depthMask( false );
			_gl.colorMask( false, false, false, false );
		
			_gl.stencilFunc( _gl.ALWAYS, 1, 0xFF );
			_gl.stencilOpSeparate( _gl.BACK,  _gl.KEEP, _gl.INCR, _gl.KEEP );
			_gl.stencilOpSeparate( _gl.FRONT, _gl.KEEP, _gl.DECR, _gl.KEEP );
	
	
			
			// loop through all directional lights
			
			var l, ll = scene.lights.length;
			var p;
2565 2566 2567 2568 2569 2570
			var light, geometryGroup;
			var dirLight = [];			
			var	program;
			var p_uniforms;
		    var m_uniforms;
		    var attributes;
M
Mikael Emtinger 已提交
2571 2572 2573 2574 2575 2576 2577 2578
	
			ol = scene.__webglShadowVolumes.length;
			
			for( l = 0; l < ll; l++ ) {
				
				light = scene.lights[ l ];
				
				if( light instanceof THREE.DirectionalLight ) {
2579 2580 2581 2582 2583

					dirLight[ 0 ] = -light.position.x;
					dirLight[ 1 ] = -light.position.y;
					dirLight[ 2 ] = -light.position.z;

M
Mikael Emtinger 已提交
2584 2585 2586 2587 2588
					
					// render all volumes
					
					for ( o = 0; o < ol; o++ ) {
			
2589 2590 2591 2592 2593 2594
						object        = scene.__webglShadowVolumes[ o ].object;
						geometryGroup = scene.__webglShadowVolumes[ o ].buffer;
						material      = object.materials[ 0 ];


						if ( !material.program ) _this.initMaterial( material, lights, fog, object );
M
Mikael Emtinger 已提交
2595
	
2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618
						program = material.program,
			  			p_uniforms = program.uniforms,
		                m_uniforms = material.uniforms,
		                attributes = program.attributes;


						if( _oldProgram !== program ) {
							
							_gl.useProgram( program );
							_oldProgram = program;

							_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );
							_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
							_gl.uniform3fv( p_uniforms.directionalLightDirection, dirLight );
						}


						object.matrixWorld.flattenToArray( object._objectMatrixArray );
						//object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );

						_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
						//_gl.uniformMatrix4fv( p_uniforms.modelViewMatrix, false, object._modelViewMatrixArray );

M
Mikael Emtinger 已提交
2619
	
2620 2621 2622 2623 2624 2625 2626 2627
						_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
						_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );

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

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

M
Mikael Emtinger 已提交
2628
						_gl.cullFace( _gl.FRONT );
2629 2630 2631 2632
						_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );

						_gl.cullFace( _gl.BACK );
						_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
M
Mikael Emtinger 已提交
2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647
				
					}
	
				}
	
			}
	
	
			// draw darkening polygon	
	
			_gl.disable( _gl.POLYGON_OFFSET_FILL );
			_gl.colorMask( true, true, true, true );
			_gl.stencilFunc( _gl.NOTEQUAL, 0, 0xFF );
			_gl.stencilOp( _gl.KEEP, _gl.KEEP, _gl.KEEP );
		    _gl.disable( _gl.DEPTH_TEST );
2648
			
M
Mikael Emtinger 已提交
2649
			_gl.enable( _gl.BLEND );
2650 2651
			_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
			_gl.blendEquation( _gl.FUNC_ADD );
M
Mikael Emtinger 已提交
2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679
	
	
			_oldBlending = "";
			_oldProgram = _shadow.program;
	
			_gl.useProgram( _shadow.program );
			_gl.uniformMatrix4fv( _shadow.projectionLocation, false, _projectionMatrixArray );
			
			_gl.bindBuffer( _gl.ARRAY_BUFFER, _shadow.vertexBuffer );
			_gl.vertexAttribPointer( _shadow.vertexLocation, 3, _gl.FLOAT, false, 0, 0 );
			_gl.enableVertexAttribArray( _shadow.vertexLocation );
				
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _shadow.elementBuffer );
			_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
	
	
			// disable stencil
	
		    _gl.disable	 ( _gl.STENCIL_TEST );
		    _gl.enable	 ( _gl.DEPTH_TEST );
			_gl.disable  ( _gl.BLEND );
		    _gl.depthMask( true );
		}


		//////////////////////// stencil shadows end //////////////////////


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

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

2684
			updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
2685

2686
		}
2687

M
Mr.doob 已提交
2688
	};
M
Mr.doob 已提交
2689

2690
	function setupMatrices ( object, camera ) {
2691

2692 2693
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
		THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
2694

2695
	};
2696

A
alteredq 已提交
2697
	this.initWebGLObjects = function ( scene ) {
2698

2699
		if ( !scene.__webglObjects ) {
2700

2701 2702
			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
M
Mikael Emtinger 已提交
2703
			scene.__webglShadowVolumes = [];
2704 2705
		}

M
Mr.doob 已提交
2706
		while ( scene.__objectsAdded.length ) {
2707

M
Mr.doob 已提交
2708 2709
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
2710 2711 2712

		}

M
Mr.doob 已提交
2713
		while ( scene.__objectsRemoved.length ) {
2714

M
Mr.doob 已提交
2715 2716
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
2717 2718

		}
2719

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

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

M
Mr.doob 已提交
2724
			updateObject( scene.__webglObjects[ o ].object, scene );
A
alteredq 已提交
2725 2726

		}
M
Mikael Emtinger 已提交
2727 2728 2729 2730 2731 2732 2733
		
		for ( var o = 0, ol = scene.__webglShadowVolumes.length; o < ol; o ++ ) {

			updateObject( scene.__webglShadowVolumes[ o ].object, scene );

		}
		
A
alteredq 已提交
2734

2735
	};
2736

2737
	function addObject ( object, scene ) {
2738

2739
		var g, geometry, geometryGroup;
M
Mr.doob 已提交
2740

2741
		if ( object._modelViewMatrix == undefined ) {
2742

2743
			object._modelViewMatrix = new THREE.Matrix4();
2744

2745 2746 2747
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
2748

2749
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
2750

2751
		}
A
alteredq 已提交
2752

2753
		if ( object instanceof THREE.Mesh ) {
A
alteredq 已提交
2754

2755 2756 2757 2758 2759 2760 2761 2762
			geometry = object.geometry;

			if ( geometry.geometryGroups == undefined ) {

				sortFacesByMaterial( geometry );

			}

2763
			// create separate VBOs per geometry chunk
A
alteredq 已提交
2764

2765
			for ( g in geometry.geometryGroups ) {
A
alteredq 已提交
2766

2767
				geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
2768

2769
				// initialise VBO on the first access
M
Mr.doob 已提交
2770

2771
				if ( ! geometryGroup.__webGLVertexBuffer ) {
M
Mr.doob 已提交
2772

2773 2774
					createMeshBuffers( geometryGroup );
					initMeshBuffers( geometryGroup, object );
A
alteredq 已提交
2775

2776
					geometry.__dirtyVertices = true;
2777
					geometry.__dirtyMorphTargets = true;
2778 2779 2780 2781 2782
					geometry.__dirtyElements = true;
					geometry.__dirtyUvs = true;
					geometry.__dirtyNormals = true;
					geometry.__dirtyTangents = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
2783

2784
				}
2785

2786
				// create separate wrapper per each use of VBO
2787

M
Mikael Emtinger 已提交
2788 2789 2790 2791 2792 2793 2794 2795 2796
				if( object instanceof THREE.ShadowVolume ) {
					
					addBuffer( scene.__webglShadowVolumes, geometryGroup, object );
					
				} else {
					
					addBuffer( scene.__webglObjects, geometryGroup, object );
					
				}
2797
			}
M
Mr.doob 已提交
2798

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

2801 2802
			geometry = object.geometry;

A
alteredq 已提交
2803 2804 2805 2806 2807 2808 2809 2810 2811 2812
			if( ! geometry.__webGLVertexBuffer ) {

				createRibbonBuffers( geometry );
				initRibbonBuffers( geometry );

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

			}

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

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

2817 2818
			geometry = object.geometry;

2819
			if( ! geometry.__webGLVertexBuffer ) {
M
Mr.doob 已提交
2820

2821 2822
				createLineBuffers( geometry );
				initLineBuffers( geometry );
M
Mr.doob 已提交
2823

2824 2825
				geometry.__dirtyVertices = true;
				geometry.__dirtyColors = true;
M
Mr.doob 已提交
2826

2827
			}
M
Mr.doob 已提交
2828

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

A
alteredq 已提交
2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841
		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

			if ( ! geometry.__webGLVertexBuffer ) {

				createParticleBuffers( geometry );
				initParticleBuffers( geometry );

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

2843
			}
2844

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

A
alteredq 已提交
2847 2848 2849 2850 2851 2852 2853 2854 2855 2856
		} else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes ) {

			addBufferImmediate( scene.__webglObjectsImmediate, object );

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

		}*/

	};

2857
	function updateObject ( object, scene ) {
A
alteredq 已提交
2858

M
Mr.doob 已提交
2859
		var g, geometry, geometryGroup;
A
alteredq 已提交
2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870

		if ( object instanceof THREE.Mesh ) {

			geometry = object.geometry;

			// check all geometry groups

			for ( g in geometry.geometryGroups ) {

				geometryGroup = geometry.geometryGroups[ g ];

2871
				if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
A
alteredq 已提交
2872 2873 2874 2875 2876 2877 2878 2879 2880
					geometry.__dirtyUvs || geometry.__dirtyNormals ||
					geometry.__dirtyColors || geometry.__dirtyTangents ) {

					setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW );

				}

			}

2881
			geometry.__dirtyVertices = false;
2882
			geometry.__dirtyMorphTargets = false;
A
alteredq 已提交
2883 2884 2885 2886
			geometry.__dirtyElements = false;
			geometry.__dirtyUvs = false;
			geometry.__dirtyNormals = false;
			geometry.__dirtyTangents = false;
2887
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
2888

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

2891 2892
			geometry = object.geometry;

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

A
alteredq 已提交
2895
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
2896

A
alteredq 已提交
2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908
			}

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

2910
			}
2911

A
alteredq 已提交
2912 2913 2914 2915 2916 2917 2918
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

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

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

2923
			}
M
Mr.doob 已提交
2924

2925 2926
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
2927

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

A
alteredq 已提交
2930
			// it updates itself in render callback
2931 2932

		} else if ( object instanceof THREE.Particle ) {
2933 2934

		}*/
2935

2936
	};
2937

2938
	function removeObject ( object, scene ) {
M
Mr.doob 已提交
2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955

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

			}

		}

	};

2956
	function sortFacesByMaterial ( geometry ) {
2957 2958 2959 2960 2961 2962 2963

		// 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 = {};
2964
		var numMorphTargets = geometry.morphTargets !== undefined ? geometry.morphTargets.length : 0;
2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006

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

3007
				geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019

			}

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

3020
					geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032

				}

			}

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

		}

	};

3033
	function addBuffer ( objlist, buffer, object ) {
3034

3035 3036 3037 3038
		objlist.push( { buffer: buffer, object: object,
				opaque: { list: [], count: 0 },
				transparent: { list: [], count: 0 }
			} );
M
Mr.doob 已提交
3039

3040
	};
3041

3042
	function addBufferImmediate ( objlist, object ) {
3043

3044 3045 3046 3047
		objlist.push( { object: object,
				opaque: { list: [], count: 0 },
				transparent: { list: [], count: 0 }
			} );
3048

3049
	};
3050

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

3053
		if ( cullFace ) {
M
Mr.doob 已提交
3054

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

3057
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
3058

3059
			} else {
M
Mr.doob 已提交
3060

3061
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
3062

3063
			}
M
Mr.doob 已提交
3064

3065
			if( cullFace == "back" ) {
M
Mr.doob 已提交
3066

3067
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
3068

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

3071
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
3072

3073
			} else {
M
Mr.doob 已提交
3074

3075
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
3076

3077
			}
M
Mr.doob 已提交
3078

3079
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
3080

3081
		} else {
M
Mr.doob 已提交
3082

3083
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
3084

3085 3086 3087
		}

	};
N
Nicolas Garcia Belmonte 已提交
3088

3089
	this.supportsVertexTextures = function () {
3090

3091
		return maxVertexTextures() > 0;
3092

3093
	};
3094

3095
	function maxVertexTextures () {
3096

3097 3098 3099
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
3100

3101
	function initGL ( antialias, clearColor, clearAlpha ) {
N
Nicolas Garcia Belmonte 已提交
3102 3103 3104

		try {

M
Mikael Emtinger 已提交
3105
			if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { antialias: antialias, stencil:true } ) ) ) {
N
Nicolas Garcia Belmonte 已提交
3106

3107
				throw 'Error creating WebGL context.';
N
Nicolas Garcia Belmonte 已提交
3108

3109 3110 3111
			}

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

3113
			console.error( e );
N
Nicolas Garcia Belmonte 已提交
3114 3115 3116 3117 3118 3119 3120 3121 3122

		}

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

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

3123 3124
		_gl.frontFace( _gl.CCW );
		_gl.cullFace( _gl.BACK );
3125
		_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
3126

N
Nicolas Garcia Belmonte 已提交
3127
		_gl.enable( _gl.BLEND );
3128
		_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
3129
		_gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
3130

A
alteredq 已提交
3131
		_cullEnabled = true;
N
Nicolas Garcia Belmonte 已提交
3132

3133
	};
M
Mr.doob 已提交
3134

3135
	function buildProgram ( fragmentShader, vertexShader, parameters ) {
3136
		
M
Mr.doob 已提交
3137
		var program = _gl.createProgram(),
M
Mr.doob 已提交
3138

M
Mr.doob 已提交
3139 3140 3141 3142
		prefix_fragment = [
			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",
M
Mr.doob 已提交
3143

3144 3145
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
3146

3147 3148
			parameters.fog ? "#define USE_FOG" : "",
			parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "",
3149

3150
			parameters.map ? "#define USE_MAP" : "",
3151 3152 3153
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
3154

3155
			"uniform mat4 viewMatrix;",
3156
			"uniform vec3 cameraPosition;",
M
Mr.doob 已提交
3157 3158
			""
		].join("\n"),
3159

M
Mr.doob 已提交
3160
		prefix_vertex = [
3161
			maxVertexTextures() > 0 ? "#define VERTEX_TEXTURES" : "",
3162

3163 3164 3165
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

3166 3167
			"#define MAX_BONES " + parameters.maxBones,

3168
			parameters.map ? "#define USE_MAP" : "",
3169 3170 3171
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
3172
			parameters.skinning ? "#define USE_SKINNING" : "",
3173
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
3174

3175

3176 3177
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
3178 3179 3180
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
3181 3182
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
3183
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
3184 3185 3186

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
3187
			"attribute vec3 position;",
3188 3189 3190 3191 3192 3193 3194 3195
			"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 已提交
3196
			"attribute vec3 normal;",
A
alteredq 已提交
3197
			"attribute vec3 color;",
M
Mr.doob 已提交
3198
			"attribute vec2 uv;",
3199
			"attribute vec2 uv2;",
3200

A
alteredq 已提交
3201 3202 3203 3204
			"attribute vec4 skinVertexA;",
			"attribute vec4 skinVertexB;",
			"attribute vec4 skinIndex;",
			"attribute vec4 skinWeight;",
M
Mr.doob 已提交
3205 3206
			""
		].join("\n");
3207

3208 3209
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
3210

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

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

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

N
Nicolas Garcia Belmonte 已提交
3217
		}
3218

3219 3220
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
3221

M
Mr.doob 已提交
3222
		program.uniforms = {};
3223
		program.attributes = {};
M
Mr.doob 已提交
3224

M
Mr.doob 已提交
3225
		return program;
M
Mr.doob 已提交
3226

M
Mr.doob 已提交
3227
	};
M
Mr.doob 已提交
3228

3229
	function loadUniformsSkinning ( uniforms, object ) {
3230

M
Mr.doob 已提交
3231
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray );
A
alteredq 已提交
3232
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
3233

3234
	};
3235
		
3236

3237
	function loadUniformsMatrices ( uniforms, object ) {
3238

A
alteredq 已提交
3239 3240 3241 3242
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
		_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );

	};
3243

3244
	function loadUniformsGeneric ( program, uniforms ) {
M
Mr.doob 已提交
3245

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

M
Mr.doob 已提交
3248
		for( u in uniforms ) {
M
Mr.doob 已提交
3249

3250 3251
			location = program.uniforms[u];
			if ( !location ) continue;
M
Mr.doob 已提交
3252

3253
			uniform = uniforms[u];
M
Mr.doob 已提交
3254

3255 3256
			type = uniform.type;
			value = uniform.value;
M
Mr.doob 已提交
3257

M
Mr.doob 已提交
3258
			if( type == "i" ) {
M
Mr.doob 已提交
3259

M
Mr.doob 已提交
3260
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
3261

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

M
Mr.doob 已提交
3264
				_gl.uniform1f( location, value );
3265

A
alteredq 已提交
3266 3267 3268
			} else if( type == "fv1" ) {

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

3270 3271 3272 3273
			} else if( type == "fv" ) {

				_gl.uniform3fv( location, value );

3274 3275 3276 3277
			} else if( type == "v2" ) {

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

3278 3279 3280
			} else if( type == "v3" ) {

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

3282 3283 3284
			} else if( type == "c" ) {

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

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

M
Mr.doob 已提交
3288
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
3289

3290
				texture = uniform.texture;
M
Mr.doob 已提交
3291

3292
				if ( !texture ) continue;
M
Mr.doob 已提交
3293

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

3296
					setCubeTexture( texture, value );
M
Mr.doob 已提交
3297

3298
				} else {
M
Mr.doob 已提交
3299

3300
					setTexture( texture, value );
M
Mr.doob 已提交
3301

3302
				}
M
Mr.doob 已提交
3303

3304
			}
M
Mr.doob 已提交
3305

3306
		}
M
Mr.doob 已提交
3307

3308
	};
M
Mr.doob 已提交
3309

3310
	function setBlending ( blending ) {
A
alteredq 已提交
3311 3312

		if ( blending != _oldBlending ) {
3313

A
alteredq 已提交
3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336
			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;

3337 3338 3339 3340 3341 3342
				case THREE.ReverseSubtractiveBlending:

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

    				break;
A
alteredq 已提交
3343 3344 3345 3346 3347 3348
				default:

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

					break;
3349

A
alteredq 已提交
3350
			}
3351

A
alteredq 已提交
3352
			_oldBlending = blending;
3353

A
alteredq 已提交
3354 3355 3356
		}

	};
3357

3358
	function setTextureParameters ( textureType, texture, image ) {
3359

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

3362 3363
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
3364

3365 3366
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
3367

3368
			_gl.generateMipmap( textureType );
M
Mr.doob 已提交
3369

3370
		} else {
M
Mr.doob 已提交
3371

3372 3373 3374 3375 3376
			_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 已提交
3377

3378
		}
M
Mr.doob 已提交
3379

3380 3381
	};
	
3382
	function setTexture ( texture, slot ) {
3383

3384
		if ( texture.needsUpdate ) {
A
alteredq 已提交
3385

3386
			if ( !texture.__wasSetOnce ) {
M
Mr.doob 已提交
3387

3388
				texture.__webGLTexture = _gl.createTexture();
A
alteredq 已提交
3389

3390 3391
				_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 已提交
3392

A
alteredq 已提交
3393
				texture.__wasSetOnce = true;
M
Mr.doob 已提交
3394

A
alteredq 已提交
3395
			} else {
M
Mr.doob 已提交
3396

A
alteredq 已提交
3397 3398
				_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 已提交
3399 3400 3401

			}

3402 3403 3404
			setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			
A
alteredq 已提交
3405
			texture.needsUpdate = false;
3406 3407 3408 3409

		}

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

3412
	};
M
Mr.doob 已提交
3413

3414
	function setCubeTexture ( texture, slot ) {
3415 3416 3417 3418

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

			if ( texture.needsUpdate ) {
3419 3420
				
				if ( !texture.__wasSetOnce ) {
3421 3422 3423

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

3424
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube );
3425

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

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

3430 3431 3432
					}
				
					texture.__wasSetOnce = true;
3433 3434 3435

				} else {

3436
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube );
3437

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

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

3442
					}
3443 3444 3445

				}

3446
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[0] );
3447 3448 3449
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

				texture.needsUpdate = false;
3450
				
3451 3452 3453 3454 3455 3456 3457 3458 3459
			}

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

		}

	};

3460
	function setRenderTarget ( renderTexture ) {
3461 3462

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

3464 3465 3466 3467 3468
			renderTexture.__webGLFramebuffer = _gl.createFramebuffer();
			renderTexture.__webGLRenderbuffer = _gl.createRenderbuffer();
			renderTexture.__webGLTexture = _gl.createTexture();

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

3470 3471 3472 3473
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTexture.__webGLRenderbuffer );
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTexture.width, renderTexture.height );

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

3475
			_gl.bindTexture( _gl.TEXTURE_2D, renderTexture.__webGLTexture );
3476 3477 3478 3479
			_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 ) );
3480
			_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTexture.format ), renderTexture.width, renderTexture.height, 0, paramThreeToGL( renderTexture.format ), paramThreeToGL( renderTexture.type ), null );
3481 3482

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

3484 3485
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTexture.__webGLFramebuffer );
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, renderTexture.__webGLTexture, 0 );
3486
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webGLRenderbuffer );
3487 3488

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

3490 3491 3492
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
3493

3494 3495
		}

3496
		var framebuffer, width, height;
M
Mr.doob 已提交
3497

3498
		if ( renderTexture ) {
M
Mr.doob 已提交
3499

3500 3501 3502
			framebuffer = renderTexture.__webGLFramebuffer;
			width = renderTexture.width;
			height = renderTexture.height;
M
Mr.doob 已提交
3503

3504
		} else {
M
Mr.doob 已提交
3505

3506
			framebuffer = null;
3507 3508
			width = _viewportWidth;
			height = _viewportHeight;
M
Mr.doob 已提交
3509

3510
		}
M
Mr.doob 已提交
3511

3512
		if( framebuffer != _oldFramebuffer ) {
M
Mr.doob 已提交
3513

3514
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
3515
			_gl.viewport( _viewportX, _viewportY, width, height );
M
Mr.doob 已提交
3516

3517
			_oldFramebuffer = framebuffer;
M
Mr.doob 已提交
3518

3519
		}
3520

3521
	};
M
Mr.doob 已提交
3522

3523
	function updateRenderTargetMipmap ( renderTarget ) {
M
Mr.doob 已提交
3524

3525 3526 3527
		_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webGLTexture );
		_gl.generateMipmap( _gl.TEXTURE_2D );
		_gl.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
3528 3529

	};
3530

3531
	function cacheUniformLocations ( program, identifiers ) {
M
Mr.doob 已提交
3532

M
Mr.doob 已提交
3533
		var i, l, id;
M
Mr.doob 已提交
3534

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

3537 3538
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
3539

M
Mr.doob 已提交
3540
		}
M
Mr.doob 已提交
3541

M
Mr.doob 已提交
3542
	};
M
Mr.doob 已提交
3543

3544
	function cacheAttributeLocations ( program, identifiers ) {
3545

3546
		var i, l, id;
M
Mr.doob 已提交
3547

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

3550 3551
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
3552

3553
		}
M
Mr.doob 已提交
3554

M
Mr.doob 已提交
3555
	};
M
Mr.doob 已提交
3556

3557
	function getShader ( type, string ) {
N
Nicolas Garcia Belmonte 已提交
3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575

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

3576
			console.error( _gl.getShaderInfoLog( shader ) );
3577
			console.error( string );
N
Nicolas Garcia Belmonte 已提交
3578 3579 3580 3581 3582
			return null;

		}

		return shader;
M
Mr.doob 已提交
3583

3584
	};
N
Nicolas Garcia Belmonte 已提交
3585

3586
	// fallback filters for non-power-of-2 textures
3587

3588
	function filterFallback ( f ) {
3589

3590 3591 3592 3593 3594 3595 3596 3597
		switch ( f ) {

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

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mikael Emtinger 已提交
3598 3599 3600 3601
			case THREE.LinearMipMapLinearFilter: 
			default:
				
				return _gl.LINEAR; break;
3602 3603 3604 3605 3606

		}
		
	};
	
3607
	function paramThreeToGL ( p ) {
M
Mr.doob 已提交
3608

3609
		switch ( p ) {
M
Mr.doob 已提交
3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622

			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;

3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636
			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;

3637
		}
M
Mr.doob 已提交
3638

3639
		return 0;
M
Mr.doob 已提交
3640

3641 3642
	};

3643
	function isPowerOfTwo ( value ) {
3644 3645 3646 3647 3648

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

	};

3649
	function materialNeedsSmoothNormals ( material ) {
3650 3651 3652

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

3653
	};
M
Mr.doob 已提交
3654

3655
	function bufferNeedsSmoothNormals ( geometryGroup, object ) {
M
Mr.doob 已提交
3656

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

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

M
Mr.doob 已提交
3661
			meshMaterial = object.materials[ m ];
3662 3663 3664

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

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

3667
					if ( materialNeedsSmoothNormals( geometryGroup.materials[ i ] ) ) {
3668

3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689
						needsSmoothNormals = true;
						break;

					}

				}

			} else {

				if ( materialNeedsSmoothNormals( meshMaterial ) ) {

					needsSmoothNormals = true;
					break;

				}

			}

			if ( needsSmoothNormals ) break;

		}
M
Mr.doob 已提交
3690

3691
		return needsSmoothNormals;
M
Mr.doob 已提交
3692

3693
	};
M
Mr.doob 已提交
3694

3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768
	function unrollGroupMaterials( geometryGroup, object ) {
		
		var m, ml, i, il,
			material, meshMaterial,
			materials = [];
		
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

			meshMaterial = object.materials[ m ];

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

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

					material = geometryGroup.materials[ i ];

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

					}

				}

			} else {

				material = meshMaterial;

				if ( material ) {

					materials.push( material );

				}

			}

		}
		
		return materials;

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

			}
			
		}
		
		return false;
		
	};

	function bufferGuessNormalType ( materials, geometryGroup, object ) {
		
		var i, m, ml = materials.length;
			
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
		
		for ( i = 0; i < ml; i++ ) {
			
			m = materials[ i ];
			
A
alteredq 已提交
3769
			if ( ( m instanceof THREE.MeshBasicMaterial && !m.envMap ) || m instanceof THREE.MeshDepthMaterial ) continue;
3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796
			
			if ( materialNeedsSmoothNormals( m ) ) {
				
				return THREE.SmoothShading;

			} else {

				return THREE.FlatShading;

			}

		}
		
		return false;
		
	};

	function bufferGuessUVType ( materials, geometryGroup, object ) {
		
		var i, m, ml = materials.length;
			
		// material must use some texture to require uvs
		
		for ( i = 0; i < ml; i++ ) {
			
			m = materials[ i ];
			
A
alteredq 已提交
3797
			if ( m.map || m.lightMap || m instanceof THREE.MeshShaderMaterial ) {
3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808
				
				return true;
				
			}
			
		}
		
		return false;
		
	};
	
3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831
	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 ) {
3832

3833 3834
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
3835

3836
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
3837

3838
			light = lights[ l ];
3839

3840 3841
			if ( light instanceof THREE.DirectionalLight ) dirLights++;
			if ( light instanceof THREE.PointLight ) pointLights++;
3842

3843
		}
3844

3845
		if ( ( pointLights + dirLights ) <= maxLights ) {
3846

3847 3848
			maxDirLights = dirLights;
			maxPointLights = pointLights;
3849

3850
		} else {
3851

3852 3853
			maxDirLights = Math.ceil( maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = maxLights - maxDirLights;
3854 3855 3856

		}

3857
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
3858 3859

	};
M
Mr.doob 已提交
3860

A
alteredq 已提交
3861
	/* DEBUG
3862
	function getGLParams() {
M
Mr.doob 已提交
3863

3864
		var params  = {
M
Mr.doob 已提交
3865

3866 3867
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
3868

3869 3870 3871
			'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 已提交
3872

3873 3874 3875
			'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 已提交
3876

3877 3878
		return params;
	};
M
Mr.doob 已提交
3879

3880
	function dumpObject( obj ) {
M
Mr.doob 已提交
3881

3882 3883
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
3884

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

3887
		}
M
Mr.doob 已提交
3888

3889 3890
		return str;
	}
A
alteredq 已提交
3891
	*/
3892
};
3893