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

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

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

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

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

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

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

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

A
alteredq 已提交
27
	_this = this,
28

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

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

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

41
	// camera matrices caches
42 43

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

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

56
	_vector3 = new THREE.Vector4(),
57

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

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

	},

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

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

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

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

80
	}
M
Mr.doob 已提交
81

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

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

88 89
	this.context = _gl;

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

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

		_canvas.width = width;
		_canvas.height = height;
96 97 98 99
		
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
100

101
	this.setViewport = function ( x, y, width, height ) {
102 103 104 105 106 107 108 109 110
		
		_viewportX = x;
		_viewportY = y;
		
		_viewportWidth = width;
		_viewportHeight = height;
		
		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
		
N
Nicolas Garcia Belmonte 已提交
111
	};
112
	
113
	this.setScissor = function ( x, y, width, height ) {
N
Nicolas Garcia Belmonte 已提交
114

115 116 117 118
		_gl.scissor( x, y, width, height );
		
	};
	
119
	this.enableScissorTest = function ( enable ) {
120 121 122 123 124 125 126 127
		
		if ( enable )
			_gl.enable( _gl.SCISSOR_TEST );
		else
			_gl.disable( _gl.SCISSOR_TEST );
		
	};
	
128 129 130 131 132 133
	this.enableDepthBufferWrite = function ( enable ) {
		
		_gl.depthMask( enable );

	};
	
134
	this.setClearColorHex = function ( hex, alpha ) {
135

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

139
	};
A
alteredq 已提交
140

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

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

	};
146

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

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

	};

M
Mr.doob 已提交
153

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

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

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

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

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

167
			dlength = 0,
168
			plength = 0,
169

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

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

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

			if ( light instanceof THREE.AmbientLight ) {

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

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

188
				doffset = dlength * 3;
189

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

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

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

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

202
				poffset = plength * 3;
203

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

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

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

214 215 216
			}

		}
217

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

221 222
		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 已提交
223

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

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

231
	};
M
Mr.doob 已提交
232

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

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

238
	};
M
Mr.doob 已提交
239

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

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

245
	};
246

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

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

	};

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

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

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

268 269
		geometryGroup.__webGLFaceBuffer = _gl.createBuffer();
		geometryGroup.__webGLLineBuffer = _gl.createBuffer();
M
Mr.doob 已提交
270

271
	};
272

273
	function initLineBuffers ( geometry ) {
M
Mr.doob 已提交
274

275 276 277
		var nvertices = geometry.vertices.length;

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

280
		geometry.__webGLLineCount = nvertices;
M
Mr.doob 已提交
281

282
	};
M
Mr.doob 已提交
283

284
	function initRibbonBuffers ( geometry ) {
A
alteredq 已提交
285 286 287 288 289 290 291 292 293

		var nvertices = geometry.vertices.length;

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

		geometry.__webGLVertexCount = nvertices;

	};
294

295
	function initParticleBuffers ( geometry ) {
296 297 298 299

		var nvertices = geometry.vertices.length;

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

302
		geometry.__sortArray = [];
303 304 305 306 307

		geometry.__webGLParticleCount = nvertices;

	};

308
	function initMeshBuffers ( geometryGroup, object ) {
M
Mr.doob 已提交
309

310
		var f, fl, nvertices = 0, ntris = 0, nlines = 0,
M
Mr.doob 已提交
311
			obj_faces = object.geometry.faces,
312
			chunk_faces = geometryGroup.faces;
M
Mr.doob 已提交
313

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

316 317
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
M
Mr.doob 已提交
318

319
			if ( face instanceof THREE.Face3 ) {
M
Mr.doob 已提交
320

321 322 323
				nvertices += 3;
				ntris += 1;
				nlines += 3;
M
Mr.doob 已提交
324

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

327 328
				nvertices += 4;
				ntris += 2;
329
				nlines += 4;
M
Mr.doob 已提交
330

331
			}
M
Mr.doob 已提交
332

333
		}
M
Mr.doob 已提交
334

335
		// TODO: only create arrays for attributes existing in the object
M
Mr.doob 已提交
336

337 338 339 340 341 342
		geometryGroup.__vertexArray  = new Float32Array( nvertices * 3 );
		geometryGroup.__normalArray  = new Float32Array( nvertices * 3 );
		geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
		geometryGroup.__colorArray = new Float32Array( nvertices * 3 );
		geometryGroup.__uvArray = new Float32Array( nvertices * 2 );
		geometryGroup.__uv2Array = new Float32Array( nvertices * 2 );
M
Mr.doob 已提交
343

344 345 346 347
		geometryGroup.__skinVertexAArray = new Float32Array( nvertices * 4 );
		geometryGroup.__skinVertexBArray = new Float32Array( nvertices * 4 );
		geometryGroup.__skinIndexArray = new Float32Array( nvertices * 4 );
		geometryGroup.__skinWeightArray = new Float32Array( nvertices * 4 );
348

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

352
		geometryGroup.__needsSmoothNormals = bufferNeedsSmoothNormals ( geometryGroup, object );
M
Mr.doob 已提交
353

354 355
		geometryGroup.__webGLFaceCount = ntris * 3;
		geometryGroup.__webGLLineCount = nlines * 2;
M
Mr.doob 已提交
356

357
	};
M
Mr.doob 已提交
358

359
	function setMeshBuffers ( geometryGroup, object, hint ) {
360

361 362
		var f, fl, fi, face, vertexNormals, faceNormal, normal,
			uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4,
363
			c1, c2, c3, c4,
A
alteredq 已提交
364 365 366 367
			sw1, sw2, sw3, sw4,
			si1, si2, si3, si4,
			sa1, sa2, sa3, sa4,
			sb1, sb2, sb3, sb4,
368
			m, ml, i,
369
			vn, uvi, uv2i,
M
Mr.doob 已提交
370

371
		vertexIndex = 0,
372

373 374
		offset = 0,
		offset_uv = 0,
375
		offset_uv2 = 0,
376 377 378 379
		offset_face = 0,
		offset_normal = 0,
		offset_tangent = 0,
		offset_line = 0,
380
		offset_color = 0,
A
alteredq 已提交
381
		offset_skin = 0,
M
Mr.doob 已提交
382

383 384 385 386 387 388
		vertexArray = geometryGroup.__vertexArray,
		uvArray = geometryGroup.__uvArray,
		uv2Array = geometryGroup.__uv2Array,
		normalArray = geometryGroup.__normalArray,
		tangentArray = geometryGroup.__tangentArray,
		colorArray = geometryGroup.__colorArray,
389

390 391 392 393
		skinVertexAArray = geometryGroup.__skinVertexAArray,
		skinVertexBArray = geometryGroup.__skinVertexBArray,
		skinIndexArray = geometryGroup.__skinIndexArray,
		skinWeightArray = geometryGroup.__skinWeightArray,
M
Mr.doob 已提交
394

395 396
		faceArray = geometryGroup.__faceArray,
		lineArray = geometryGroup.__lineArray,
M
Mr.doob 已提交
397

398
		needsSmoothNormals = geometryGroup.__needsSmoothNormals,
399

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

402
		dirtyVertices = geometry.__dirtyVertices,
403 404 405
		dirtyElements = geometry.__dirtyElements,
		dirtyUvs = geometry.__dirtyUvs,
		dirtyNormals = geometry.__dirtyNormals,
406
		dirtyTangents = geometry.__dirtyTangents,
407
		dirtyColors = geometry.__dirtyColors,
M
Mr.doob 已提交
408

409
		vertices = geometry.vertices,
410
		chunk_faces = geometryGroup.faces,
411
		obj_faces = geometry.faces,
412
		obj_uvs = geometry.uvs,
413
		obj_uvs2 = geometry.uvs2,
A
alteredq 已提交
414
		obj_colors = geometry.colors,
415

A
alteredq 已提交
416 417 418 419
		obj_skinVerticesA = geometry.skinVerticesA,
		obj_skinVerticesB = geometry.skinVerticesB,
		obj_skinIndices = geometry.skinIndices,
		obj_skinWeights = geometry.skinWeights;
420

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

423 424 425
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
			uv = obj_uvs[ fi ];
426
			uv2 = obj_uvs2[ fi ];
M
Mr.doob 已提交
427

428
			vertexNormals = face.vertexNormals;
429
			faceNormal = face.normal;
430 431 432

			if ( face instanceof THREE.Face3 ) {

433
				if ( dirtyVertices ) {
M
Mr.doob 已提交
434

435 436 437
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
M
Mr.doob 已提交
438

439 440 441
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
442

443 444 445
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
446

447 448 449
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
M
Mr.doob 已提交
450

451
					offset += 9;
M
Mr.doob 已提交
452

453
				}
454

A
alteredq 已提交
455 456 457
				if ( obj_skinWeights.length ) {

					// weights
458

A
alteredq 已提交
459 460 461
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
462

A
alteredq 已提交
463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478
					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
479

A
alteredq 已提交
480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499
					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
500

A
alteredq 已提交
501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
					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
521

A
alteredq 已提交
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541
					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;
542

A
alteredq 已提交
543
				}
544

545
				if ( dirtyColors && obj_colors.length ) {
546

547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
					c1 = obj_colors[ face.a ];
					c2 = obj_colors[ face.b ];
					c3 = obj_colors[ face.c ];

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

563 564 565 566
					offset_color += 9;

				}

567
				if ( dirtyTangents && geometry.hasTangents ) {
568

569 570 571
					t1 = vertices[ face.a ].tangent;
					t2 = vertices[ face.b ].tangent;
					t3 = vertices[ face.c ].tangent;
572

573 574 575 576
					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 已提交
577

578 579 580 581
					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 已提交
582

583 584 585 586
					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 已提交
587

588
					offset_tangent += 12;
M
Mr.doob 已提交
589

590 591
				}

592
				if ( dirtyNormals ) {
M
Mr.doob 已提交
593

594 595 596
					if ( vertexNormals.length == 3 && needsSmoothNormals ) {

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

598
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
599

600 601 602
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
603

604
							offset_normal += 3;
M
Mr.doob 已提交
605

606
						}
M
Mr.doob 已提交
607

608
					} else {
609

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

612 613 614
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
615

616
							offset_normal += 3;
M
Mr.doob 已提交
617

618
						}
M
Mr.doob 已提交
619 620

					}
M
Mr.doob 已提交
621

622 623
				}

624
				if ( dirtyUvs && uv ) {
625

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

628
						uvi = uv[ i ];
M
Mr.doob 已提交
629

630 631
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
632

633
						offset_uv += 2;
M
Mr.doob 已提交
634

M
Mr.doob 已提交
635
					}
636 637 638

				}

639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
				if ( dirtyUvs && uv2 ) {

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

						uv2i = uv2[ i ];

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

						offset_uv2 += 2;

					}

				}

654
				if( dirtyElements ) {
M
Mr.doob 已提交
655

656 657 658
					faceArray[ offset_face ] = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
M
Mr.doob 已提交
659

660
					offset_face += 3;
M
Mr.doob 已提交
661

662 663
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
664

665 666
					lineArray[ offset_line + 2 ] = vertexIndex;
					lineArray[ offset_line + 3 ] = vertexIndex + 2;
M
Mr.doob 已提交
667

668 669
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
670

671
					offset_line += 6;
672

673
					vertexIndex += 3;
M
Mr.doob 已提交
674

675
				}
M
Mr.doob 已提交
676

677 678 679

			} else if ( face instanceof THREE.Face4 ) {

680
				if ( dirtyVertices ) {
M
Mr.doob 已提交
681

682 683 684 685
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
					v4 = vertices[ face.d ].position;
M
Mr.doob 已提交
686

687 688 689
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
690

691 692 693
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
694

695 696 697
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
698

699 700 701
					vertexArray[ offset + 9 ] = v4.x;
					vertexArray[ offset + 10 ] = v4.y;
					vertexArray[ offset + 11 ] = v4.z;
M
Mr.doob 已提交
702

703
					offset += 12;
M
Mr.doob 已提交
704

705
				}
706

A
alteredq 已提交
707 708 709
				if ( obj_skinWeights.length ) {

					// weights
710

A
alteredq 已提交
711 712 713 714
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
					sw4 = obj_skinWeights[ face.d ];
715

A
alteredq 已提交
716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736
					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
737

A
alteredq 已提交
738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763
					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
764

A
alteredq 已提交
765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790
					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
791

A
alteredq 已提交
792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816
					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;

817 818
					offset_skin += 16;

A
alteredq 已提交
819
				}
820

821 822 823 824 825
				if ( dirtyColors && obj_colors.length ) {

					c1 = obj_colors[ face.a ];
					c2 = obj_colors[ face.b ];
					c3 = obj_colors[ face.c ];
826
					c4 = obj_colors[ face.d ];
827 828 829 830 831 832 833 834 835 836 837 838

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

840 841 842
					colorArray[ offset_color + 9 ]  = c4.r;
					colorArray[ offset_color + 10 ] = c4.g;
					colorArray[ offset_color + 11 ] = c4.b;
843

844 845
					offset_color += 12;

846 847
				}

848
				if ( dirtyTangents && geometry.hasTangents ) {
849

850 851 852 853
					t1 = vertices[ face.a ].tangent;
					t2 = vertices[ face.b ].tangent;
					t3 = vertices[ face.c ].tangent;
					t4 = vertices[ face.d ].tangent;
854

855 856 857 858
					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 已提交
859

860 861 862 863
					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 已提交
864

865 866 867 868
					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 已提交
869

870 871 872 873
					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 已提交
874

875
					offset_tangent += 16;
M
Mr.doob 已提交
876

877
				}
M
Mr.doob 已提交
878

879
				if( dirtyNormals ) {
M
Mr.doob 已提交
880

881
					if ( vertexNormals.length == 4 && needsSmoothNormals ) {
882

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

885
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
886

887 888 889
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
890

891
							offset_normal += 3;
M
Mr.doob 已提交
892

893
						}
M
Mr.doob 已提交
894

895
					} else {
896

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

899 900 901
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
902

903
							offset_normal += 3;
M
Mr.doob 已提交
904

905
						}
M
Mr.doob 已提交
906 907

					}
M
Mr.doob 已提交
908

909 910
				}

911
				if ( dirtyUvs && uv ) {
912

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

915
						uvi = uv[ i ];
M
Mr.doob 已提交
916

917 918
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
919

920
						offset_uv += 2;
M
Mr.doob 已提交
921

M
Mr.doob 已提交
922
					}
923 924

				}
925

926 927 928 929 930 931 932 933 934 935 936 937 938 939
				if ( dirtyUvs && uv2 ) {

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

941
				if ( dirtyElements ) {
M
Mr.doob 已提交
942

943 944 945
					faceArray[ offset_face ]     = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
M
Mr.doob 已提交
946

947 948 949
					faceArray[ offset_face + 3 ] = vertexIndex;
					faceArray[ offset_face + 4 ] = vertexIndex + 2;
					faceArray[ offset_face + 5 ] = vertexIndex + 3;
M
Mr.doob 已提交
950

951
					offset_face += 6;
M
Mr.doob 已提交
952

953 954
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
955

956
					lineArray[ offset_line + 2 ] = vertexIndex;
957
					lineArray[ offset_line + 3 ] = vertexIndex + 3;
M
Mr.doob 已提交
958

959 960
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
961

962 963
					lineArray[ offset_line + 6 ] = vertexIndex + 2;
					lineArray[ offset_line + 7 ] = vertexIndex + 3;
M
Mr.doob 已提交
964

965
					offset_line += 8;
M
Mr.doob 已提交
966

967
					vertexIndex += 4;
M
Mr.doob 已提交
968

969
				}
M
Mr.doob 已提交
970

971
			}
M
Mr.doob 已提交
972

973 974
		}

975
		if ( dirtyVertices ) {
M
Mr.doob 已提交
976

977
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
978
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
979

980
		}
M
Mr.doob 已提交
981

982 983
		if ( dirtyColors && obj_colors.length ) {

984
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLColorBuffer );
985 986 987
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}
988

989
		if ( dirtyNormals ) {
M
Mr.doob 已提交
990

991
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLNormalBuffer );
992
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
993

994 995
		}

996
		if ( dirtyTangents && geometry.hasTangents ) {
997

998
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLTangentBuffer );
999
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
M
Mr.doob 已提交
1000

1001
		}
1002

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

1005
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUVBuffer );
1006
			_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
M
Mr.doob 已提交
1007

1008
		}
M
Mr.doob 已提交
1009

1010 1011
		if ( dirtyUvs && offset_uv2 > 0 ) {

1012
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUV2Buffer );
1013 1014 1015 1016
			_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );

		}

1017
		if ( dirtyElements ) {
M
Mr.doob 已提交
1018

1019
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLFaceBuffer );
1020
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
1021

1022
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLLineBuffer );
1023
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
M
Mr.doob 已提交
1024

1025
		}
1026

1027
		if ( offset_skin > 0 ) {
1028

1029
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexABuffer );
A
alteredq 已提交
1030 1031
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );

1032
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexBBuffer );
A
alteredq 已提交
1033 1034
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );

1035
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinIndicesBuffer );
A
alteredq 已提交
1036 1037
			_gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );

1038
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinWeightsBuffer );
A
alteredq 已提交
1039
			_gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
1040

A
alteredq 已提交
1041
		}
1042 1043

	};
1044

1045
	function setLineBuffers ( geometry, hint ) {
M
Mr.doob 已提交
1046

1047
		var v, c, vertex, offset,
1048
			vertices = geometry.vertices,
1049
			colors = geometry.colors,
1050
			vl = vertices.length,
1051
			cl = colors.length,
M
Mr.doob 已提交
1052 1053

			vertexArray = geometry.__vertexArray,
1054
			colorArray = geometry.__colorArray,
1055 1056

			dirtyVertices = geometry.__dirtyVertices,
1057
			dirtyColors = geometry.__dirtyColors;
M
Mr.doob 已提交
1058

1059
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1060

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

1063
				vertex = vertices[ v ].position;
M
Mr.doob 已提交
1064

1065
				offset = v * 3;
M
Mr.doob 已提交
1066

1067 1068 1069
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
M
Mr.doob 已提交
1070

1071 1072
			}

A
alteredq 已提交
1073 1074 1075
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

1076
		}
M
Mr.doob 已提交
1077

1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096
		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 );

		}

1097
	};
M
Mr.doob 已提交
1098

1099
	function setRibbonBuffers ( geometry, hint ) {
A
alteredq 已提交
1100 1101 1102 1103 1104 1105 1106 1107 1108

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

			vertexArray = geometry.__vertexArray,
			colorArray = geometry.__colorArray,
1109 1110

			dirtyVertices = geometry.__dirtyVertices,
A
alteredq 已提交
1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151
			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 );

		}

	};
1152

1153
	function setParticleBuffers ( geometry, hint, object ) {
1154

A
alteredq 已提交
1155
		var v, c, vertex, offset,
1156 1157 1158
			vertices = geometry.vertices,
			vl = vertices.length,

A
alteredq 已提交
1159 1160
			colors = geometry.colors,
			cl = colors.length,
1161

1162
			vertexArray = geometry.__vertexArray,
A
alteredq 已提交
1163
			colorArray = geometry.__colorArray,
1164

1165
			sortArray = geometry.__sortArray,
1166

1167 1168 1169
			dirtyVertices = geometry.__dirtyVertices,
			dirtyElements = geometry.__dirtyElements,
			dirtyColors = geometry.__dirtyColors;
1170

1171
		if ( object.sortParticles ) {
1172

1173
			_projScreenMatrix.multiplySelf( object.matrixWorld );
1174

1175 1176 1177
			for ( v = 0; v < vl; v++ ) {

				vertex = vertices[ v ].position;
1178

1179 1180
				_vector3.copy( vertex );
				_projScreenMatrix.multiplyVector3( _vector3 );
1181

1182
				sortArray[ v ] = [ _vector3.z, v ];
1183

1184
			}
1185

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

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

1190
				vertex = vertices[ sortArray[v][1] ].position;
1191

1192
				offset = v * 3;
1193

1194 1195 1196
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
1197

1198
			}
1199

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

A
alteredq 已提交
1202
				offset = c * 3;
1203

A
alteredq 已提交
1204 1205 1206 1207 1208
				color = colors[ sortArray[c][1] ];

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

1210
			}
1211 1212


1213
		} else {
1214

1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227
			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;

				}
1228 1229

			}
1230

A
alteredq 已提交
1231
			if ( dirtyColors ) {
1232

A
alteredq 已提交
1233 1234 1235 1236 1237 1238 1239 1240 1241 1242
				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;

1243
				}
1244

A
alteredq 已提交
1245
			}
1246 1247

		}
1248

A
alteredq 已提交
1249
		if ( dirtyVertices || object.sortParticles ) {
1250

A
alteredq 已提交
1251 1252
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
1253

A
alteredq 已提交
1254
		}
1255

A
alteredq 已提交
1256
		if ( dirtyColors || object.sortParticles ) {
1257

A
alteredq 已提交
1258 1259
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLColorBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
1260

A
alteredq 已提交
1261
		}
1262

1263
	};
M
Mr.doob 已提交
1264

1265
	function setMaterialShaders ( material, shaders ) {
1266

1267 1268
		material.fragmentShader = shaders.fragmentShader;
		material.vertexShader = shaders.vertexShader;
1269
		material.uniforms = Uniforms.clone( shaders.uniforms );
1270

M
Mr.doob 已提交
1271
	};
1272

1273
	function refreshUniformsCommon ( uniforms, material ) {
M
Mr.doob 已提交
1274

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

1278
		// pure color
A
alteredq 已提交
1279
		//uniforms.color.value.setHex( material.color.hex );
M
Mr.doob 已提交
1280

A
alteredq 已提交
1281 1282
		uniforms.opacity.value = material.opacity;
		uniforms.map.texture = material.map;
1283

1284
		uniforms.lightMap.texture = material.lightMap;
1285

1286
		uniforms.envMap.texture = material.envMap;
A
alteredq 已提交
1287
		uniforms.reflectivity.value = material.reflectivity;
1288
		uniforms.refractionRatio.value = material.refractionRatio;
A
alteredq 已提交
1289
		uniforms.combine.value = material.combine;
1290
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
1291

1292
	};
1293

1294
	function refreshUniformsLine ( uniforms, material ) {
1295

A
alteredq 已提交
1296 1297
		uniforms.diffuse.value.setRGB( material.color.r * material.opacity, material.color.g * material.opacity, material.color.b * material.opacity );
		uniforms.opacity.value = material.opacity;
1298 1299

	};
M
Mr.doob 已提交
1300

1301
	function refreshUniformsParticle ( uniforms, material ) {
1302

A
alteredq 已提交
1303 1304 1305 1306
		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;
		uniforms.map.texture = material.map;
1307

A
alteredq 已提交
1308
	};
1309

1310
	function refreshUniformsFog ( uniforms, fog ) {
1311

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

A
alteredq 已提交
1314
		if ( fog instanceof THREE.Fog ) {
1315

A
alteredq 已提交
1316 1317
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
1318

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

A
alteredq 已提交
1321
			uniforms.fogDensity.value = fog.density;
1322 1323

		}
1324

1325 1326
	};

1327
	function refreshUniformsPhong ( uniforms, material ) {
M
Mr.doob 已提交
1328

A
alteredq 已提交
1329 1330 1331 1332 1333
		//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 已提交
1334

1335
	};
M
Mr.doob 已提交
1336 1337


1338
	function refreshUniformsLights ( uniforms, lights ) {
M
Mr.doob 已提交
1339

A
alteredq 已提交
1340 1341 1342 1343 1344 1345
		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 已提交
1346

A
alteredq 已提交
1347
	};
M
Mr.doob 已提交
1348

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

1351
		var u, identifiers, parameters, maxLightCount, maxBones;
1352

A
alteredq 已提交
1353
		if ( material instanceof THREE.MeshDepthMaterial ) {
1354

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

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

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

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

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

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

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

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

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

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

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

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

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

A
alteredq 已提交
1381
		}
1382

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

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

1388 1389
		maxBones = allocateBones( object );
		
1390
		parameters = { fog: fog, map: material.map, envMap: material.envMap, lightMap: material.lightMap, vertexColors: material.vertexColors,
1391
					   skinning: material.skinning,
1392 1393
					   maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
					   maxBones: maxBones };
1394

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

1397
		identifiers = [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
A
alteredq 已提交
1398
						'cameraInverseMatrix', 'boneGlobalMatrices'
A
alteredq 已提交
1399
						];
A
alteredq 已提交
1400

A
alteredq 已提交
1401
		for( u in material.uniforms ) {
1402

A
alteredq 已提交
1403
			identifiers.push(u);
M
Mr.doob 已提交
1404

A
alteredq 已提交
1405
		}
M
Mr.doob 已提交
1406

A
alteredq 已提交
1407
		cacheUniformLocations( material.program, identifiers );
1408
		cacheAttributeLocations( material.program, [ "position", "normal", "uv", "uv2", "tangent", "color",
A
alteredq 已提交
1409
													 "skinVertexA", "skinVertexB", "skinIndex", "skinWeight" ] );
1410

A
alteredq 已提交
1411
		var attributes = material.program.attributes;
1412

A
alteredq 已提交
1413
		_gl.enableVertexAttribArray( attributes.position );
1414

A
alteredq 已提交
1415
		if ( attributes.color >= 0 ) 	_gl.enableVertexAttribArray( attributes.color );
1416
		if ( attributes.normal >= 0 ) 	_gl.enableVertexAttribArray( attributes.normal );
A
alteredq 已提交
1417
		if ( attributes.tangent >= 0 ) 	_gl.enableVertexAttribArray( attributes.tangent );
1418 1419 1420

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

A
alteredq 已提交
1423 1424 1425 1426
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
1427

A
alteredq 已提交
1428
		}
M
Mr.doob 已提交
1429

1430
	};
1431

1432
	function setProgram ( camera, lights, fog, material, object ) {
1433

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

1436
		var program = material.program,
A
alteredq 已提交
1437 1438
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
1439

M
Mr.doob 已提交
1440
		if( program != _oldProgram ) {
M
Mr.doob 已提交
1441

M
Mr.doob 已提交
1442 1443
			_gl.useProgram( program );
			_oldProgram = program;
1444

M
Mr.doob 已提交
1445
		}
1446

1447 1448
		_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );

A
alteredq 已提交
1449
		// refresh uniforms common to several materials
1450 1451

		if ( fog && (
A
alteredq 已提交
1452 1453
			 material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
1454
			 material instanceof THREE.MeshPhongMaterial ||
A
alteredq 已提交
1455 1456 1457
			 material instanceof THREE.LineBasicMaterial ||
			 material instanceof THREE.ParticleBasicMaterial )
			) {
1458

A
alteredq 已提交
1459
			refreshUniformsFog( m_uniforms, fog );
1460 1461

		}
M
Mr.doob 已提交
1462

M
Mr.doob 已提交
1463
		if ( material instanceof THREE.MeshPhongMaterial ||
1464
			 material instanceof THREE.MeshLambertMaterial ) {
1465

A
alteredq 已提交
1466
			setupLights( program, lights );
A
alteredq 已提交
1467
			refreshUniformsLights( m_uniforms, _lights );
M
Mr.doob 已提交
1468 1469 1470

		}

1471 1472 1473
		if ( material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
			 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
1474

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

A
alteredq 已提交
1477
		}
M
Mr.doob 已提交
1478

A
alteredq 已提交
1479
		// refresh single material specific uniforms
1480

1481
		if ( material instanceof THREE.LineBasicMaterial ) {
M
Mr.doob 已提交
1482

A
alteredq 已提交
1483
			refreshUniformsLine( m_uniforms, material );
1484

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

A
alteredq 已提交
1487
			refreshUniformsParticle( m_uniforms, material );
1488

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

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

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

1495 1496
			m_uniforms.mNear.value = camera.near;
			m_uniforms.mFar.value = camera.far;
A
alteredq 已提交
1497
			m_uniforms.opacity.value = material.opacity;
1498

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

A
alteredq 已提交
1501
			m_uniforms.opacity.value = material.opacity;
1502

1503
		}
1504

A
alteredq 已提交
1505
		// load common uniforms
1506

A
alteredq 已提交
1507 1508
		loadUniformsGeneric( program, m_uniforms );
		loadUniformsMatrices( p_uniforms, object );
1509

A
alteredq 已提交
1510 1511
		// load material specific uniforms
		// (shader material also gets them for the sake of genericity)
1512

A
alteredq 已提交
1513 1514
		if ( material instanceof THREE.MeshShaderMaterial ||
			 material instanceof THREE.MeshPhongMaterial ||
1515
			 material.envMap ) {
1516

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

1519
		}
1520

A
alteredq 已提交
1521
		if ( material instanceof THREE.MeshShaderMaterial ||
1522
			 material.envMap ||
1523
			 material.skinning ) {
1524

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

A
alteredq 已提交
1527
		}
1528

A
alteredq 已提交
1529 1530
		if ( material instanceof THREE.MeshPhongMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
A
alteredq 已提交
1531
			 material instanceof THREE.MeshShaderMaterial ||
1532 1533
			 material.skinning ) {

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

A
alteredq 已提交
1536
		}
1537

1538
		if ( material.skinning ) {
1539

1540
			loadUniformsSkinning( p_uniforms, object );
1541

A
alteredq 已提交
1542
		}
1543

A
alteredq 已提交
1544
		return program;
1545

A
alteredq 已提交
1546
	};
1547

1548
	function renderBuffer ( camera, lights, fog, material, geometryGroup, object ) {
A
alteredq 已提交
1549 1550 1551

		var program, attributes, linewidth, primitives;

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

1554
		attributes = program.attributes;
M
Mr.doob 已提交
1555

1556
		// vertices
M
Mr.doob 已提交
1557

1558
		_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
1559
		_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
1560

A
alteredq 已提交
1561 1562 1563 1564
		// colors

		if ( attributes.color >= 0 ) {

1565
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLColorBuffer );
1566
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
1567 1568 1569

		}

1570
		// normals
M
Mr.doob 已提交
1571

1572
		if ( attributes.normal >= 0 ) {
1573

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

1577
		}
1578

1579 1580 1581
		// tangents

		if ( attributes.tangent >= 0 ) {
1582

1583
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLTangentBuffer );
1584
			_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
1585

1586
		}
1587

1588
		// uvs
M
Mr.doob 已提交
1589

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

1592
			if ( geometryGroup.__webGLUVBuffer ) {
1593

1594
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUVBuffer );
1595
				_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
1596

1597
				_gl.enableVertexAttribArray( attributes.uv );
1598

1599
			} else {
1600

1601
				_gl.disableVertexAttribArray( attributes.uv );
M
Mr.doob 已提交
1602

1603
			}
1604 1605 1606

		}

1607 1608
		if ( attributes.uv2 >= 0 ) {

1609
			if ( geometryGroup.__webGLUV2Buffer ) {
1610

1611
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUV2Buffer );
1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623
				_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );

				_gl.enableVertexAttribArray( attributes.uv2 );

			} else {

				_gl.disableVertexAttribArray( attributes.uv2 );

			}

		}

1624 1625
		if ( material.skinning &&
			 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
A
alteredq 已提交
1626
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
1627

1628
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexABuffer );
A
alteredq 已提交
1629 1630
			_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );

1631
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexBBuffer );
A
alteredq 已提交
1632 1633
			_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );

1634
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinIndicesBuffer );
A
alteredq 已提交
1635 1636
			_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );

1637
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinWeightsBuffer );
A
alteredq 已提交
1638
			_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
1639

A
alteredq 已提交
1640
		}
1641

1642
		// render mesh
M
Mr.doob 已提交
1643

1644
		if ( object instanceof THREE.Mesh ) {
1645

1646
			// wireframe
1647

1648
			if ( material.wireframe ) {
M
Mr.doob 已提交
1649

1650
				_gl.lineWidth( material.wireframeLinewidth );
1651 1652
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webGLLineCount, _gl.UNSIGNED_SHORT, 0 );
1653

1654
			// triangles
1655

1656
			} else {
1657

1658 1659
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
1660

1661
			}
1662

1663
		// render lines
1664

1665
		} else if ( object instanceof THREE.Line ) {
1666

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

1669
			_gl.lineWidth( material.linewidth );
1670
			_gl.drawArrays( primitives, 0, geometryGroup.__webGLLineCount );
1671

1672
		// render particles
1673

1674
		} else if ( object instanceof THREE.ParticleSystem ) {
1675

1676
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webGLParticleCount );
1677

A
alteredq 已提交
1678
		// render ribbon
1679

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

1682
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webGLVertexCount );
1683

1684 1685 1686 1687
		}

	};

1688
	function renderBufferImmediate ( object, program ) {
1689

A
alteredq 已提交
1690 1691
		if ( ! object.__webGLVertexBuffer ) object.__webGLVertexBuffer = _gl.createBuffer();
		if ( ! object.__webGLNormalBuffer ) object.__webGLNormalBuffer = _gl.createBuffer();
1692

A
alteredq 已提交
1693
		if ( object.hasPos ) {
1694

A
alteredq 已提交
1695 1696 1697 1698
		  _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 );
1699

A
alteredq 已提交
1700
		}
1701

A
alteredq 已提交
1702
		if ( object.hasNormal ) {
1703

A
alteredq 已提交
1704 1705 1706 1707
		  _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 );
1708

A
alteredq 已提交
1709
		}
1710

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

A
alteredq 已提交
1713
		object.count = 0;
1714

A
alteredq 已提交
1715
	};
1716

1717
	function setObjectFaces ( object ) {
1718

1719
		if ( _oldDoubleSided != object.doubleSided ) {
1720

1721
			if( object.doubleSided ) {
1722

1723
				_gl.disable( _gl.CULL_FACE );
1724

1725
			} else {
1726

A
alteredq 已提交
1727
				_gl.enable( _gl.CULL_FACE );
1728

A
alteredq 已提交
1729
			}
1730

1731
			_oldDoubleSided = object.doubleSided;
1732

1733
		}
1734

1735
		if ( _oldFlipSided != object.flipSided ) {
1736

1737 1738 1739 1740
			if( object.flipSided ) {

				_gl.frontFace( _gl.CW );

1741
			} else {
1742 1743 1744 1745

				_gl.frontFace( _gl.CCW );

			}
1746

1747
			_oldFlipSided = object.flipSided;
1748 1749

		}
1750

1751
	};
1752

1753
	function setDepthTest ( test ) {
1754

A
alteredq 已提交
1755 1756 1757
		if ( _oldDepth != test ) {

			if( test ) {
1758

A
alteredq 已提交
1759
				_gl.enable( _gl.DEPTH_TEST );
1760

A
alteredq 已提交
1761
			} else {
1762

A
alteredq 已提交
1763
				_gl.disable( _gl.DEPTH_TEST );
1764

A
alteredq 已提交
1765
			}
1766

A
alteredq 已提交
1767 1768 1769
			_oldDepth = test;

		}
1770

A
alteredq 已提交
1771
	};
1772

1773
	function computeFrustum ( m ) {
1774 1775 1776 1777 1778 1779 1780 1781 1782

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

A
alteredq 已提交
1784
		for ( i = 0; i < 6; i ++ ) {
1785 1786 1787 1788 1789 1790 1791

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

		}

	};
1792

1793
	function isInFrustum ( object ) {
1794

1795
		var distance, matrix = object.matrixWorld,
1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807
		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;

	};
1808

1809
	function addToFixedArray ( where, what ) {
1810

1811 1812
		where.list[ where.count ] = what;
		where.count += 1;
1813

1814
	};
1815

1816
	function unrollImmediateBufferMaterials ( globject ) {
1817

1818 1819 1820 1821 1822 1823 1824
		var i, l, m, ml, material,
			object = globject.object,
			opaque = globject.opaque,
			transparent = globject.transparent;

		transparent.count = 0;
		opaque.count = 0;
1825

1826 1827 1828
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

			material = object.materials[ m ];
1829

1830 1831 1832 1833
			if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending )
				addToFixedArray( transparent, material );
			else
				addToFixedArray( opaque, material );
1834

1835
		}
1836

1837
	};
1838

1839
	function unrollBufferMaterials ( globject ) {
1840

1841 1842 1843 1844 1845 1846 1847 1848
		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;
1849

1850 1851 1852 1853 1854 1855 1856 1857 1858
		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 ];
1859

1860
					if ( material ) {
1861

1862 1863 1864 1865
						if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending )
							addToFixedArray( transparent, material );
						else
							addToFixedArray( opaque, material );
1866

1867 1868 1869 1870 1871 1872 1873
					}

				}

			} else {

				material = meshMaterial;
1874

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

1877
					addToFixedArray( transparent, material );
1878 1879 1880

				} else {

1881 1882
					addToFixedArray( opaque, material );

1883 1884
				}

1885 1886 1887
			}

		}
1888

1889
	};
1890 1891


1892
	function painterSort ( a, b ) {
1893

1894
		return b.z - a.z;
1895 1896

	};
1897

1898
	this.render = function ( scene, camera, renderTarget, forceClear ) {
1899

A
alteredq 已提交
1900
		var i, program, opaque, transparent, material,
1901
			o, ol, oil, webglObject, object, buffer,
A
alteredq 已提交
1902
			lights = scene.lights,
1903 1904
			fog = scene.fog,
			ol;
1905 1906 1907

		camera.matrixAutoUpdate && camera.update();

M
Mr.doob 已提交
1908
		camera.matrixWorldInverse.flattenToArray( _viewMatrixArray );
1909
		camera.projectionMatrix.flattenToArray( _projectionMatrixArray );
M
Mr.doob 已提交
1910

M
Mr.doob 已提交
1911
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
1912
		computeFrustum( _projScreenMatrix );
1913

A
alteredq 已提交
1914
		scene.update( undefined, false, camera );
1915

A
alteredq 已提交
1916
		this.initWebGLObjects( scene );
M
Mr.doob 已提交
1917

A
alteredq 已提交
1918
		setRenderTarget( renderTarget );
M
Mr.doob 已提交
1919

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

1922
			this.clear();
M
Mr.doob 已提交
1923

1924 1925
		}

1926
		// set matrices
1927

1928
		ol = scene.__webglObjects.length;
1929

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

1932 1933
			webglObject = scene.__webglObjects[ o ];
			object = webglObject.object;
M
Mr.doob 已提交
1934

1935
			if ( object.visible ) {
1936 1937

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

1939
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
1940

1941
					setupMatrices( object, camera );
1942

1943
					unrollBufferMaterials( webglObject );
1944

1945
					webglObject.render = true;
1946

1947
					if ( this.sortObjects ) {
1948

1949 1950 1951
						_vector3.copy( object.position );
						_projScreenMatrix.multiplyVector3( _vector3 );

1952
						webglObject.z = _vector3.z;
1953

1954
					}
1955

1956
				} else {
1957

1958
					webglObject.render = false;
1959

1960
				}
1961

1962
			} else {
1963

1964
				webglObject.render = false;
1965

1966
			}
1967

1968
		}
1969

1970
		if ( this.sortObjects ) {
1971

1972
			scene.__webglObjects.sort( painterSort );
1973

1974
		}
1975

1976
		oil = scene.__webglObjectsImmediate.length;
1977

1978
		for ( o = 0; o < oil; o++ ) {
1979

1980 1981
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
1982

1983
			if ( object.visible ) {
1984 1985 1986

				if( object.matrixAutoUpdate ) {

1987
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
1988

A
alteredq 已提交
1989
				}
1990

1991
				setupMatrices( object, camera );
1992

1993
				unrollImmediateBufferMaterials( webglObject );
1994

1995
			}
1996

1997
		}
A
alteredq 已提交
1998

1999 2000
		// opaque pass

2001
		setBlending( THREE.NormalBlending );
2002

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

2005
			webglObject = scene.__webglObjects[ o ];
2006

2007
			if ( webglObject.render ) {
2008

2009 2010 2011
				object = webglObject.object;
				buffer = webglObject.buffer;
				opaque = webglObject.opaque;
2012

2013
				setObjectFaces( object );
2014

2015
				for( i = 0; i < opaque.count; i++ ) {
2016

2017
					material = opaque.list[ i ];
2018

2019
					setDepthTest( material.depthTest );
A
alteredq 已提交
2020
					renderBuffer( camera, lights, fog, material, buffer, object );
2021

2022
				}
2023 2024 2025 2026 2027

			}

		}

A
alteredq 已提交
2028
		// opaque pass (immediate simulator)
2029

2030
		for ( o = 0; o < oil; o++ ) {
2031

2032 2033
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2034

A
alteredq 已提交
2035
			if ( object.visible ) {
2036

2037
				opaque = webglObject.opaque;
2038

2039
				setObjectFaces( object );
2040

2041
				for( i = 0; i < opaque.count; i++ ) {
2042

2043
					material = opaque.list[ i ];
2044

2045
					setDepthTest( material.depthTest );
2046

A
alteredq 已提交
2047
					program = setProgram( camera, lights, fog, material, object );
2048
					object.render( function( object ) { renderBufferImmediate( object, program ); } );
2049

2050
				}
2051

A
alteredq 已提交
2052
			}
2053

A
alteredq 已提交
2054 2055
		}

2056 2057
		// transparent pass

2058
		for ( o = 0; o < ol; o++ ) {
2059

2060
			webglObject = scene.__webglObjects[ o ];
2061

2062
			if ( webglObject.render ) {
2063

2064 2065 2066
				object = webglObject.object;
				buffer = webglObject.buffer;
				transparent = webglObject.transparent;
2067

2068
				setObjectFaces( object );
2069

2070
				for( i = 0; i < transparent.count; i++ ) {
2071

2072
					material = transparent.list[ i ];
2073

2074
					setBlending( material.blending );
2075
					setDepthTest( material.depthTest );
2076

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

2079
				}
2080

2081
			}
M
Mr.doob 已提交
2082

M
Mr.doob 已提交
2083
		}
M
Mr.doob 已提交
2084

2085
		// transparent pass (immediate simulator)
2086

2087
		for ( o = 0; o < oil; o++ ) {
2088

2089 2090
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2091

2092
			if ( object.visible ) {
2093

2094
				transparent = webglObject.transparent;
2095

2096
				setObjectFaces( object );
2097

2098
				for( i = 0; i < transparent.count; i++ ) {
2099

2100
					material = transparent.list[ i ];
2101

2102
					setBlending( material.blending );
2103
					setDepthTest( material.depthTest );
2104

A
alteredq 已提交
2105
					program = setProgram( camera, lights, fog, material, object );
2106
					object.render( function( object ) { renderBufferImmediate( object, program ); } );
2107

2108
				}
2109

2110
			}
2111

2112
		}
2113

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

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

2118
			updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
2119

2120
		}
2121

M
Mr.doob 已提交
2122
	};
M
Mr.doob 已提交
2123

2124
	function setupMatrices ( object, camera ) {
2125

2126 2127
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
		THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
2128

2129
	};
2130

A
alteredq 已提交
2131
	this.initWebGLObjects = function ( scene ) {
2132

2133
		if ( !scene.__webglObjects ) {
2134

2135 2136
			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
2137 2138 2139

		}

M
Mr.doob 已提交
2140
		while ( scene.__objectsAdded.length ) {
2141

M
Mr.doob 已提交
2142 2143
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
2144 2145 2146

		}

M
Mr.doob 已提交
2147
		while ( scene.__objectsRemoved.length ) {
2148

M
Mr.doob 已提交
2149 2150
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
2151 2152

		}
2153

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

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

M
Mr.doob 已提交
2158
			updateObject( scene.__webglObjects[ o ].object, scene );
A
alteredq 已提交
2159 2160 2161

		}

2162
	};
2163

2164
	function addObject ( object, scene ) {
2165

2166
		var g, geometry, geometryGroup;
M
Mr.doob 已提交
2167

2168
		if ( object._modelViewMatrix == undefined ) {
2169

2170
			object._modelViewMatrix = new THREE.Matrix4();
2171

2172 2173 2174
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
2175

2176
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
2177

2178
		}
A
alteredq 已提交
2179

2180
		if ( object instanceof THREE.Mesh ) {
A
alteredq 已提交
2181

2182 2183 2184 2185 2186 2187 2188 2189
			geometry = object.geometry;

			if ( geometry.geometryGroups == undefined ) {

				sortFacesByMaterial( geometry );

			}

2190
			// create separate VBOs per geometry chunk
A
alteredq 已提交
2191

2192
			for ( g in geometry.geometryGroups ) {
A
alteredq 已提交
2193

2194
				geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
2195

2196
				// initialise VBO on the first access
M
Mr.doob 已提交
2197

2198
				if ( ! geometryGroup.__webGLVertexBuffer ) {
M
Mr.doob 已提交
2199

2200 2201
					createMeshBuffers( geometryGroup );
					initMeshBuffers( geometryGroup, object );
A
alteredq 已提交
2202

2203 2204 2205 2206 2207 2208
					geometry.__dirtyVertices = true;
					geometry.__dirtyElements = true;
					geometry.__dirtyUvs = true;
					geometry.__dirtyNormals = true;
					geometry.__dirtyTangents = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
2209

2210
				}
2211

2212
				// create separate wrapper per each use of VBO
2213

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

2216
			}
M
Mr.doob 已提交
2217

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

2220 2221
			geometry = object.geometry;

A
alteredq 已提交
2222 2223 2224 2225 2226 2227 2228 2229 2230 2231
			if( ! geometry.__webGLVertexBuffer ) {

				createRibbonBuffers( geometry );
				initRibbonBuffers( geometry );

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

			}

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

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

2236 2237
			geometry = object.geometry;

2238
			if( ! geometry.__webGLVertexBuffer ) {
M
Mr.doob 已提交
2239

2240 2241
				createLineBuffers( geometry );
				initLineBuffers( geometry );
M
Mr.doob 已提交
2242

2243 2244
				geometry.__dirtyVertices = true;
				geometry.__dirtyColors = true;
M
Mr.doob 已提交
2245

2246
			}
M
Mr.doob 已提交
2247

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

A
alteredq 已提交
2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260
		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

			if ( ! geometry.__webGLVertexBuffer ) {

				createParticleBuffers( geometry );
				initParticleBuffers( geometry );

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

2262
			}
2263

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

A
alteredq 已提交
2266 2267 2268 2269 2270 2271 2272 2273 2274 2275
		} else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes ) {

			addBufferImmediate( scene.__webglObjectsImmediate, object );

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

		}*/

	};

2276
	function updateObject ( object, scene ) {
A
alteredq 已提交
2277

M
Mr.doob 已提交
2278
		var g, geometry, geometryGroup;
A
alteredq 已提交
2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299

		if ( object instanceof THREE.Mesh ) {

			geometry = object.geometry;

			// check all geometry groups

			for ( g in geometry.geometryGroups ) {

				geometryGroup = geometry.geometryGroups[ g ];

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

					setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW );

				}

			}

2300
			geometry.__dirtyVertices = false;
A
alteredq 已提交
2301 2302 2303 2304
			geometry.__dirtyElements = false;
			geometry.__dirtyUvs = false;
			geometry.__dirtyNormals = false;
			geometry.__dirtyTangents = false;
2305
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
2306

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

2309 2310
			geometry = object.geometry;

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

A
alteredq 已提交
2313
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
2314

A
alteredq 已提交
2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326
			}

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

2328
			}
2329

A
alteredq 已提交
2330 2331 2332 2333 2334 2335 2336
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

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

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

2341
			}
M
Mr.doob 已提交
2342

2343 2344
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
2345

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

A
alteredq 已提交
2348
			// it updates itself in render callback
2349 2350

		} else if ( object instanceof THREE.Particle ) {
2351 2352

		}*/
2353

2354
	};
2355

2356
	function removeObject ( object, scene ) {
M
Mr.doob 已提交
2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373

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

			}

		}

	};

2374
	function sortFacesByMaterial ( geometry ) {
2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449

		// 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 = {};

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

				geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0 };

			}

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

					geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0 };

				}

			}

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

		}

	};

2450
	function addBuffer ( objlist, buffer, object ) {
2451

2452 2453 2454 2455
		objlist.push( { buffer: buffer, object: object,
				opaque: { list: [], count: 0 },
				transparent: { list: [], count: 0 }
			} );
M
Mr.doob 已提交
2456

2457
	};
2458

2459
	function addBufferImmediate ( objlist, object ) {
2460

2461 2462 2463 2464
		objlist.push( { object: object,
				opaque: { list: [], count: 0 },
				transparent: { list: [], count: 0 }
			} );
2465

2466
	};
2467

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

2470
		if ( cullFace ) {
M
Mr.doob 已提交
2471

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

2474
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
2475

2476
			} else {
M
Mr.doob 已提交
2477

2478
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
2479

2480
			}
M
Mr.doob 已提交
2481

2482
			if( cullFace == "back" ) {
M
Mr.doob 已提交
2483

2484
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
2485

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

2488
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
2489

2490
			} else {
M
Mr.doob 已提交
2491

2492
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
2493

2494
			}
M
Mr.doob 已提交
2495

2496
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
2497

2498
		} else {
M
Mr.doob 已提交
2499

2500
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
2501

2502 2503 2504
		}

	};
N
Nicolas Garcia Belmonte 已提交
2505

2506
	this.supportsVertexTextures = function () {
2507

2508
		return maxVertexTextures() > 0;
2509

2510
	};
2511

2512
	function maxVertexTextures () {
2513

2514 2515 2516
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
2517

2518
	function initGL ( antialias, clearColor, clearAlpha ) {
N
Nicolas Garcia Belmonte 已提交
2519 2520 2521

		try {

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

2524
				throw 'Error creating WebGL context.';
N
Nicolas Garcia Belmonte 已提交
2525

2526 2527 2528
			}

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

2530
			console.error( e );
N
Nicolas Garcia Belmonte 已提交
2531 2532 2533 2534 2535 2536 2537 2538 2539

		}

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

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

2540 2541
		_gl.frontFace( _gl.CCW );
		_gl.cullFace( _gl.BACK );
2542
		_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
2543

N
Nicolas Garcia Belmonte 已提交
2544
		_gl.enable( _gl.BLEND );
2545
		_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
2546
		_gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
2547

A
alteredq 已提交
2548
		_cullEnabled = true;
N
Nicolas Garcia Belmonte 已提交
2549

2550
	};
M
Mr.doob 已提交
2551

2552
	function buildProgram ( fragmentShader, vertexShader, parameters ) {
M
Mr.doob 已提交
2553

M
Mr.doob 已提交
2554
		var program = _gl.createProgram(),
M
Mr.doob 已提交
2555

M
Mr.doob 已提交
2556 2557 2558 2559
		prefix_fragment = [
			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",
M
Mr.doob 已提交
2560

2561 2562
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
2563

2564 2565
			parameters.fog ? "#define USE_FOG" : "",
			parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "",
2566

2567
			parameters.map ? "#define USE_MAP" : "",
2568 2569 2570
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
2571

2572
			"uniform mat4 viewMatrix;",
2573
			"uniform vec3 cameraPosition;",
M
Mr.doob 已提交
2574 2575
			""
		].join("\n"),
2576

M
Mr.doob 已提交
2577
		prefix_vertex = [
2578
			maxVertexTextures() > 0 ? "#define VERTEX_TEXTURES" : "",
2579

2580 2581 2582
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

2583 2584
			"#define MAX_BONES " + parameters.maxBones,

2585
			parameters.map ? "#define USE_MAP" : "",
2586 2587 2588
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
2589
			parameters.skinning ? "#define USE_SKINNING" : "",
2590

M
Mr.doob 已提交
2591 2592 2593
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
2594 2595
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
2596
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
2597 2598 2599

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
2600 2601
			"attribute vec3 position;",
			"attribute vec3 normal;",
A
alteredq 已提交
2602
			"attribute vec3 color;",
M
Mr.doob 已提交
2603
			"attribute vec2 uv;",
2604
			"attribute vec2 uv2;",
2605

A
alteredq 已提交
2606 2607 2608 2609
			"attribute vec4 skinVertexA;",
			"attribute vec4 skinVertexB;",
			"attribute vec4 skinIndex;",
			"attribute vec4 skinWeight;",
M
Mr.doob 已提交
2610 2611
			""
		].join("\n");
2612

2613 2614
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
2615

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

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

M
Mr.doob 已提交
2620 2621
			alert( "Could not initialise shaders\n"+
					"VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
2622

2623 2624
			//console.log( prefix_fragment + fragmentShader );
			//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
2625

N
Nicolas Garcia Belmonte 已提交
2626
		}
2627

2628 2629
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
2630

M
Mr.doob 已提交
2631
		program.uniforms = {};
2632
		program.attributes = {};
M
Mr.doob 已提交
2633

M
Mr.doob 已提交
2634
		return program;
M
Mr.doob 已提交
2635

M
Mr.doob 已提交
2636
	};
M
Mr.doob 已提交
2637

2638
	function loadUniformsSkinning ( uniforms, object ) {
2639

M
Mr.doob 已提交
2640
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray );
A
alteredq 已提交
2641
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
2642

2643
	};
2644

2645
	function loadUniformsMatrices ( uniforms, object ) {
2646

A
alteredq 已提交
2647 2648 2649 2650
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
		_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );

	};
2651

2652
	function loadUniformsGeneric ( program, uniforms ) {
M
Mr.doob 已提交
2653

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

M
Mr.doob 已提交
2656
		for( u in uniforms ) {
M
Mr.doob 已提交
2657

2658 2659
			location = program.uniforms[u];
			if ( !location ) continue;
M
Mr.doob 已提交
2660

2661
			uniform = uniforms[u];
M
Mr.doob 已提交
2662

2663 2664
			type = uniform.type;
			value = uniform.value;
M
Mr.doob 已提交
2665

M
Mr.doob 已提交
2666
			if( type == "i" ) {
M
Mr.doob 已提交
2667

M
Mr.doob 已提交
2668
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
2669

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

M
Mr.doob 已提交
2672
				_gl.uniform1f( location, value );
2673

A
alteredq 已提交
2674 2675 2676
			} else if( type == "fv1" ) {

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

2678 2679 2680 2681
			} else if( type == "fv" ) {

				_gl.uniform3fv( location, value );

2682 2683 2684 2685
			} else if( type == "v2" ) {

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

2686 2687 2688
			} else if( type == "v3" ) {

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

2690 2691 2692
			} else if( type == "c" ) {

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

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

M
Mr.doob 已提交
2696
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
2697

2698
				texture = uniform.texture;
M
Mr.doob 已提交
2699

2700
				if ( !texture ) continue;
M
Mr.doob 已提交
2701

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

2704
					setCubeTexture( texture, value );
M
Mr.doob 已提交
2705

2706
				} else {
M
Mr.doob 已提交
2707

2708
					setTexture( texture, value );
M
Mr.doob 已提交
2709

2710
				}
M
Mr.doob 已提交
2711

2712
			}
M
Mr.doob 已提交
2713

2714
		}
M
Mr.doob 已提交
2715

2716
	};
M
Mr.doob 已提交
2717

2718
	function setBlending ( blending ) {
A
alteredq 已提交
2719 2720

		if ( blending != _oldBlending ) {
2721

A
alteredq 已提交
2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744
			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;

2745 2746 2747 2748 2749 2750
				case THREE.ReverseSubtractiveBlending:

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

    				break;
A
alteredq 已提交
2751 2752 2753 2754 2755 2756
				default:

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

					break;
2757

A
alteredq 已提交
2758
			}
2759

A
alteredq 已提交
2760
			_oldBlending = blending;
2761

A
alteredq 已提交
2762 2763 2764
		}

	};
2765

2766
	function setTextureParameters ( textureType, texture, image ) {
2767

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

2770 2771
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
2772

2773 2774
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
2775

2776
			_gl.generateMipmap( textureType );
M
Mr.doob 已提交
2777

2778
		} else {
M
Mr.doob 已提交
2779

2780 2781 2782 2783 2784
			_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 已提交
2785

2786
		}
M
Mr.doob 已提交
2787

2788 2789
	};
	
2790
	function setTexture ( texture, slot ) {
2791

2792
		if ( texture.needsUpdate ) {
A
alteredq 已提交
2793

2794
			if ( !texture.__wasSetOnce ) {
M
Mr.doob 已提交
2795

2796
				texture.__webGLTexture = _gl.createTexture();
A
alteredq 已提交
2797

2798 2799
				_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 已提交
2800

A
alteredq 已提交
2801
				texture.__wasSetOnce = true;
M
Mr.doob 已提交
2802

A
alteredq 已提交
2803
			} else {
M
Mr.doob 已提交
2804

A
alteredq 已提交
2805 2806
				_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 已提交
2807 2808 2809

			}

2810 2811 2812
			setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			
A
alteredq 已提交
2813
			texture.needsUpdate = false;
2814 2815 2816 2817

		}

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

2820
	};
M
Mr.doob 已提交
2821

2822
	function setCubeTexture ( texture, slot ) {
2823 2824 2825 2826

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

			if ( texture.needsUpdate ) {
2827 2828
				
				if ( !texture.__wasSetOnce ) {
2829 2830 2831

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

2832
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube );
2833

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

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

2838 2839 2840
					}
				
					texture.__wasSetOnce = true;
2841 2842 2843

				} else {

2844
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube );
2845

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

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

2850
					}
2851 2852 2853

				}

2854
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[0] );
2855 2856 2857
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

				texture.needsUpdate = false;
2858
				
2859 2860 2861 2862 2863 2864 2865 2866 2867
			}

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

		}

	};

2868
	function setRenderTarget ( renderTexture ) {
2869 2870

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

2872 2873 2874 2875 2876
			renderTexture.__webGLFramebuffer = _gl.createFramebuffer();
			renderTexture.__webGLRenderbuffer = _gl.createRenderbuffer();
			renderTexture.__webGLTexture = _gl.createTexture();

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

2878 2879 2880 2881
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTexture.__webGLRenderbuffer );
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTexture.width, renderTexture.height );

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

2883
			_gl.bindTexture( _gl.TEXTURE_2D, renderTexture.__webGLTexture );
2884 2885 2886 2887
			_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 ) );
2888
			_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTexture.format ), renderTexture.width, renderTexture.height, 0, paramThreeToGL( renderTexture.format ), paramThreeToGL( renderTexture.type ), null );
2889 2890

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

2892 2893
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTexture.__webGLFramebuffer );
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, renderTexture.__webGLTexture, 0 );
2894
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webGLRenderbuffer );
2895 2896

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

2898 2899 2900
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
2901

2902 2903
		}

2904
		var framebuffer, width, height;
M
Mr.doob 已提交
2905

2906
		if ( renderTexture ) {
M
Mr.doob 已提交
2907

2908 2909 2910
			framebuffer = renderTexture.__webGLFramebuffer;
			width = renderTexture.width;
			height = renderTexture.height;
M
Mr.doob 已提交
2911

2912
		} else {
M
Mr.doob 已提交
2913

2914
			framebuffer = null;
2915 2916
			width = _viewportWidth;
			height = _viewportHeight;
M
Mr.doob 已提交
2917

2918
		}
M
Mr.doob 已提交
2919

2920
		if( framebuffer != _oldFramebuffer ) {
M
Mr.doob 已提交
2921

2922
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2923
			_gl.viewport( _viewportX, _viewportY, width, height );
M
Mr.doob 已提交
2924

2925
			_oldFramebuffer = framebuffer;
M
Mr.doob 已提交
2926

2927
		}
2928

2929
	};
M
Mr.doob 已提交
2930

2931
	function updateRenderTargetMipmap ( renderTarget ) {
M
Mr.doob 已提交
2932

2933 2934 2935
		_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webGLTexture );
		_gl.generateMipmap( _gl.TEXTURE_2D );
		_gl.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
2936 2937

	};
2938

2939
	function cacheUniformLocations ( program, identifiers ) {
M
Mr.doob 已提交
2940

M
Mr.doob 已提交
2941
		var i, l, id;
M
Mr.doob 已提交
2942

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

2945 2946
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
2947

M
Mr.doob 已提交
2948
		}
M
Mr.doob 已提交
2949

M
Mr.doob 已提交
2950
	};
M
Mr.doob 已提交
2951

2952
	function cacheAttributeLocations ( program, identifiers ) {
2953

2954
		var i, l, id;
M
Mr.doob 已提交
2955

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

2958 2959
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
2960

2961
		}
M
Mr.doob 已提交
2962

M
Mr.doob 已提交
2963
	};
M
Mr.doob 已提交
2964

2965
	function getShader ( type, string ) {
N
Nicolas Garcia Belmonte 已提交
2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989

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

			alert( _gl.getShaderInfoLog( shader ) );
			return null;

		}

		return shader;
M
Mr.doob 已提交
2990

2991
	};
N
Nicolas Garcia Belmonte 已提交
2992

2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010
	// fallback filters for non-power-of-2 textures
	
	function filterFallback ( f ) {
		
		switch ( f ) {

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

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

		}
		
	};
	
3011
	function paramThreeToGL ( p ) {
M
Mr.doob 已提交
3012

3013
		switch ( p ) {
M
Mr.doob 已提交
3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026

			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;

3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040
			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;

3041
		}
M
Mr.doob 已提交
3042

3043
		return 0;
M
Mr.doob 已提交
3044

3045 3046
	};

3047
	function isPowerOfTwo ( value ) {
3048 3049 3050 3051 3052

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

	};

3053
	function materialNeedsSmoothNormals ( material ) {
3054 3055 3056

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

3057
	};
M
Mr.doob 已提交
3058

3059
	function bufferNeedsSmoothNormals ( geometryGroup, object ) {
M
Mr.doob 已提交
3060

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

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

M
Mr.doob 已提交
3065
			meshMaterial = object.materials[ m ];
3066 3067 3068

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

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

3071
					if ( materialNeedsSmoothNormals( geometryGroup.materials[ i ] ) ) {
3072

3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093
						needsSmoothNormals = true;
						break;

					}

				}

			} else {

				if ( materialNeedsSmoothNormals( meshMaterial ) ) {

					needsSmoothNormals = true;
					break;

				}

			}

			if ( needsSmoothNormals ) break;

		}
M
Mr.doob 已提交
3094

3095
		return needsSmoothNormals;
M
Mr.doob 已提交
3096

3097
	};
M
Mr.doob 已提交
3098

3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121
	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 ) {
3122

3123 3124
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
3125

3126
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
3127

3128
			light = lights[ l ];
3129

3130 3131
			if ( light instanceof THREE.DirectionalLight ) dirLights++;
			if ( light instanceof THREE.PointLight ) pointLights++;
3132

3133
		}
3134

3135
		if ( ( pointLights + dirLights ) <= maxLights ) {
3136

3137 3138
			maxDirLights = dirLights;
			maxPointLights = pointLights;
3139

3140
		} else {
3141

3142 3143
			maxDirLights = Math.ceil( maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = maxLights - maxDirLights;
3144 3145 3146

		}

3147
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
3148 3149

	};
M
Mr.doob 已提交
3150

A
alteredq 已提交
3151
	/* DEBUG
3152
	function getGLParams() {
M
Mr.doob 已提交
3153

3154
		var params  = {
M
Mr.doob 已提交
3155

3156 3157
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
3158

3159 3160 3161
			'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 已提交
3162

3163 3164 3165
			'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 已提交
3166

3167 3168
		return params;
	};
M
Mr.doob 已提交
3169

3170
	function dumpObject( obj ) {
M
Mr.doob 已提交
3171

3172 3173
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
3174

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

3177
		}
M
Mr.doob 已提交
3178

3179 3180
		return str;
	}
A
alteredq 已提交
3181
	*/
3182

3183
};
3184

3185
THREE.Snippets = {
M
Mr.doob 已提交
3186

3187
	// FOG
3188

3189
	fog_pars_fragment: [
M
Mr.doob 已提交
3190

3191
	"#ifdef USE_FOG",
3192

3193
		"uniform vec3 fogColor;",
3194

3195 3196 3197 3198 3199 3200
		"#ifdef FOG_EXP2",
			"uniform float fogDensity;",
		"#else",
			"uniform float fogNear;",
			"uniform float fogFar;",
		"#endif",
3201

3202
	"#endif"
3203

3204
	].join("\n"),
M
Mr.doob 已提交
3205

3206
	fog_fragment: [
3207

3208
	"#ifdef USE_FOG",
3209

3210 3211 3212 3213 3214 3215 3216 3217 3218
		"float depth = gl_FragCoord.z / gl_FragCoord.w;",

		"#ifdef FOG_EXP2",
			"const float LOG2 = 1.442695;",
			"float fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );",
			"fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );",
		"#else",
			"float fogFactor = smoothstep( fogNear, fogFar, depth );",
		"#endif",
3219

3220
		"gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );",
M
Mr.doob 已提交
3221

3222
	"#endif"
M
Mr.doob 已提交
3223

3224
	].join("\n"),
M
Mr.doob 已提交
3225

3226
	// ENVIRONMENT MAP
3227

3228
	envmap_pars_fragment: [
M
Mr.doob 已提交
3229

3230
	"#ifdef USE_ENVMAP",
M
Mr.doob 已提交
3231

3232 3233
		"varying vec3 vReflect;",
		"uniform float reflectivity;",
3234
		"uniform samplerCube envMap;",
3235
		"uniform int combine;",
M
Mr.doob 已提交
3236

3237
	"#endif"
M
Mr.doob 已提交
3238

3239
	].join("\n"),
M
Mr.doob 已提交
3240

3241
	envmap_fragment: [
M
Mr.doob 已提交
3242

3243 3244
	"#ifdef USE_ENVMAP",

3245
		"vec4 cubeColor = textureCube( envMap, vec3( -vReflect.x, vReflect.yz ) );",
M
Mr.doob 已提交
3246

3247 3248
		"if ( combine == 1 ) {",

3249 3250
			//"gl_FragColor = mix( gl_FragColor, cubeColor, reflectivity );",
			"gl_FragColor = vec4( mix( gl_FragColor.xyz, cubeColor.xyz, reflectivity ), opacity );",
3251 3252 3253 3254 3255

		"} else {",

			"gl_FragColor = gl_FragColor * cubeColor;",

M
Mr.doob 已提交
3256
		"}",
3257 3258

	"#endif"
M
Mr.doob 已提交
3259

3260
	].join("\n"),
M
Mr.doob 已提交
3261

3262
	envmap_pars_vertex: [
M
Mr.doob 已提交
3263

3264
	"#ifdef USE_ENVMAP",
M
Mr.doob 已提交
3265

3266
		"varying vec3 vReflect;",
3267
		"uniform float refractionRatio;",
3268
		"uniform bool useRefract;",
M
Mr.doob 已提交
3269

3270
	"#endif"
M
Mr.doob 已提交
3271

3272 3273 3274
	].join("\n"),

	envmap_vertex : [
M
Mr.doob 已提交
3275

3276
	"#ifdef USE_ENVMAP",
M
Mr.doob 已提交
3277

3278 3279
		"vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
		"vec3 nWorld = mat3( objectMatrix[0].xyz, objectMatrix[1].xyz, objectMatrix[2].xyz ) * normal;",
M
Mr.doob 已提交
3280

3281 3282
		"if ( useRefract ) {",

3283
			"vReflect = refract( normalize( mPosition.xyz - cameraPosition ), normalize( nWorld.xyz ), refractionRatio );",
3284 3285 3286 3287 3288 3289 3290 3291

		"} else {",

			"vReflect = reflect( normalize( mPosition.xyz - cameraPosition ), normalize( nWorld.xyz ) );",

		"}",

	"#endif"
M
Mr.doob 已提交
3292

3293
	].join("\n"),
3294

3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311
	// COLOR MAP (particles)

	map_particle_pars_fragment: [

	"#ifdef USE_MAP",

		"uniform sampler2D map;",

	"#endif"

	].join("\n"),


	map_particle_fragment: [

	"#ifdef USE_MAP",

A
alteredq 已提交
3312
		"gl_FragColor = gl_FragColor * texture2D( map, gl_PointCoord );",
3313 3314 3315 3316 3317 3318

	"#endif"

	].join("\n"),

	// COLOR MAP (triangles)
M
Mr.doob 已提交
3319

3320
	map_pars_fragment: [
M
Mr.doob 已提交
3321

3322
	"#ifdef USE_MAP",
M
Mr.doob 已提交
3323

3324 3325
		"varying vec2 vUv;",
		"uniform sampler2D map;",
M
Mr.doob 已提交
3326

3327
	"#endif"
M
Mr.doob 已提交
3328

3329
	].join("\n"),
M
Mr.doob 已提交
3330

3331
	map_pars_vertex: [
M
Mr.doob 已提交
3332

3333
	"#ifdef USE_MAP",
M
Mr.doob 已提交
3334

3335 3336 3337
		"varying vec2 vUv;",

	"#endif"
M
Mr.doob 已提交
3338

3339
	].join("\n"),
M
Mr.doob 已提交
3340

3341 3342 3343 3344
	map_fragment: [

	"#ifdef USE_MAP",

A
alteredq 已提交
3345
		"gl_FragColor = gl_FragColor * texture2D( map, vUv );",
3346 3347

	"#endif"
M
Mr.doob 已提交
3348

3349
	].join("\n"),
M
Mr.doob 已提交
3350

3351
	map_vertex: [
M
Mr.doob 已提交
3352

3353
	"#ifdef USE_MAP",
M
Mr.doob 已提交
3354

3355
		"vUv = uv;",
M
Mr.doob 已提交
3356

3357
	"#endif"
M
Mr.doob 已提交
3358

3359
	].join("\n"),
M
Mr.doob 已提交
3360

3361
	// LIGHT MAP
3362

3363 3364 3365 3366 3367
	lightmap_pars_fragment: [

	"#ifdef USE_LIGHTMAP",

		"varying vec2 vUv2;",
3368
		"uniform sampler2D lightMap;",
3369 3370 3371 3372

	"#endif"

	].join("\n"),
3373

3374 3375 3376 3377 3378 3379 3380 3381 3382
	lightmap_pars_vertex: [

	"#ifdef USE_LIGHTMAP",

		"varying vec2 vUv2;",

	"#endif"

	].join("\n"),
3383

3384 3385 3386 3387
	lightmap_fragment: [

	"#ifdef USE_LIGHTMAP",

3388
		"gl_FragColor = gl_FragColor * texture2D( lightMap, vUv2 );",
3389 3390 3391 3392

	"#endif"

	].join("\n"),
3393

3394 3395 3396 3397 3398 3399 3400 3401 3402 3403
	lightmap_vertex: [

	"#ifdef USE_LIGHTMAP",

		"vUv2 = uv2;",

	"#endif"

	].join("\n"),

3404
	lights_pars_vertex: [
M
Mr.doob 已提交
3405

3406 3407
	"uniform bool enableLighting;",
	"uniform vec3 ambientLightColor;",
M
Mr.doob 已提交
3408

3409
	"#if MAX_DIR_LIGHTS > 0",
M
Mr.doob 已提交
3410

3411 3412
		"uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
		"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
M
Mr.doob 已提交
3413

3414 3415 3416
	"#endif",

	"#if MAX_POINT_LIGHTS > 0",
M
Mr.doob 已提交
3417

3418 3419
		"uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
		"uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
M
Mr.doob 已提交
3420

3421 3422 3423
		"#ifdef PHONG",
			"varying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];",
		"#endif",
M
Mr.doob 已提交
3424

3425
	"#endif"
M
Mr.doob 已提交
3426

3427
	].join("\n"),
M
Mr.doob 已提交
3428

3429
	// LIGHTS
3430

3431
	lights_vertex: [
M
Mr.doob 已提交
3432

3433 3434
	"if ( !enableLighting ) {",

A
alteredq 已提交
3435
		"vLightWeighting = vec3( 1.0 );",
3436 3437 3438 3439 3440 3441

	"} else {",

		"vLightWeighting = ambientLightColor;",

		"#if MAX_DIR_LIGHTS > 0",
M
Mr.doob 已提交
3442

3443
		"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
M
Mr.doob 已提交
3444

3445 3446 3447
			"vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
			"float directionalLightWeighting = max( dot( transformedNormal, normalize( lDirection.xyz ) ), 0.0 );",
			"vLightWeighting += directionalLightColor[ i ] * directionalLightWeighting;",
M
Mr.doob 已提交
3448

3449
		"}",
M
Mr.doob 已提交
3450

3451 3452 3453
		"#endif",

		"#if MAX_POINT_LIGHTS > 0",
M
Mr.doob 已提交
3454

3455
		"for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {",
M
Mr.doob 已提交
3456

3457 3458 3459 3460
			"vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
			"vec3 pointLightVector = normalize( lPosition.xyz - mvPosition.xyz );",
			"float pointLightWeighting = max( dot( transformedNormal, pointLightVector ), 0.0 );",
			"vLightWeighting += pointLightColor[ i ] * pointLightWeighting;",
M
Mr.doob 已提交
3461

3462 3463 3464
			"#ifdef PHONG",
				"vPointLightVector[ i ] = pointLightVector;",
			"#endif",
M
Mr.doob 已提交
3465

3466
		"}",
M
Mr.doob 已提交
3467

3468
		"#endif",
M
Mr.doob 已提交
3469

3470
	"}"
M
Mr.doob 已提交
3471

3472
	].join("\n"),
M
Mr.doob 已提交
3473

3474
	lights_pars_fragment: [
M
Mr.doob 已提交
3475

3476 3477 3478
	"#if MAX_DIR_LIGHTS > 0",
		"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
	"#endif",
M
Mr.doob 已提交
3479

3480 3481 3482
	"#if MAX_POINT_LIGHTS > 0",
		"varying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];",
	"#endif",
M
Mr.doob 已提交
3483

3484 3485
	"varying vec3 vViewPosition;",
	"varying vec3 vNormal;"
M
Mr.doob 已提交
3486

3487
	].join("\n"),
M
Mr.doob 已提交
3488

3489
	lights_fragment: [
M
Mr.doob 已提交
3490

3491 3492
	"vec3 normal = normalize( vNormal );",
	"vec3 viewPosition = normalize( vViewPosition );",
3493

A
alteredq 已提交
3494
	"vec4 mColor = vec4( diffuse, opacity );",
3495 3496 3497
	"vec4 mSpecular = vec4( specular, opacity );",

	"#if MAX_POINT_LIGHTS > 0",
M
Mr.doob 已提交
3498

3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519
		"vec4 pointDiffuse  = vec4( 0.0 );",
		"vec4 pointSpecular = vec4( 0.0 );",

		"for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {",

			"vec3 pointVector = normalize( vPointLightVector[ i ] );",
			"vec3 pointHalfVector = normalize( vPointLightVector[ i ] + vViewPosition );",

			"float pointDotNormalHalf = dot( normal, pointHalfVector );",
			"float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );",

			"float pointSpecularWeight = 0.0;",
			"if ( pointDotNormalHalf >= 0.0 )",
				"pointSpecularWeight = pow( pointDotNormalHalf, shininess );",

			"pointDiffuse  += mColor * pointDiffuseWeight;",
			"pointSpecular += mSpecular * pointSpecularWeight;",

			"}",

	"#endif",
M
Mr.doob 已提交
3520

3521
	"#if MAX_DIR_LIGHTS > 0",
M
Mr.doob 已提交
3522

3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544
		"vec4 dirDiffuse  = vec4( 0.0 );",
		"vec4 dirSpecular = vec4( 0.0 );" ,

		"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",

			"vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",

			"vec3 dirVector = normalize( lDirection.xyz );",
			"vec3 dirHalfVector = normalize( lDirection.xyz + vViewPosition );",

			"float dirDotNormalHalf = dot( normal, dirHalfVector );",

			"float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );",

			"float dirSpecularWeight = 0.0;",
			"if ( dirDotNormalHalf >= 0.0 )",
				"dirSpecularWeight = pow( dirDotNormalHalf, shininess );",

			"dirDiffuse  += mColor * dirDiffuseWeight;",
			"dirSpecular += mSpecular * dirSpecularWeight;",

		"}",
M
Mr.doob 已提交
3545

3546 3547 3548 3549 3550 3551 3552
	"#endif",

	"vec4 totalLight = vec4( ambient, opacity );",

	"#if MAX_DIR_LIGHTS > 0",
		"totalLight += dirDiffuse + dirSpecular;",
	"#endif",
M
Mr.doob 已提交
3553

3554 3555
	"#if MAX_POINT_LIGHTS > 0",
		"totalLight += pointDiffuse + pointSpecular;",
A
alteredq 已提交
3556
	"#endif",
3557

A
alteredq 已提交
3558
	"gl_FragColor = gl_FragColor * totalLight;"
3559

A
alteredq 已提交
3560
	].join("\n"),
3561

A
alteredq 已提交
3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578
	// VERTEX COLORS

	color_pars_fragment: [

	"#ifdef USE_COLOR",

		"varying vec3 vColor;",

	"#endif"

	].join("\n"),


	color_fragment: [

	"#ifdef USE_COLOR",

A
alteredq 已提交
3579
		"gl_FragColor = gl_FragColor * vec4( vColor, opacity );",
A
alteredq 已提交
3580 3581 3582 3583

	"#endif"

	].join("\n"),
3584

A
alteredq 已提交
3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603
	color_pars_vertex: [

	"#ifdef USE_COLOR",

		"varying vec3 vColor;",

	"#endif"

	].join("\n"),


	color_vertex: [

	"#ifdef USE_COLOR",

		"vColor = color;",

	"#endif"

3604
	].join("\n"),
3605

3606
	// skinning
3607

3608
	skinning_pars_vertex: [
3609

3610
	"#ifdef USE_SKINNING",
3611

3612
		"uniform mat4 boneGlobalMatrices[ MAX_BONES ];",
3613

3614
	"#endif"
3615

3616
	].join("\n"),
3617

3618
	skinning_vertex: [
3619

3620 3621
	"#ifdef USE_SKINNING",

A
alteredq 已提交
3622 3623
		"gl_Position  = ( boneGlobalMatrices[ int( skinIndex.x ) ] * skinVertexA ) * skinWeight.x;",
		"gl_Position += ( boneGlobalMatrices[ int( skinIndex.y ) ] * skinVertexB ) * skinWeight.y;",
3624

3625 3626
		// this doesn't work, no idea why
		//"gl_Position  = projectionMatrix * cameraInverseMatrix * objectMatrix * gl_Position;",
3627

3628
		"gl_Position  = projectionMatrix * viewMatrix * objectMatrix * gl_Position;",
3629

3630
	"#else",
3631

3632
		"gl_Position = projectionMatrix * mvPosition;",
3633

3634
	"#endif"
3635

3636
	].join("\n")
3637

3638
};
3639

3640
THREE.UniformsLib = {
M
Mr.doob 已提交
3641

3642
	common: {
M
Mr.doob 已提交
3643

A
alteredq 已提交
3644
	"diffuse" : { type: "c", value: new THREE.Color( 0xeeeeee ) },
3645
	"opacity" : { type: "f", value: 1.0 },
3646
	"map"     : { type: "t", value: 0, texture: null },
M
Mr.doob 已提交
3647

3648
	"lightMap"       : { type: "t", value: 2, texture: null },
3649

3650
	"envMap" 		  : { type: "t", value: 1, texture: null },
3651
	"useRefract"	  : { type: "i", value: 0 },
3652
	"reflectivity"    : { type: "f", value: 1.0 },
3653
	"refractionRatio": { type: "f", value: 0.98 },
3654
	"combine"		  : { type: "i", value: 0 },
M
Mr.doob 已提交
3655

3656 3657 3658 3659
	"fogDensity": { type: "f", value: 0.00025 },
	"fogNear"	: { type: "f", value: 1 },
	"fogFar"	: { type: "f", value: 2000 },
	"fogColor"	: { type: "c", value: new THREE.Color( 0xffffff ) }
M
Mr.doob 已提交
3660

3661
	},
M
Mr.doob 已提交
3662

3663
	lights: {
M
Mr.doob 已提交
3664

3665 3666 3667 3668 3669 3670
	"enableLighting" 			: { type: "i", value: 1 },
	"ambientLightColor" 		: { type: "fv", value: [] },
	"directionalLightDirection" : { type: "fv", value: [] },
	"directionalLightColor" 	: { type: "fv", value: [] },
	"pointLightPosition"		: { type: "fv", value: [] },
	"pointLightColor"			: { type: "fv", value: [] }
M
Mr.doob 已提交
3671

3672 3673 3674 3675
	},

	particle: {

A
alteredq 已提交
3676
	"psColor"   : { type: "c", value: new THREE.Color( 0xeeeeee ) },
3677 3678
	"opacity" : { type: "f", value: 1.0 },
	"size" 	  : { type: "f", value: 1.0 },
3679
	"map"     : { type: "t", value: 0, texture: null },
M
Mr.doob 已提交
3680

3681 3682 3683 3684
	"fogDensity": { type: "f", value: 0.00025 },
	"fogNear"	: { type: "f", value: 1 },
	"fogFar"	: { type: "f", value: 2000 },
	"fogColor"	: { type: "c", value: new THREE.Color( 0xffffff ) }
3685

3686
	}
3687

3688 3689
};

3690
THREE.ShaderLib = {
3691

3692
	'depth': {
M
Mr.doob 已提交
3693

3694
		uniforms: { "mNear": { type: "f", value: 1.0 },
3695
					"mFar" : { type: "f", value: 2000.0 },
A
alteredq 已提交
3696
					"opacity" : { type: "f", value: 1.0 }
3697
				  },
3698

3699
		fragmentShader: [
M
Mr.doob 已提交
3700

3701 3702
			"uniform float mNear;",
			"uniform float mFar;",
3703
			"uniform float opacity;",
M
Mr.doob 已提交
3704

3705
			"void main() {",
M
Mr.doob 已提交
3706

3707 3708
				"float depth = gl_FragCoord.z / gl_FragCoord.w;",
				"float color = 1.0 - smoothstep( mNear, mFar, depth );",
3709
				"gl_FragColor = vec4( vec3( color ), opacity );",
M
Mr.doob 已提交
3710

3711
			"}"
M
Mr.doob 已提交
3712

3713
		].join("\n"),
3714

3715
		vertexShader: [
3716

3717
			"void main() {",
3718

3719
				"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
3720

3721
			"}"
3722

3723
		].join("\n")
3724

3725
	},
3726

3727
	'normal': {
M
Mr.doob 已提交
3728

3729
		uniforms: { "opacity" : { type: "f", value: 1.0 } },
3730

3731
		fragmentShader: [
3732

3733
			"uniform float opacity;",
3734
			"varying vec3 vNormal;",
M
Mr.doob 已提交
3735

3736
			"void main() {",
3737

3738
				"gl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );",
M
Mr.doob 已提交
3739

3740
			"}"
M
Mr.doob 已提交
3741

3742
		].join("\n"),
M
Mr.doob 已提交
3743

3744
		vertexShader: [
3745

3746
			"varying vec3 vNormal;",
3747

3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759
			"void main() {",

				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
				"vNormal = normalize( normalMatrix * normal );",

				"gl_Position = projectionMatrix * mvPosition;",

			"}"

		].join("\n")

	},
3760

3761
	'basic': {
M
Mr.doob 已提交
3762

3763
		uniforms: THREE.UniformsLib[ "common" ],
M
Mr.doob 已提交
3764

3765
		fragmentShader: [
3766

A
alteredq 已提交
3767
			"uniform vec3 diffuse;",
3768
			"uniform float opacity;",
M
Mr.doob 已提交
3769

3770
			THREE.Snippets[ "color_pars_fragment" ],
3771
			THREE.Snippets[ "map_pars_fragment" ],
3772
			THREE.Snippets[ "lightmap_pars_fragment" ],
3773 3774
			THREE.Snippets[ "envmap_pars_fragment" ],
			THREE.Snippets[ "fog_pars_fragment" ],
M
Mr.doob 已提交
3775

3776
			"void main() {",
3777

A
alteredq 已提交
3778
				"gl_FragColor = vec4( diffuse, opacity );",
3779

3780
				THREE.Snippets[ "map_fragment" ],
3781
				THREE.Snippets[ "lightmap_fragment" ],
3782
				THREE.Snippets[ "color_fragment" ],
3783 3784
				THREE.Snippets[ "envmap_fragment" ],
				THREE.Snippets[ "fog_fragment" ],
M
Mr.doob 已提交
3785

3786
			"}"
3787

3788
		].join("\n"),
M
Mr.doob 已提交
3789

3790
		vertexShader: [
M
Mr.doob 已提交
3791

3792
			THREE.Snippets[ "map_pars_vertex" ],
3793
			THREE.Snippets[ "lightmap_pars_vertex" ],
3794
			THREE.Snippets[ "envmap_pars_vertex" ],
3795
			THREE.Snippets[ "color_pars_vertex" ],
3796
			THREE.Snippets[ "skinning_pars_vertex" ],
M
Mr.doob 已提交
3797

3798
			"void main() {",
M
Mr.doob 已提交
3799

3800
				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
M
Mr.doob 已提交
3801

3802
				THREE.Snippets[ "map_vertex" ],
3803
				THREE.Snippets[ "lightmap_vertex" ],
3804
				THREE.Snippets[ "envmap_vertex" ],
3805
				THREE.Snippets[ "color_vertex" ],
3806
				THREE.Snippets[ "skinning_vertex" ],
3807

3808
			"}"
3809

3810
		].join("\n")
M
Mr.doob 已提交
3811

3812
	},
3813

3814
	'lambert': {
M
Mr.doob 已提交
3815 3816

		uniforms: Uniforms.merge( [ THREE.UniformsLib[ "common" ],
3817
									THREE.UniformsLib[ "lights" ] ] ),
M
Mr.doob 已提交
3818

3819
		fragmentShader: [
M
Mr.doob 已提交
3820

A
alteredq 已提交
3821
			"uniform vec3 diffuse;",
3822
			"uniform float opacity;",
M
Mr.doob 已提交
3823

3824
			"varying vec3 vLightWeighting;",
M
Mr.doob 已提交
3825

A
alteredq 已提交
3826
			THREE.Snippets[ "color_pars_fragment" ],
3827
			THREE.Snippets[ "map_pars_fragment" ],
3828
			THREE.Snippets[ "lightmap_pars_fragment" ],
3829 3830
			THREE.Snippets[ "envmap_pars_fragment" ],
			THREE.Snippets[ "fog_pars_fragment" ],
M
Mr.doob 已提交
3831

3832
			"void main() {",
M
Mr.doob 已提交
3833

A
alteredq 已提交
3834 3835
				"gl_FragColor = vec4( diffuse, opacity );",
				"gl_FragColor = gl_FragColor * vec4( vLightWeighting, 1.0 );",
3836 3837

				THREE.Snippets[ "map_fragment" ],
3838
				THREE.Snippets[ "lightmap_fragment" ],
A
alteredq 已提交
3839
				THREE.Snippets[ "color_fragment" ],
3840
				THREE.Snippets[ "envmap_fragment" ],
3841 3842 3843 3844 3845 3846
				THREE.Snippets[ "fog_fragment" ],

			"}"

		].join("\n"),

3847
		vertexShader: [
M
Mr.doob 已提交
3848

3849
			"varying vec3 vLightWeighting;",
M
Mr.doob 已提交
3850

3851
			THREE.Snippets[ "map_pars_vertex" ],
3852
			THREE.Snippets[ "lightmap_pars_vertex" ],
3853 3854
			THREE.Snippets[ "envmap_pars_vertex" ],
			THREE.Snippets[ "lights_pars_vertex" ],
A
alteredq 已提交
3855
			THREE.Snippets[ "color_pars_vertex" ],
3856
			THREE.Snippets[ "skinning_pars_vertex" ],
A
alteredq 已提交
3857

3858
			"void main() {",
M
Mr.doob 已提交
3859

3860
				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
M
Mr.doob 已提交
3861

3862
				THREE.Snippets[ "map_vertex" ],
3863
				THREE.Snippets[ "lightmap_vertex" ],
3864
				THREE.Snippets[ "envmap_vertex" ],
A
alteredq 已提交
3865
				THREE.Snippets[ "color_vertex" ],
M
Mr.doob 已提交
3866

3867
				"vec3 transformedNormal = normalize( normalMatrix * normal );",
M
Mr.doob 已提交
3868

3869
				THREE.Snippets[ "lights_vertex" ],
3870
				THREE.Snippets[ "skinning_vertex" ],
3871 3872 3873 3874

			"}"

		].join("\n")
M
Mr.doob 已提交
3875

3876
	},
M
Mr.doob 已提交
3877

3878
	'phong': {
M
Mr.doob 已提交
3879 3880

		uniforms: Uniforms.merge( [ THREE.UniformsLib[ "common" ],
3881
									THREE.UniformsLib[ "lights" ],
M
Mr.doob 已提交
3882

3883
									{ "ambient"  : { type: "c", value: new THREE.Color( 0x050505 ) },
3884 3885 3886
									  "specular" : { type: "c", value: new THREE.Color( 0x111111 ) },
									  "shininess": { type: "f", value: 30 }
									}
M
Mr.doob 已提交
3887

3888
								] ),
M
Mr.doob 已提交
3889

3890
		fragmentShader: [
M
Mr.doob 已提交
3891

A
alteredq 已提交
3892
			"uniform vec3 diffuse;",
3893
			"uniform float opacity;",
M
Mr.doob 已提交
3894

3895 3896 3897
			"uniform vec3 ambient;",
			"uniform vec3 specular;",
			"uniform float shininess;",
M
Mr.doob 已提交
3898

3899
			"varying vec3 vLightWeighting;",
M
Mr.doob 已提交
3900

A
alteredq 已提交
3901
			THREE.Snippets[ "color_pars_fragment" ],
3902
			THREE.Snippets[ "map_pars_fragment" ],
3903
			THREE.Snippets[ "lightmap_pars_fragment" ],
3904 3905 3906
			THREE.Snippets[ "envmap_pars_fragment" ],
			THREE.Snippets[ "fog_pars_fragment" ],
			THREE.Snippets[ "lights_pars_fragment" ],
M
Mr.doob 已提交
3907

3908
			"void main() {",
M
Mr.doob 已提交
3909

A
alteredq 已提交
3910 3911
				"gl_FragColor = vec4( vLightWeighting, 1.0 );",
				THREE.Snippets[ "lights_fragment" ],
3912 3913

				THREE.Snippets[ "map_fragment" ],
3914
				THREE.Snippets[ "lightmap_fragment" ],
A
alteredq 已提交
3915
				THREE.Snippets[ "color_fragment" ],
3916 3917 3918 3919 3920 3921 3922
				THREE.Snippets[ "envmap_fragment" ],
				THREE.Snippets[ "fog_fragment" ],

			"}"

		].join("\n"),

3923
		vertexShader: [
M
Mr.doob 已提交
3924

3925
			"#define PHONG",
M
Mr.doob 已提交
3926

3927 3928 3929
			"varying vec3 vLightWeighting;",
			"varying vec3 vViewPosition;",
			"varying vec3 vNormal;",
M
Mr.doob 已提交
3930

3931
			THREE.Snippets[ "map_pars_vertex" ],
3932
			THREE.Snippets[ "lightmap_pars_vertex" ],
3933 3934
			THREE.Snippets[ "envmap_pars_vertex" ],
			THREE.Snippets[ "lights_pars_vertex" ],
A
alteredq 已提交
3935
			THREE.Snippets[ "color_pars_vertex" ],
3936
			THREE.Snippets[ "skinning_pars_vertex" ],
M
Mr.doob 已提交
3937

3938
			"void main() {",
M
Mr.doob 已提交
3939

3940
				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
M
Mr.doob 已提交
3941

3942
				THREE.Snippets[ "map_vertex" ],
3943
				THREE.Snippets[ "lightmap_vertex" ],
3944
				THREE.Snippets[ "envmap_vertex" ],
A
alteredq 已提交
3945
				THREE.Snippets[ "color_vertex" ],
M
Mr.doob 已提交
3946

3947 3948 3949
				"#ifndef USE_ENVMAP",
					"vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
				"#endif",
M
Mr.doob 已提交
3950

3951
				"vViewPosition = cameraPosition - mPosition.xyz;",
M
Mr.doob 已提交
3952

3953 3954
				"vec3 transformedNormal = normalize( normalMatrix * normal );",
				"vNormal = transformedNormal;",
3955

3956
				THREE.Snippets[ "lights_vertex" ],
3957
				THREE.Snippets[ "skinning_vertex" ],
3958 3959 3960 3961

			"}"

		].join("\n")
M
Mr.doob 已提交
3962

3963
	},
3964

3965 3966 3967 3968
	'particle_basic': {

		uniforms: THREE.UniformsLib[ "particle" ],

3969
		fragmentShader: [
3970

A
alteredq 已提交
3971
			"uniform vec3 psColor;",
3972 3973
			"uniform float opacity;",

A
alteredq 已提交
3974
			THREE.Snippets[ "color_pars_fragment" ],
3975 3976 3977 3978 3979
			THREE.Snippets[ "map_particle_pars_fragment" ],
			THREE.Snippets[ "fog_pars_fragment" ],

			"void main() {",

A
alteredq 已提交
3980
				"gl_FragColor = vec4( psColor, opacity );",
3981 3982

				THREE.Snippets[ "map_particle_fragment" ],
A
alteredq 已提交
3983
				THREE.Snippets[ "color_fragment" ],
3984 3985 3986 3987 3988 3989
				THREE.Snippets[ "fog_fragment" ],

			"}"

		].join("\n"),

3990
		vertexShader: [
3991 3992

			"uniform float size;",
3993

A
alteredq 已提交
3994
			THREE.Snippets[ "color_pars_vertex" ],
3995

3996 3997
			"void main() {",

A
alteredq 已提交
3998
				THREE.Snippets[ "color_vertex" ],
3999

4000 4001 4002 4003 4004 4005 4006 4007 4008 4009
				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",

				"gl_Position = projectionMatrix * mvPosition;",
				"gl_PointSize = size;",
				//"gl_PointSize = 10.0 + 6.0 * mvPosition.z;";

			"}"

		].join("\n")

M
Mr.doob 已提交
4010
	}
A
alteredq 已提交
4011

4012 4013

};