WebGLRenderer.js 91.6 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
	// camera matrices caches
37 38

	_frustum = [
39 40 41 42 43 44 45 46
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4()
	 ],

47
	_projScreenMatrix = new THREE.Matrix4(),
48
	_projectionMatrixArray = new Float32Array( 16 ),
49
	_viewMatrixArray = new Float32Array( 16 ),
50

51
	_vector3 = new THREE.Vector4(),
52

53
	// parameters defaults
M
Mr.doob 已提交
54

55 56 57
	antialias = true,
	clearColor = new THREE.Color( 0x000000 ),
	clearAlpha = 0;
58

59
	if ( parameters ) {
M
Mr.doob 已提交
60

61 62 63
		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 已提交
64

65
	}
M
Mr.doob 已提交
66

N
Nicolas Garcia Belmonte 已提交
67 68
	this.domElement = _canvas;
	this.autoClear = true;
69
	this.sortObjects = true;
N
Nicolas Garcia Belmonte 已提交
70

71
	initGL( antialias, clearColor, clearAlpha );
M
Mr.doob 已提交
72

73 74
	this.context = _gl;

75
	//alert( dumpObject( getGLParams() ) );
M
Mr.doob 已提交
76

77
	this.lights = {
M
Mr.doob 已提交
78 79 80

		ambient: 	 [ 0, 0, 0 ],
		directional: { length: 0, colors: new Array(), positions: new Array() },
81
		point: 		 { length: 0, colors: new Array(), positions: new Array() }
M
Mr.doob 已提交
82

83
	};
M
Mr.doob 已提交
84

N
Nicolas Garcia Belmonte 已提交
85 86 87 88 89 90 91 92
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
		_gl.viewport( 0, 0, _canvas.width, _canvas.height );

	};

93
	this.setClearColorHex = function ( hex, alpha ) {
94

95 96
		var color = new THREE.Color( hex );
		_gl.clearColor( color.r, color.g, color.b, alpha );
97

98
	};
A
alteredq 已提交
99

100
	this.setClearColor = function ( color, alpha ) {
A
alteredq 已提交
101 102 103 104

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

	};
105

N
Nicolas Garcia Belmonte 已提交
106 107 108 109 110 111
	this.clear = function () {

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

	};

M
Mr.doob 已提交
112

A
alteredq 已提交
113
	function setupLights ( program, lights ) {
114

115
		var l, ll, light, r = 0, g = 0, b = 0,
116
			color, position, intensity,
M
Mr.doob 已提交
117

A
alteredq 已提交
118
			zlights = _this.lights,
M
Mr.doob 已提交
119

120 121
			dcolors    = zlights.directional.colors,
			dpositions = zlights.directional.positions,
122

123 124
			pcolors    = zlights.point.colors,
			ppositions = zlights.point.positions,
125

126
			dlength = 0,
127
			plength = 0,
128

129 130
			doffset = 0,
			poffset = 0;
M
Mr.doob 已提交
131

132
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
133

134
			light = lights[ l ];
135 136 137
			color = light.color;
			position = light.position;
			intensity = light.intensity;
138 139 140

			if ( light instanceof THREE.AmbientLight ) {

141 142 143
				r += color.r;
				g += color.g;
				b += color.b;
M
Mr.doob 已提交
144

145
			} else if ( light instanceof THREE.DirectionalLight ) {
146

147
				doffset = dlength * 3;
148

149 150 151
				dcolors[ doffset ]     = color.r * intensity;
				dcolors[ doffset + 1 ] = color.g * intensity;
				dcolors[ doffset + 2 ] = color.b * intensity;
152

153 154 155
				dpositions[ doffset ]     = position.x;
				dpositions[ doffset + 1 ] = position.y;
				dpositions[ doffset + 2 ] = position.z;
156

157
				dlength += 1;
M
Mr.doob 已提交
158

159 160
			} else if( light instanceof THREE.PointLight ) {

161
				poffset = plength * 3;
162

163 164 165
				pcolors[ poffset ]     = color.r * intensity;
				pcolors[ poffset + 1 ] = color.g * intensity;
				pcolors[ poffset + 2 ] = color.b * intensity;
166

167 168 169
				ppositions[ poffset ]     = position.x;
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
M
Mr.doob 已提交
170

171
				plength += 1;
M
Mr.doob 已提交
172

173 174 175
			}

		}
176

177 178
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
179

180 181
		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 已提交
182

183 184
		zlights.point.length = plength;
		zlights.directional.length = dlength;
M
Mr.doob 已提交
185

186 187 188
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
M
Mr.doob 已提交
189

190
	};
M
Mr.doob 已提交
191

192
	function createParticleBuffers ( geometry ) {
M
Mr.doob 已提交
193

194
		geometry.__webGLVertexBuffer = _gl.createBuffer();
195
		geometry.__webGLColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
196

197
	};
M
Mr.doob 已提交
198

199
	function createLineBuffers ( geometry ) {
M
Mr.doob 已提交
200

201
		geometry.__webGLVertexBuffer = _gl.createBuffer();
202
		geometry.__webGLColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
203

204
	};
205

A
alteredq 已提交
206 207 208 209 210 211 212
	function createRibbonBuffers ( geometry ) {

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

	};

213
	function createMeshBuffers( geometryGroup ) {
M
Mr.doob 已提交
214

215 216 217 218 219 220
		geometryGroup.__webGLVertexBuffer = _gl.createBuffer();
		geometryGroup.__webGLNormalBuffer = _gl.createBuffer();
		geometryGroup.__webGLTangentBuffer = _gl.createBuffer();
		geometryGroup.__webGLColorBuffer = _gl.createBuffer();
		geometryGroup.__webGLUVBuffer = _gl.createBuffer();
		geometryGroup.__webGLUV2Buffer = _gl.createBuffer();
221

222 223 224 225
		geometryGroup.__webGLSkinVertexABuffer = _gl.createBuffer();
		geometryGroup.__webGLSkinVertexBBuffer = _gl.createBuffer();
		geometryGroup.__webGLSkinIndicesBuffer = _gl.createBuffer();
		geometryGroup.__webGLSkinWeightsBuffer = _gl.createBuffer();
226

227 228
		geometryGroup.__webGLFaceBuffer = _gl.createBuffer();
		geometryGroup.__webGLLineBuffer = _gl.createBuffer();
M
Mr.doob 已提交
229

230
	};
231

232
	function initLineBuffers( geometry ) {
M
Mr.doob 已提交
233

234 235 236
		var nvertices = geometry.vertices.length;

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

239
		geometry.__webGLLineCount = nvertices;
M
Mr.doob 已提交
240

241
	};
M
Mr.doob 已提交
242

243
	function initRibbonBuffers( geometry ) {
A
alteredq 已提交
244 245 246 247 248 249 250 251 252

		var nvertices = geometry.vertices.length;

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

		geometry.__webGLVertexCount = nvertices;

	};
253

254
	function initParticleBuffers( geometry ) {
255 256 257 258

		var nvertices = geometry.vertices.length;

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

261
		geometry.__sortArray = [];
262 263 264 265 266

		geometry.__webGLParticleCount = nvertices;

	};

267
	function initMeshBuffers( geometryGroup, object ) {
M
Mr.doob 已提交
268

269
		var f, fl, nvertices = 0, ntris = 0, nlines = 0,
M
Mr.doob 已提交
270
			obj_faces = object.geometry.faces,
271
			chunk_faces = geometryGroup.faces;
M
Mr.doob 已提交
272

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

275 276
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
M
Mr.doob 已提交
277

278
			if ( face instanceof THREE.Face3 ) {
M
Mr.doob 已提交
279

280 281 282
				nvertices += 3;
				ntris += 1;
				nlines += 3;
M
Mr.doob 已提交
283

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

286 287
				nvertices += 4;
				ntris += 2;
288
				nlines += 4;
M
Mr.doob 已提交
289

290
			}
M
Mr.doob 已提交
291

292
		}
M
Mr.doob 已提交
293

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

296 297 298 299 300 301
		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 已提交
302

303 304 305 306
		geometryGroup.__skinVertexAArray = new Float32Array( nvertices * 4 );
		geometryGroup.__skinVertexBArray = new Float32Array( nvertices * 4 );
		geometryGroup.__skinIndexArray = new Float32Array( nvertices * 4 );
		geometryGroup.__skinWeightArray = new Float32Array( nvertices * 4 );
307

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

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

313 314
		geometryGroup.__webGLFaceCount = ntris * 3;
		geometryGroup.__webGLLineCount = nlines * 2;
M
Mr.doob 已提交
315

316
	};
M
Mr.doob 已提交
317

318
	function setMeshBuffers( geometryGroup, object, hint ) {
319

320 321
		var f, fl, fi, face, vertexNormals, faceNormal, normal,
			uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4,
322
			c1, c2, c3, c4,
A
alteredq 已提交
323 324 325 326
			sw1, sw2, sw3, sw4,
			si1, si2, si3, si4,
			sa1, sa2, sa3, sa4,
			sb1, sb2, sb3, sb4,
327
			m, ml, i,
328
			vn, uvi, uv2i,
M
Mr.doob 已提交
329

330
		vertexIndex = 0,
331

332 333
		offset = 0,
		offset_uv = 0,
334
		offset_uv2 = 0,
335 336 337 338
		offset_face = 0,
		offset_normal = 0,
		offset_tangent = 0,
		offset_line = 0,
339
		offset_color = 0,
A
alteredq 已提交
340
		offset_skin = 0,
M
Mr.doob 已提交
341

342 343 344 345 346 347
		vertexArray = geometryGroup.__vertexArray,
		uvArray = geometryGroup.__uvArray,
		uv2Array = geometryGroup.__uv2Array,
		normalArray = geometryGroup.__normalArray,
		tangentArray = geometryGroup.__tangentArray,
		colorArray = geometryGroup.__colorArray,
348

349 350 351 352
		skinVertexAArray = geometryGroup.__skinVertexAArray,
		skinVertexBArray = geometryGroup.__skinVertexBArray,
		skinIndexArray = geometryGroup.__skinIndexArray,
		skinWeightArray = geometryGroup.__skinWeightArray,
M
Mr.doob 已提交
353

354 355
		faceArray = geometryGroup.__faceArray,
		lineArray = geometryGroup.__lineArray,
M
Mr.doob 已提交
356

357
		needsSmoothNormals = geometryGroup.__needsSmoothNormals,
358

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

361
		dirtyVertices = geometry.__dirtyVertices,
362 363 364
		dirtyElements = geometry.__dirtyElements,
		dirtyUvs = geometry.__dirtyUvs,
		dirtyNormals = geometry.__dirtyNormals,
365
		dirtyTangents = geometry.__dirtyTangents,
366
		dirtyColors = geometry.__dirtyColors,
M
Mr.doob 已提交
367

368
		vertices = geometry.vertices,
369
		chunk_faces = geometryGroup.faces,
370
		obj_faces = geometry.faces,
371
		obj_uvs = geometry.uvs,
372
		obj_uvs2 = geometry.uvs2,
A
alteredq 已提交
373
		obj_colors = geometry.colors,
374

A
alteredq 已提交
375 376 377 378
		obj_skinVerticesA = geometry.skinVerticesA,
		obj_skinVerticesB = geometry.skinVerticesB,
		obj_skinIndices = geometry.skinIndices,
		obj_skinWeights = geometry.skinWeights;
379

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

382 383 384
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
			uv = obj_uvs[ fi ];
385
			uv2 = obj_uvs2[ fi ];
M
Mr.doob 已提交
386

387
			vertexNormals = face.vertexNormals;
388
			faceNormal = face.normal;
389 390 391

			if ( face instanceof THREE.Face3 ) {

392
				if ( dirtyVertices ) {
M
Mr.doob 已提交
393

394 395 396
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
M
Mr.doob 已提交
397

398 399 400
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
401

402 403 404
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
405

406 407 408
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
M
Mr.doob 已提交
409

410
					offset += 9;
M
Mr.doob 已提交
411

412
				}
413

A
alteredq 已提交
414 415 416
				if ( obj_skinWeights.length ) {

					// weights
417

A
alteredq 已提交
418 419 420
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
421

A
alteredq 已提交
422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437
					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
438

A
alteredq 已提交
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458
					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
459

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

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

A
alteredq 已提交
502
				}
503

504
				if ( dirtyColors && obj_colors.length ) {
505

506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
					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;
521

522 523 524 525
					offset_color += 9;

				}

526
				if ( dirtyTangents && geometry.hasTangents ) {
527

528 529 530
					t1 = vertices[ face.a ].tangent;
					t2 = vertices[ face.b ].tangent;
					t3 = vertices[ face.c ].tangent;
531

532 533 534 535
					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 已提交
536

537 538 539 540
					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 已提交
541

542 543 544 545
					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 已提交
546

547
					offset_tangent += 12;
M
Mr.doob 已提交
548

549 550
				}

551
				if ( dirtyNormals ) {
M
Mr.doob 已提交
552

553 554 555
					if ( vertexNormals.length == 3 && needsSmoothNormals ) {

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

557
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
558

559 560 561
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
562

563
							offset_normal += 3;
M
Mr.doob 已提交
564

565
						}
M
Mr.doob 已提交
566

567
					} else {
568

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

571 572 573
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
574

575
							offset_normal += 3;
M
Mr.doob 已提交
576

577
						}
M
Mr.doob 已提交
578 579

					}
M
Mr.doob 已提交
580

581 582
				}

583
				if ( dirtyUvs && uv ) {
584

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

587
						uvi = uv[ i ];
M
Mr.doob 已提交
588

589 590
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
591

592
						offset_uv += 2;
M
Mr.doob 已提交
593

M
Mr.doob 已提交
594
					}
595 596 597

				}

598 599 600 601 602 603 604 605 606 607 608 609 610 611 612
				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;

					}

				}

613
				if( dirtyElements ) {
M
Mr.doob 已提交
614

615 616 617
					faceArray[ offset_face ] = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
M
Mr.doob 已提交
618

619
					offset_face += 3;
M
Mr.doob 已提交
620

621 622
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
623

624 625
					lineArray[ offset_line + 2 ] = vertexIndex;
					lineArray[ offset_line + 3 ] = vertexIndex + 2;
M
Mr.doob 已提交
626

627 628
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
629

630
					offset_line += 6;
631

632
					vertexIndex += 3;
M
Mr.doob 已提交
633

634
				}
M
Mr.doob 已提交
635

636 637 638

			} else if ( face instanceof THREE.Face4 ) {

639
				if ( dirtyVertices ) {
M
Mr.doob 已提交
640

641 642 643 644
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
					v4 = vertices[ face.d ].position;
M
Mr.doob 已提交
645

646 647 648
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
649

650 651 652
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
653

654 655 656
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
657

658 659 660
					vertexArray[ offset + 9 ] = v4.x;
					vertexArray[ offset + 10 ] = v4.y;
					vertexArray[ offset + 11 ] = v4.z;
M
Mr.doob 已提交
661

662
					offset += 12;
M
Mr.doob 已提交
663

664
				}
665

A
alteredq 已提交
666 667 668
				if ( obj_skinWeights.length ) {

					// weights
669

A
alteredq 已提交
670 671 672 673
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
					sw4 = obj_skinWeights[ face.d ];
674

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

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

A
alteredq 已提交
724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749
					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
750

A
alteredq 已提交
751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775
					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;

776 777
					offset_skin += 16;

A
alteredq 已提交
778
				}
779

780 781 782 783 784
				if ( dirtyColors && obj_colors.length ) {

					c1 = obj_colors[ face.a ];
					c2 = obj_colors[ face.b ];
					c3 = obj_colors[ face.c ];
785
					c4 = obj_colors[ face.d ];
786 787 788 789 790 791 792 793 794 795 796 797

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

799 800 801
					colorArray[ offset_color + 9 ]  = c4.r;
					colorArray[ offset_color + 10 ] = c4.g;
					colorArray[ offset_color + 11 ] = c4.b;
802

803 804
					offset_color += 12;

805 806
				}

807
				if ( dirtyTangents && geometry.hasTangents ) {
808

809 810 811 812
					t1 = vertices[ face.a ].tangent;
					t2 = vertices[ face.b ].tangent;
					t3 = vertices[ face.c ].tangent;
					t4 = vertices[ face.d ].tangent;
813

814 815 816 817
					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 已提交
818

819 820 821 822
					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 已提交
823

824 825 826 827
					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 已提交
828

829 830 831 832
					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 已提交
833

834
					offset_tangent += 16;
M
Mr.doob 已提交
835

836
				}
M
Mr.doob 已提交
837

838
				if( dirtyNormals ) {
M
Mr.doob 已提交
839

840
					if ( vertexNormals.length == 4 && needsSmoothNormals ) {
841

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

844
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
845

846 847 848
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
849

850
							offset_normal += 3;
M
Mr.doob 已提交
851

852
						}
M
Mr.doob 已提交
853

854
					} else {
855

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

858 859 860
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
861

862
							offset_normal += 3;
M
Mr.doob 已提交
863

864
						}
M
Mr.doob 已提交
865 866

					}
M
Mr.doob 已提交
867

868 869
				}

870
				if ( dirtyUvs && uv ) {
871

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

874
						uvi = uv[ i ];
M
Mr.doob 已提交
875

876 877
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
878

879
						offset_uv += 2;
M
Mr.doob 已提交
880

M
Mr.doob 已提交
881
					}
882 883

				}
884

885 886 887 888 889 890 891 892 893 894 895 896 897 898
				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 已提交
899

900
				if( dirtyElements ) {
M
Mr.doob 已提交
901

902 903 904
					faceArray[ offset_face ]     = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
M
Mr.doob 已提交
905

906 907 908
					faceArray[ offset_face + 3 ] = vertexIndex;
					faceArray[ offset_face + 4 ] = vertexIndex + 2;
					faceArray[ offset_face + 5 ] = vertexIndex + 3;
M
Mr.doob 已提交
909

910
					offset_face += 6;
M
Mr.doob 已提交
911

912 913
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
914

915
					lineArray[ offset_line + 2 ] = vertexIndex;
916
					lineArray[ offset_line + 3 ] = vertexIndex + 3;
M
Mr.doob 已提交
917

918 919
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
920

921 922
					lineArray[ offset_line + 6 ] = vertexIndex + 2;
					lineArray[ offset_line + 7 ] = vertexIndex + 3;
M
Mr.doob 已提交
923

924
					offset_line += 8;
M
Mr.doob 已提交
925

926
					vertexIndex += 4;
M
Mr.doob 已提交
927

928
				}
M
Mr.doob 已提交
929

930
			}
M
Mr.doob 已提交
931

932 933
		}

934
		if ( dirtyVertices ) {
M
Mr.doob 已提交
935

936
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
937
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
938

939
		}
M
Mr.doob 已提交
940

941 942
		if ( dirtyColors && obj_colors.length ) {

943
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLColorBuffer );
944 945 946
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}
947

948
		if ( dirtyNormals ) {
M
Mr.doob 已提交
949

950
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLNormalBuffer );
951
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
952

953 954
		}

955
		if ( dirtyTangents && geometry.hasTangents ) {
956

957
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLTangentBuffer );
958
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
M
Mr.doob 已提交
959

960
		}
961

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

964
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUVBuffer );
965
			_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
M
Mr.doob 已提交
966

967
		}
M
Mr.doob 已提交
968

969 970
		if ( dirtyUvs && offset_uv2 > 0 ) {

971
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUV2Buffer );
972 973 974 975
			_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );

		}

976
		if ( dirtyElements ) {
M
Mr.doob 已提交
977

978
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLFaceBuffer );
979
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
980

981
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLLineBuffer );
982
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
M
Mr.doob 已提交
983

984
		}
985

986
		if ( offset_skin > 0 ) {
987

988
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexABuffer );
A
alteredq 已提交
989 990
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );

991
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexBBuffer );
A
alteredq 已提交
992 993
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );

994
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinIndicesBuffer );
A
alteredq 已提交
995 996
			_gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );

997
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinWeightsBuffer );
A
alteredq 已提交
998
			_gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
999

A
alteredq 已提交
1000
		}
1001 1002

	};
1003

1004
	function setLineBuffers( geometry, hint ) {
M
Mr.doob 已提交
1005

1006
		var v, c, vertex, offset,
1007
			vertices = geometry.vertices,
1008
			colors = geometry.colors,
1009
			vl = vertices.length,
1010
			cl = colors.length,
M
Mr.doob 已提交
1011 1012

			vertexArray = geometry.__vertexArray,
1013
			colorArray = geometry.__colorArray,
1014 1015

			dirtyVertices = geometry.__dirtyVertices,
1016
			dirtyColors = geometry.__dirtyColors;
M
Mr.doob 已提交
1017

1018
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1019

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

1022
				vertex = vertices[ v ].position;
M
Mr.doob 已提交
1023

1024
				offset = v * 3;
M
Mr.doob 已提交
1025

1026 1027 1028
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
M
Mr.doob 已提交
1029

1030 1031
			}

A
alteredq 已提交
1032 1033 1034
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

1035
		}
M
Mr.doob 已提交
1036

1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055
		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 );

		}

1056
	};
M
Mr.doob 已提交
1057

1058
	function setRibbonBuffers( geometry, hint ) {
A
alteredq 已提交
1059 1060 1061 1062 1063 1064 1065 1066 1067

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

			vertexArray = geometry.__vertexArray,
			colorArray = geometry.__colorArray,
1068 1069

			dirtyVertices = geometry.__dirtyVertices,
A
alteredq 已提交
1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
			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 );

		}

	};
1111

1112
	function setParticleBuffers( geometry, hint, object ) {
1113

A
alteredq 已提交
1114
		var v, c, vertex, offset,
1115 1116 1117
			vertices = geometry.vertices,
			vl = vertices.length,

A
alteredq 已提交
1118 1119
			colors = geometry.colors,
			cl = colors.length,
1120

1121
			vertexArray = geometry.__vertexArray,
A
alteredq 已提交
1122
			colorArray = geometry.__colorArray,
1123

1124
			sortArray = geometry.__sortArray,
1125

1126 1127 1128
			dirtyVertices = geometry.__dirtyVertices,
			dirtyElements = geometry.__dirtyElements,
			dirtyColors = geometry.__dirtyColors;
1129

1130
		if ( object.sortParticles ) {
1131

1132
			_projScreenMatrix.multiplySelf( object.matrixWorld );
1133

1134 1135 1136
			for ( v = 0; v < vl; v++ ) {

				vertex = vertices[ v ].position;
1137

1138 1139
				_vector3.copy( vertex );
				_projScreenMatrix.multiplyVector3( _vector3 );
1140

1141
				sortArray[ v ] = [ _vector3.z, v ];
1142

1143
			}
1144

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

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

1149
				vertex = vertices[ sortArray[v][1] ].position;
1150

1151
				offset = v * 3;
1152

1153 1154 1155
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
1156

1157
			}
1158

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

A
alteredq 已提交
1161
				offset = c * 3;
1162

A
alteredq 已提交
1163 1164 1165 1166 1167
				color = colors[ sortArray[c][1] ];

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

1169
			}
1170 1171


1172
		} else {
1173

1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186
			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;

				}
1187 1188

			}
1189

A
alteredq 已提交
1190
			if ( dirtyColors ) {
1191

A
alteredq 已提交
1192 1193 1194 1195 1196 1197 1198 1199 1200 1201
				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;

1202
				}
1203

A
alteredq 已提交
1204
			}
1205 1206

		}
1207

A
alteredq 已提交
1208
		if ( dirtyVertices || object.sortParticles ) {
1209

A
alteredq 已提交
1210 1211
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
1212

A
alteredq 已提交
1213
		}
1214

A
alteredq 已提交
1215
		if ( dirtyColors || object.sortParticles ) {
1216

A
alteredq 已提交
1217 1218
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLColorBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
1219

A
alteredq 已提交
1220
		}
1221

1222
	};
M
Mr.doob 已提交
1223

M
Mr.doob 已提交
1224
	function setMaterialShaders( material, shaders ) {
1225

1226 1227
		material.fragmentShader = shaders.fragmentShader;
		material.vertexShader = shaders.vertexShader;
1228
		material.uniforms = Uniforms.clone( shaders.uniforms );
1229

M
Mr.doob 已提交
1230
	};
1231

A
alteredq 已提交
1232
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
1233

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

1237
		// pure color
A
alteredq 已提交
1238
		//uniforms.color.value.setHex( material.color.hex );
M
Mr.doob 已提交
1239

A
alteredq 已提交
1240 1241
		uniforms.opacity.value = material.opacity;
		uniforms.map.texture = material.map;
1242

1243
		uniforms.lightMap.texture = material.lightMap;
1244

1245
		uniforms.envMap.texture = material.envMap;
A
alteredq 已提交
1246
		uniforms.reflectivity.value = material.reflectivity;
1247
		uniforms.refractionRatio.value = material.refractionRatio;
A
alteredq 已提交
1248
		uniforms.combine.value = material.combine;
1249
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
1250

1251
	};
1252

A
alteredq 已提交
1253
	function refreshUniformsLine( uniforms, material ) {
1254

A
alteredq 已提交
1255 1256
		uniforms.diffuse.value.setRGB( material.color.r * material.opacity, material.color.g * material.opacity, material.color.b * material.opacity );
		uniforms.opacity.value = material.opacity;
1257 1258

	};
M
Mr.doob 已提交
1259

A
alteredq 已提交
1260
	function refreshUniformsParticle( uniforms, material ) {
1261

A
alteredq 已提交
1262 1263 1264 1265
		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;
1266

A
alteredq 已提交
1267
	};
1268

A
alteredq 已提交
1269
	function refreshUniformsFog( uniforms, fog ) {
1270

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

A
alteredq 已提交
1273
		if ( fog instanceof THREE.Fog ) {
1274

A
alteredq 已提交
1275 1276
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
1277

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

A
alteredq 已提交
1280
			uniforms.fogDensity.value = fog.density;
1281 1282

		}
1283

1284 1285
	};

A
alteredq 已提交
1286
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
1287

A
alteredq 已提交
1288 1289 1290 1291 1292
		//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 已提交
1293

1294
	};
M
Mr.doob 已提交
1295 1296


A
alteredq 已提交
1297
	function refreshUniformsLights( uniforms, lights ) {
M
Mr.doob 已提交
1298

A
alteredq 已提交
1299 1300 1301 1302 1303 1304
		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 已提交
1305

A
alteredq 已提交
1306
	};
M
Mr.doob 已提交
1307

1308
	this.initMaterial = function( material, lights, fog ) {
M
Mr.doob 已提交
1309

A
alteredq 已提交
1310
		var u, identifiers, parameters, maxLightCount;
1311

A
alteredq 已提交
1312
		if ( material instanceof THREE.MeshDepthMaterial ) {
1313

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

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

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

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

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

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

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

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

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

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

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

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

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

A
alteredq 已提交
1340
		}
1341

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

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

1347
		parameters = { fog: fog, map: material.map, envMap: material.envMap, lightMap: material.lightMap, vertexColors: material.vertexColors,
1348
					   skinning: material.skinning,
A
alteredq 已提交
1349
					   maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point };
1350

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

1353
		identifiers = [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
A
alteredq 已提交
1354
						'cameraInverseMatrix', 'boneGlobalMatrices'
A
alteredq 已提交
1355
						];
A
alteredq 已提交
1356

A
alteredq 已提交
1357
		for( u in material.uniforms ) {
1358

A
alteredq 已提交
1359
			identifiers.push(u);
M
Mr.doob 已提交
1360

A
alteredq 已提交
1361
		}
M
Mr.doob 已提交
1362

A
alteredq 已提交
1363
		cacheUniformLocations( material.program, identifiers );
1364
		cacheAttributeLocations( material.program, [ "position", "normal", "uv", "uv2", "tangent", "color",
A
alteredq 已提交
1365
													 "skinVertexA", "skinVertexB", "skinIndex", "skinWeight" ] );
1366

A
alteredq 已提交
1367
		var attributes = material.program.attributes;
1368

A
alteredq 已提交
1369
		_gl.enableVertexAttribArray( attributes.position );
1370

A
alteredq 已提交
1371
		if ( attributes.color >= 0 ) 	_gl.enableVertexAttribArray( attributes.color );
1372
		if ( attributes.normal >= 0 ) 	_gl.enableVertexAttribArray( attributes.normal );
A
alteredq 已提交
1373
		if ( attributes.tangent >= 0 ) 	_gl.enableVertexAttribArray( attributes.tangent );
1374 1375 1376

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

A
alteredq 已提交
1379 1380 1381 1382
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
1383

A
alteredq 已提交
1384
		}
M
Mr.doob 已提交
1385

1386
	};
1387

1388
	function setProgram( camera, lights, fog, material, object ) {
1389

A
alteredq 已提交
1390
		if ( !material.program ) _this.initMaterial( material, lights, fog );
M
Mr.doob 已提交
1391

1392
		var program = material.program,
A
alteredq 已提交
1393 1394
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
1395

M
Mr.doob 已提交
1396
		if( program != _oldProgram ) {
M
Mr.doob 已提交
1397

M
Mr.doob 已提交
1398 1399
			_gl.useProgram( program );
			_oldProgram = program;
1400

A
alteredq 已提交
1401
			_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );
M
Mr.doob 已提交
1402

M
Mr.doob 已提交
1403
		}
1404

A
alteredq 已提交
1405
		// refresh uniforms common to several materials
1406 1407

		if ( fog && (
A
alteredq 已提交
1408 1409
			 material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
1410
			 material instanceof THREE.MeshPhongMaterial ||
A
alteredq 已提交
1411 1412 1413
			 material instanceof THREE.LineBasicMaterial ||
			 material instanceof THREE.ParticleBasicMaterial )
			) {
1414

A
alteredq 已提交
1415
			refreshUniformsFog( m_uniforms, fog );
1416 1417

		}
M
Mr.doob 已提交
1418

M
Mr.doob 已提交
1419
		if ( material instanceof THREE.MeshPhongMaterial ||
1420
			 material instanceof THREE.MeshLambertMaterial ) {
1421

A
alteredq 已提交
1422 1423
			setupLights( program, lights );
			refreshUniformsLights( m_uniforms, _this.lights );
M
Mr.doob 已提交
1424 1425 1426

		}

1427 1428 1429
		if ( material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
			 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
1430

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

A
alteredq 已提交
1433
		}
M
Mr.doob 已提交
1434

A
alteredq 已提交
1435
		// refresh single material specific uniforms
1436

1437
		if ( material instanceof THREE.LineBasicMaterial ) {
M
Mr.doob 已提交
1438

A
alteredq 已提交
1439
			refreshUniformsLine( m_uniforms, material );
1440

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

A
alteredq 已提交
1443
			refreshUniformsParticle( m_uniforms, material );
1444

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

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

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

1451 1452
			m_uniforms.mNear.value = camera.near;
			m_uniforms.mFar.value = camera.far;
A
alteredq 已提交
1453
			m_uniforms.opacity.value = material.opacity;
1454

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

A
alteredq 已提交
1457
			m_uniforms.opacity.value = material.opacity;
1458

1459
		}
1460

A
alteredq 已提交
1461
		// load common uniforms
1462

A
alteredq 已提交
1463 1464
		loadUniformsGeneric( program, m_uniforms );
		loadUniformsMatrices( p_uniforms, object );
1465

A
alteredq 已提交
1466 1467
		// load material specific uniforms
		// (shader material also gets them for the sake of genericity)
1468

A
alteredq 已提交
1469 1470
		if ( material instanceof THREE.MeshShaderMaterial ||
			 material instanceof THREE.MeshPhongMaterial ||
1471
			 material.envMap ) {
1472

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

1475
		}
1476

A
alteredq 已提交
1477
		if ( material instanceof THREE.MeshShaderMaterial ||
1478
			 material.envMap ||
1479
			 material.skinning ) {
1480

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

A
alteredq 已提交
1483
		}
1484

A
alteredq 已提交
1485 1486
		if ( material instanceof THREE.MeshPhongMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
A
alteredq 已提交
1487
			 material instanceof THREE.MeshShaderMaterial ||
1488 1489
			 material.skinning ) {

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

A
alteredq 已提交
1492
		}
1493

1494
		if ( material.skinning ) {
1495

1496
			loadUniformsSkinning( p_uniforms, object );
1497

A
alteredq 已提交
1498
		}
1499

A
alteredq 已提交
1500
		return program;
1501

A
alteredq 已提交
1502
	};
1503

1504
	function renderBuffer( camera, lights, fog, material, geometryGroup, object ) {
A
alteredq 已提交
1505 1506 1507

		var program, attributes, linewidth, primitives;

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

1510
		attributes = program.attributes;
M
Mr.doob 已提交
1511

1512
		// vertices
M
Mr.doob 已提交
1513

1514
		_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
1515
		_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
1516

A
alteredq 已提交
1517 1518 1519 1520
		// colors

		if ( attributes.color >= 0 ) {

1521
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLColorBuffer );
1522
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
1523 1524 1525

		}

1526
		// normals
M
Mr.doob 已提交
1527

1528
		if ( attributes.normal >= 0 ) {
1529

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

1533
		}
1534

1535 1536 1537
		// tangents

		if ( attributes.tangent >= 0 ) {
1538

1539
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLTangentBuffer );
1540
			_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
1541

1542
		}
1543

1544
		// uvs
M
Mr.doob 已提交
1545

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

1548
			if ( geometryGroup.__webGLUVBuffer ) {
1549

1550
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUVBuffer );
1551
				_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
1552

1553
				_gl.enableVertexAttribArray( attributes.uv );
1554

1555
			} else {
1556

1557
				_gl.disableVertexAttribArray( attributes.uv );
M
Mr.doob 已提交
1558

1559
			}
1560 1561 1562

		}

1563 1564
		if ( attributes.uv2 >= 0 ) {

1565
			if ( geometryGroup.__webGLUV2Buffer ) {
1566

1567
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUV2Buffer );
1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579
				_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );

				_gl.enableVertexAttribArray( attributes.uv2 );

			} else {

				_gl.disableVertexAttribArray( attributes.uv2 );

			}

		}

1580 1581
		if ( material.skinning &&
			 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
A
alteredq 已提交
1582
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
1583

1584
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexABuffer );
A
alteredq 已提交
1585 1586
			_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );

1587
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexBBuffer );
A
alteredq 已提交
1588 1589
			_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );

1590
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinIndicesBuffer );
A
alteredq 已提交
1591 1592
			_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );

1593
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinWeightsBuffer );
A
alteredq 已提交
1594
			_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
1595

A
alteredq 已提交
1596
		}
1597

1598
		// render mesh
M
Mr.doob 已提交
1599

1600
		if ( object instanceof THREE.Mesh ) {
1601

1602
			// wireframe
1603

1604
			if ( material.wireframe ) {
M
Mr.doob 已提交
1605

1606
				_gl.lineWidth( material.wireframeLinewidth );
1607 1608
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webGLLineCount, _gl.UNSIGNED_SHORT, 0 );
1609

1610
			// triangles
1611

1612
			} else {
1613

1614 1615
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
1616

1617
			}
1618

1619
		// render lines
1620

1621
		} else if ( object instanceof THREE.Line ) {
1622

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

1625
			_gl.lineWidth( material.linewidth );
1626
			_gl.drawArrays( primitives, 0, geometryGroup.__webGLLineCount );
1627

1628
		// render particles
1629

1630
		} else if ( object instanceof THREE.ParticleSystem ) {
1631

1632
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webGLParticleCount );
1633

A
alteredq 已提交
1634
		// render ribbon
1635

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

1638
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webGLVertexCount );
1639

1640 1641 1642 1643
		}

	};

A
alteredq 已提交
1644
	function renderBufferImmediate( object, program ) {
1645

A
alteredq 已提交
1646 1647
		if ( ! object.__webGLVertexBuffer ) object.__webGLVertexBuffer = _gl.createBuffer();
		if ( ! object.__webGLNormalBuffer ) object.__webGLNormalBuffer = _gl.createBuffer();
1648

A
alteredq 已提交
1649
		if ( object.hasPos ) {
1650

A
alteredq 已提交
1651 1652 1653 1654
		  _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 );
1655

A
alteredq 已提交
1656
		}
1657

A
alteredq 已提交
1658
		if ( object.hasNormal ) {
1659

A
alteredq 已提交
1660 1661 1662 1663
		  _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 );
1664

A
alteredq 已提交
1665
		}
1666

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

A
alteredq 已提交
1669
		object.count = 0;
1670

A
alteredq 已提交
1671
	};
1672

1673
	function setObjectFaces( object ) {
1674

1675
		if ( _oldDoubleSided != object.doubleSided ) {
1676

1677
			if( object.doubleSided ) {
1678

1679
				_gl.disable( _gl.CULL_FACE );
1680

1681
			} else {
1682

A
alteredq 已提交
1683
				_gl.enable( _gl.CULL_FACE );
1684

A
alteredq 已提交
1685
			}
1686

1687
			_oldDoubleSided = object.doubleSided;
1688

1689
		}
1690

1691
		if ( _oldFlipSided != object.flipSided ) {
1692

1693 1694 1695 1696
			if( object.flipSided ) {

				_gl.frontFace( _gl.CW );

1697
			} else {
1698 1699 1700 1701

				_gl.frontFace( _gl.CCW );

			}
1702

1703
			_oldFlipSided = object.flipSided;
1704 1705

		}
1706

1707
	};
1708

A
alteredq 已提交
1709
	function setDepthTest( test ) {
1710

A
alteredq 已提交
1711 1712 1713
		if ( _oldDepth != test ) {

			if( test ) {
1714

A
alteredq 已提交
1715
				_gl.enable( _gl.DEPTH_TEST );
1716

A
alteredq 已提交
1717
			} else {
1718

A
alteredq 已提交
1719
				_gl.disable( _gl.DEPTH_TEST );
1720

A
alteredq 已提交
1721
			}
1722

A
alteredq 已提交
1723 1724 1725
			_oldDepth = test;

		}
1726

A
alteredq 已提交
1727
	};
1728

1729 1730 1731 1732 1733 1734 1735 1736 1737 1738
	function computeFrustum( m ) {

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

A
alteredq 已提交
1740
		for ( i = 0; i < 6; i ++ ) {
1741 1742 1743 1744 1745 1746 1747

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

		}

	};
1748

1749 1750
	function isInFrustum( object ) {

1751
		var distance, matrix = object.matrixWorld,
1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763
		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;

	};
1764 1765

	function addToFixedArray( where, what ) {
1766

1767 1768
		where.list[ where.count ] = what;
		where.count += 1;
1769

1770
	};
1771

1772
	function unrollImmediateBufferMaterials( globject ) {
1773

1774 1775 1776 1777 1778 1779 1780
		var i, l, m, ml, material,
			object = globject.object,
			opaque = globject.opaque,
			transparent = globject.transparent;

		transparent.count = 0;
		opaque.count = 0;
1781

1782 1783 1784
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

			material = object.materials[ m ];
1785

1786 1787 1788 1789
			if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending )
				addToFixedArray( transparent, material );
			else
				addToFixedArray( opaque, material );
1790

1791
		}
1792

1793
	};
1794

1795
	function unrollBufferMaterials( globject ) {
1796

1797 1798 1799 1800 1801 1802 1803 1804
		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;
1805

1806 1807 1808 1809 1810 1811 1812 1813 1814
		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 ];
1815

1816
					if ( material ) {
1817

1818 1819 1820 1821
						if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending )
							addToFixedArray( transparent, material );
						else
							addToFixedArray( opaque, material );
1822

1823 1824 1825 1826 1827 1828 1829
					}

				}

			} else {

				material = meshMaterial;
1830

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

1833
					addToFixedArray( transparent, material );
1834 1835 1836

				} else {

1837 1838
					addToFixedArray( opaque, material );

1839 1840
				}

1841 1842 1843
			}

		}
1844

1845
	};
1846 1847


1848
	function painterSort( a, b ) {
1849

1850
		return b.z - a.z;
1851 1852

	};
1853

A
alteredq 已提交
1854
	this.render = function( scene, camera, renderTarget, clear ) {
1855

A
alteredq 已提交
1856
		var i, program, opaque, transparent, material,
1857
			o, ol, oil, webglObject, object, buffer,
A
alteredq 已提交
1858
			lights = scene.lights,
1859 1860
			fog = scene.fog,
			ol;
1861 1862 1863

		camera.matrixAutoUpdate && camera.update();

M
Mr.doob 已提交
1864
		camera.matrixWorldInverse.flattenToArray( _viewMatrixArray );
1865
		camera.projectionMatrix.flattenToArray( _projectionMatrixArray );
M
Mr.doob 已提交
1866

M
Mr.doob 已提交
1867
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
1868
		computeFrustum( _projScreenMatrix );
1869

A
alteredq 已提交
1870
		scene.update( undefined, false, camera );
1871

1872
		this.initWebGLObjects( scene, camera );
M
Mr.doob 已提交
1873

M
Mr.doob 已提交
1874 1875
		setRenderTarget( renderTarget, clear !== undefined ? clear : true );

1876
		if ( this.autoClear ) {
M
Mr.doob 已提交
1877

1878
			this.clear();
M
Mr.doob 已提交
1879

1880 1881
		}

1882
		// set matrices
1883

1884
		ol = scene.__webglObjects.length;
1885

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

1888 1889
			webglObject = scene.__webglObjects[ o ];
			object = webglObject.object;
M
Mr.doob 已提交
1890

1891
			if ( object.visible ) {
1892 1893

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

1895
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
1896

1897
					setupMatrices( object, camera );
1898

1899
					unrollBufferMaterials( webglObject );
1900

1901
					webglObject.render = true;
1902

1903
					if ( this.sortObjects ) {
1904

1905 1906 1907
						_vector3.copy( object.position );
						_projScreenMatrix.multiplyVector3( _vector3 );

1908
						webglObject.z = _vector3.z;
1909

1910
					}
1911

1912
				} else {
1913

1914
					webglObject.render = false;
1915

1916
				}
1917

1918
			} else {
1919

1920
				webglObject.render = false;
1921

1922
			}
1923

1924
		}
1925

1926
		if ( this.sortObjects ) {
1927

1928
			scene.__webglObjects.sort( painterSort );
1929

1930
		}
1931

1932
		oil = scene.__webglObjectsImmediate.length;
1933

1934
		for ( o = 0; o < oil; o++ ) {
1935

1936 1937
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
1938

1939
			if ( object.visible ) {
1940 1941 1942

				if( object.matrixAutoUpdate ) {

1943
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
1944

A
alteredq 已提交
1945
				}
1946

1947
				setupMatrices( object, camera );
1948

1949
				unrollImmediateBufferMaterials( webglObject );
1950

1951
			}
1952

1953
		}
A
alteredq 已提交
1954

1955 1956
		// opaque pass

1957
		setBlending( THREE.NormalBlending );
1958

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

1961
			webglObject = scene.__webglObjects[ o ];
1962

1963
			if ( webglObject.render ) {
1964

1965 1966 1967
				object = webglObject.object;
				buffer = webglObject.buffer;
				opaque = webglObject.opaque;
1968

1969
				setObjectFaces( object );
1970

1971
				for( i = 0; i < opaque.count; i++ ) {
1972

1973
					material = opaque.list[ i ];
1974

1975
					setDepthTest( material.depthTest );
A
alteredq 已提交
1976
					renderBuffer( camera, lights, fog, material, buffer, object );
1977

1978
				}
1979 1980 1981 1982 1983

			}

		}

A
alteredq 已提交
1984
		// opaque pass (immediate simulator)
1985

1986
		for ( o = 0; o < oil; o++ ) {
1987

1988 1989
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
1990

A
alteredq 已提交
1991
			if ( object.visible ) {
1992

1993
				opaque = webglObject.opaque;
1994

1995
				setObjectFaces( object );
1996

1997
				for( i = 0; i < opaque.count; i++ ) {
1998

1999
					material = opaque.list[ i ];
2000

2001
					setDepthTest( material.depthTest );
2002

A
alteredq 已提交
2003
					program = setProgram( camera, lights, fog, material, object );
2004
					object.render( function( object ) { renderBufferImmediate( object, program ); } );
2005

2006
				}
2007

A
alteredq 已提交
2008
			}
2009

A
alteredq 已提交
2010 2011
		}

2012 2013
		// transparent pass

2014
		for ( o = 0; o < ol; o++ ) {
2015

2016
			webglObject = scene.__webglObjects[ o ];
2017

2018
			if ( webglObject.render ) {
2019

2020 2021 2022
				object = webglObject.object;
				buffer = webglObject.buffer;
				transparent = webglObject.transparent;
2023

2024
				setObjectFaces( object );
2025

2026
				for( i = 0; i < transparent.count; i++ ) {
2027

2028
					material = transparent.list[ i ];
2029

2030
					setBlending( material.blending );
2031
					setDepthTest( material.depthTest );
2032

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

2035
				}
2036

2037
			}
M
Mr.doob 已提交
2038

M
Mr.doob 已提交
2039
		}
M
Mr.doob 已提交
2040

2041
		// transparent pass (immediate simulator)
2042

2043
		for ( o = 0; o < oil; o++ ) {
2044

2045 2046
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2047

2048
			if ( object.visible ) {
2049

2050
				transparent = webglObject.transparent;
2051

2052
				setObjectFaces( object );
2053

2054
				for( i = 0; i < transparent.count; i++ ) {
2055

2056
					material = transparent.list[ i ];
2057

2058
					setBlending( material.blending );
2059
					setDepthTest( material.depthTest );
2060

A
alteredq 已提交
2061
					program = setProgram( camera, lights, fog, material, object );
2062
					object.render( function( object ) { renderBufferImmediate( object, program ); } );
2063

2064
				}
2065

2066
			}
2067

2068
		}
2069

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

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

2074
			updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
2075

2076
		}
2077

M
Mr.doob 已提交
2078
	};
M
Mr.doob 已提交
2079

2080
	function setupMatrices( object, camera ) {
2081

2082 2083
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
		THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
2084

2085
	};
2086

2087
	this.initWebGLObjects = function ( scene, camera ) {
2088

2089
		if ( !scene.__webglObjects ) {
2090

2091 2092
			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
2093 2094 2095

		}

M
Mr.doob 已提交
2096
		while ( scene.__objectsAdded.length ) {
2097

M
Mr.doob 已提交
2098 2099
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
2100 2101 2102

		}

M
Mr.doob 已提交
2103
		while ( scene.__objectsRemoved.length ) {
2104

M
Mr.doob 已提交
2105 2106
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
2107 2108

		}
2109

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

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

M
Mr.doob 已提交
2114
			updateObject( scene.__webglObjects[ o ].object, scene );
A
alteredq 已提交
2115 2116 2117

		}

2118
	};
2119

2120
	function addObject( object, scene ) {
2121

2122
		var g, geometry, geometryGroup;
M
Mr.doob 已提交
2123

2124
		if ( object._modelViewMatrix == undefined ) {
2125

2126
			object._modelViewMatrix = new THREE.Matrix4();
2127

2128 2129 2130
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
2131

2132
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
2133

2134
		}
A
alteredq 已提交
2135

2136
		if ( object instanceof THREE.Mesh ) {
A
alteredq 已提交
2137

2138 2139 2140 2141 2142 2143 2144 2145
			geometry = object.geometry;

			if ( geometry.geometryGroups == undefined ) {

				sortFacesByMaterial( geometry );

			}

2146
			// create separate VBOs per geometry chunk
A
alteredq 已提交
2147

2148
			for ( g in geometry.geometryGroups ) {
A
alteredq 已提交
2149

2150
				geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
2151

2152
				// initialise VBO on the first access
M
Mr.doob 已提交
2153

2154
				if ( ! geometryGroup.__webGLVertexBuffer ) {
M
Mr.doob 已提交
2155

2156 2157
					createMeshBuffers( geometryGroup );
					initMeshBuffers( geometryGroup, object );
A
alteredq 已提交
2158

2159 2160 2161 2162 2163 2164
					geometry.__dirtyVertices = true;
					geometry.__dirtyElements = true;
					geometry.__dirtyUvs = true;
					geometry.__dirtyNormals = true;
					geometry.__dirtyTangents = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
2165

2166
				}
2167

2168
				// create separate wrapper per each use of VBO
2169

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

2172
			}
M
Mr.doob 已提交
2173

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

2176 2177
			geometry = object.geometry;

A
alteredq 已提交
2178 2179 2180 2181 2182 2183 2184 2185 2186 2187
			if( ! geometry.__webGLVertexBuffer ) {

				createRibbonBuffers( geometry );
				initRibbonBuffers( geometry );

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

			}

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

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

2192 2193
			geometry = object.geometry;

2194
			if( ! geometry.__webGLVertexBuffer ) {
M
Mr.doob 已提交
2195

2196 2197
				createLineBuffers( geometry );
				initLineBuffers( geometry );
M
Mr.doob 已提交
2198

2199 2200
				geometry.__dirtyVertices = true;
				geometry.__dirtyColors = true;
M
Mr.doob 已提交
2201

2202
			}
M
Mr.doob 已提交
2203

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

A
alteredq 已提交
2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216
		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

			if ( ! geometry.__webGLVertexBuffer ) {

				createParticleBuffers( geometry );
				initParticleBuffers( geometry );

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

2218
			}
2219

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

A
alteredq 已提交
2222 2223 2224 2225 2226 2227 2228 2229 2230 2231
		} else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes ) {

			addBufferImmediate( scene.__webglObjectsImmediate, object );

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

		}*/

	};

M
Mr.doob 已提交
2232
	function updateObject( object, scene ) {
A
alteredq 已提交
2233

M
Mr.doob 已提交
2234
		var g, geometry, geometryGroup;
A
alteredq 已提交
2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255

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

				}

			}

2256
			geometry.__dirtyVertices = false;
A
alteredq 已提交
2257 2258 2259 2260
			geometry.__dirtyElements = false;
			geometry.__dirtyUvs = false;
			geometry.__dirtyNormals = false;
			geometry.__dirtyTangents = false;
2261
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
2262

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

2265 2266
			geometry = object.geometry;

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

A
alteredq 已提交
2269
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
2270

A
alteredq 已提交
2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282
			}

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

2284
			}
2285

A
alteredq 已提交
2286 2287 2288 2289 2290 2291 2292
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

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

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

2297
			}
M
Mr.doob 已提交
2298

2299 2300
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
2301

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

A
alteredq 已提交
2304
			// it updates itself in render callback
2305 2306

		} else if ( object instanceof THREE.Particle ) {
2307 2308

		}*/
2309

2310
	};
2311

M
Mr.doob 已提交
2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329
	function removeObject( object, scene ) {

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

			}

		}

	};

2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 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
	function sortFacesByMaterial( geometry ) {

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

		}

	};

2406
	function addBuffer( objlist, buffer, object ) {
2407

2408 2409 2410 2411
		objlist.push( { buffer: buffer, object: object,
				opaque: { list: [], count: 0 },
				transparent: { list: [], count: 0 }
			} );
M
Mr.doob 已提交
2412

2413
	};
2414

2415
	function addBufferImmediate( objlist, object ) {
2416

2417 2418 2419 2420
		objlist.push( { object: object,
				opaque: { list: [], count: 0 },
				transparent: { list: [], count: 0 }
			} );
2421

2422
	};
2423

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

2426
		if ( cullFace ) {
M
Mr.doob 已提交
2427

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

2430
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
2431

2432
			} else {
M
Mr.doob 已提交
2433

2434
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
2435

2436
			}
M
Mr.doob 已提交
2437

2438
			if( cullFace == "back" ) {
M
Mr.doob 已提交
2439

2440
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
2441

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

2444
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
2445

2446
			} else {
M
Mr.doob 已提交
2447

2448
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
2449

2450
			}
M
Mr.doob 已提交
2451

2452
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
2453

2454
		} else {
M
Mr.doob 已提交
2455

2456
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
2457

2458 2459 2460
		}

	};
N
Nicolas Garcia Belmonte 已提交
2461

2462
	this.supportsVertexTextures = function() {
2463

2464
		return maxVertexTextures() > 0;
2465

2466
	};
2467

2468
	function maxVertexTextures() {
2469

2470 2471 2472
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
2473

2474
	function initGL( antialias, clearColor, clearAlpha ) {
N
Nicolas Garcia Belmonte 已提交
2475 2476 2477

		try {

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

2480
				throw 'Error creating WebGL context.';
N
Nicolas Garcia Belmonte 已提交
2481

2482 2483 2484
			}

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

2486
			console.error( e );
N
Nicolas Garcia Belmonte 已提交
2487 2488 2489 2490 2491 2492 2493 2494 2495

		}

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

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

2496 2497
		_gl.frontFace( _gl.CCW );
		_gl.cullFace( _gl.BACK );
2498
		_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
2499

N
Nicolas Garcia Belmonte 已提交
2500
		_gl.enable( _gl.BLEND );
2501
		_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
2502
		_gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
2503

A
alteredq 已提交
2504
		_cullEnabled = true;
N
Nicolas Garcia Belmonte 已提交
2505

2506
	};
M
Mr.doob 已提交
2507

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

M
Mr.doob 已提交
2510
		var program = _gl.createProgram(),
M
Mr.doob 已提交
2511

M
Mr.doob 已提交
2512 2513 2514 2515
		prefix_fragment = [
			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",
M
Mr.doob 已提交
2516

2517 2518
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
2519

2520 2521
			parameters.fog ? "#define USE_FOG" : "",
			parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "",
2522

2523
			parameters.map ? "#define USE_MAP" : "",
2524 2525 2526
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
2527

2528
			"uniform mat4 viewMatrix;",
2529
			"uniform vec3 cameraPosition;",
M
Mr.doob 已提交
2530 2531
			""
		].join("\n"),
2532

M
Mr.doob 已提交
2533
		prefix_vertex = [
2534
			maxVertexTextures() > 0 ? "#define VERTEX_TEXTURES" : "",
2535

2536 2537 2538
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

2539
			parameters.map ? "#define USE_MAP" : "",
2540 2541 2542
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
2543
			parameters.skinning ? "#define USE_SKINNING" : "",
2544

M
Mr.doob 已提交
2545 2546 2547
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
2548 2549
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
2550
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
2551 2552 2553

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
2554 2555
			"attribute vec3 position;",
			"attribute vec3 normal;",
A
alteredq 已提交
2556
			"attribute vec3 color;",
M
Mr.doob 已提交
2557
			"attribute vec2 uv;",
2558
			"attribute vec2 uv2;",
2559

A
alteredq 已提交
2560 2561 2562 2563
			"attribute vec4 skinVertexA;",
			"attribute vec4 skinVertexB;",
			"attribute vec4 skinIndex;",
			"attribute vec4 skinWeight;",
M
Mr.doob 已提交
2564 2565
			""
		].join("\n");
2566

2567 2568
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
2569

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

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

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

2577 2578
			//console.log( prefix_fragment + fragmentShader );
			//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
2579

N
Nicolas Garcia Belmonte 已提交
2580
		}
2581

2582 2583
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
2584

M
Mr.doob 已提交
2585
		program.uniforms = {};
2586
		program.attributes = {};
M
Mr.doob 已提交
2587

M
Mr.doob 已提交
2588
		return program;
M
Mr.doob 已提交
2589

M
Mr.doob 已提交
2590
	};
M
Mr.doob 已提交
2591

2592
	function loadUniformsSkinning( uniforms, object ) {
2593

M
Mr.doob 已提交
2594
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray );
A
alteredq 已提交
2595
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
2596

2597
	};
2598

A
alteredq 已提交
2599
	function loadUniformsMatrices( uniforms, object ) {
2600

A
alteredq 已提交
2601 2602 2603 2604
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
		_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );

	};
2605

A
alteredq 已提交
2606
	function loadUniformsGeneric( program, uniforms ) {
M
Mr.doob 已提交
2607

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

M
Mr.doob 已提交
2610
		for( u in uniforms ) {
M
Mr.doob 已提交
2611

2612 2613
			location = program.uniforms[u];
			if ( !location ) continue;
M
Mr.doob 已提交
2614

2615
			uniform = uniforms[u];
M
Mr.doob 已提交
2616

2617 2618
			type = uniform.type;
			value = uniform.value;
M
Mr.doob 已提交
2619

M
Mr.doob 已提交
2620
			if( type == "i" ) {
M
Mr.doob 已提交
2621

M
Mr.doob 已提交
2622
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
2623

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

M
Mr.doob 已提交
2626
				_gl.uniform1f( location, value );
2627

A
alteredq 已提交
2628 2629 2630
			} else if( type == "fv1" ) {

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

2632 2633 2634 2635
			} else if( type == "fv" ) {

				_gl.uniform3fv( location, value );

2636 2637 2638 2639
			} else if( type == "v2" ) {

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

2640 2641 2642
			} else if( type == "v3" ) {

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

2644 2645 2646
			} else if( type == "c" ) {

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

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

M
Mr.doob 已提交
2650
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
2651

2652
				texture = uniform.texture;
M
Mr.doob 已提交
2653

2654
				if ( !texture ) continue;
M
Mr.doob 已提交
2655

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

2658
					setCubeTexture( texture, value );
M
Mr.doob 已提交
2659

2660
				} else {
M
Mr.doob 已提交
2661

2662
					setTexture( texture, value );
M
Mr.doob 已提交
2663

2664
				}
M
Mr.doob 已提交
2665

2666
			}
M
Mr.doob 已提交
2667

2668
		}
M
Mr.doob 已提交
2669

2670
	};
M
Mr.doob 已提交
2671

A
alteredq 已提交
2672 2673 2674
	function setBlending( blending ) {

		if ( blending != _oldBlending ) {
2675

A
alteredq 已提交
2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698
			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;

2699 2700 2701 2702 2703 2704
				case THREE.ReverseSubtractiveBlending:

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

    				break;
A
alteredq 已提交
2705 2706 2707 2708 2709 2710
				default:

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

					break;
2711

A
alteredq 已提交
2712
			}
2713

A
alteredq 已提交
2714
			_oldBlending = blending;
2715

A
alteredq 已提交
2716 2717 2718
		}

	};
2719

2720
	function setTexture( texture, slot ) {
2721

2722
		if ( texture.needsUpdate ) {
M
Mr.doob 已提交
2723

2724
			if ( !texture.__wasSetOnce ) {
M
Mr.doob 已提交
2725

2726
				texture.__webGLTexture = _gl.createTexture();
M
Mr.doob 已提交
2727

2728 2729
				_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 已提交
2730

2731
				if ( isPowerOfTwo( texture.image.width ) && isPowerOfTwo( texture.image.height ) ) {
M
Mr.doob 已提交
2732

2733 2734
					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
2735

2736 2737
					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
2738

2739
					_gl.generateMipmap( _gl.TEXTURE_2D );
2740

2741
				} else {
A
alteredq 已提交
2742

2743 2744 2745
					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.LINEAR );
					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
M
Mr.doob 已提交
2746

2747
				}
A
alteredq 已提交
2748 2749

				_gl.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
2750

A
alteredq 已提交
2751
				texture.__wasSetOnce = true;
M
Mr.doob 已提交
2752

A
alteredq 已提交
2753
			} else {
M
Mr.doob 已提交
2754

A
alteredq 已提交
2755 2756
				_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 已提交
2757

2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774
				if ( isPowerOfTwo( texture.image.width ) && isPowerOfTwo( texture.image.height ) ) {

					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );

					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );

					_gl.generateMipmap( _gl.TEXTURE_2D );

				} else {

					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.LINEAR );
					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );

				}
M
Mr.doob 已提交
2775

A
alteredq 已提交
2776
				_gl.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
2777 2778 2779

			}

A
alteredq 已提交
2780
			texture.needsUpdate = false;
2781 2782 2783 2784

		}

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

2787
	};
M
Mr.doob 已提交
2788

2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806
	function setCubeTexture( texture, slot ) {

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

			if ( texture.needsUpdate ) {

				if ( !texture.image.__webGLTextureCube ) {

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

				}

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

				_gl.texParameteri( _gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
				_gl.texParameteri( _gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );

				_gl.texParameteri( _gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_MAG_FILTER, _gl.LINEAR );
2807 2808 2809 2810 2811 2812 2813 2814 2815 2816

				if ( isPowerOfTwo( texture.image.width ) && isPowerOfTwo( texture.image.height ) ) {

					_gl.texParameteri( _gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_MIN_FILTER, _gl.LINEAR_MIPMAP_LINEAR );

				} else {

					_gl.texParameteri( _gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_MIN_FILTER, _gl.LINEAR );

				}
2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838

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

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

				}

				_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );

				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

				texture.needsUpdate = false;

			}

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

		}

	};

A
alteredq 已提交
2839
	function setRenderTarget( renderTexture, clear ) {
2840 2841

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

2843 2844 2845 2846 2847
			renderTexture.__webGLFramebuffer = _gl.createFramebuffer();
			renderTexture.__webGLRenderbuffer = _gl.createRenderbuffer();
			renderTexture.__webGLTexture = _gl.createTexture();

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

2849 2850 2851 2852
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTexture.__webGLRenderbuffer );
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTexture.width, renderTexture.height );

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

2854
			_gl.bindTexture( _gl.TEXTURE_2D, renderTexture.__webGLTexture );
2855 2856 2857 2858
			_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 ) );
2859
			_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTexture.format ), renderTexture.width, renderTexture.height, 0, paramThreeToGL( renderTexture.format ), paramThreeToGL( renderTexture.type ), null );
2860 2861

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

2863 2864
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTexture.__webGLFramebuffer );
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, renderTexture.__webGLTexture, 0 );
2865
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webGLRenderbuffer );
2866 2867

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

2869 2870 2871
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
2872

2873 2874
		}

2875
		var framebuffer, width, height;
M
Mr.doob 已提交
2876

2877
		if ( renderTexture ) {
M
Mr.doob 已提交
2878

2879 2880 2881
			framebuffer = renderTexture.__webGLFramebuffer;
			width = renderTexture.width;
			height = renderTexture.height;
M
Mr.doob 已提交
2882

2883
		} else {
M
Mr.doob 已提交
2884

2885 2886 2887
			framebuffer = null;
			width = _canvas.width;
			height = _canvas.height;
M
Mr.doob 已提交
2888

2889
		}
M
Mr.doob 已提交
2890

2891
		if( framebuffer != _oldFramebuffer ) {
M
Mr.doob 已提交
2892

2893 2894
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
			_gl.viewport( 0, 0, width, height );
M
Mr.doob 已提交
2895

A
alteredq 已提交
2896
			if ( clear ) {
M
Mr.doob 已提交
2897

A
alteredq 已提交
2898
				_gl.clear( _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT );
M
Mr.doob 已提交
2899

A
alteredq 已提交
2900
			}
M
Mr.doob 已提交
2901

2902
			_oldFramebuffer = framebuffer;
M
Mr.doob 已提交
2903

2904
		}
2905

2906
	};
M
Mr.doob 已提交
2907

2908
	function updateRenderTargetMipmap( renderTarget ) {
M
Mr.doob 已提交
2909

2910 2911 2912
		_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webGLTexture );
		_gl.generateMipmap( _gl.TEXTURE_2D );
		_gl.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
2913 2914

	};
2915

M
Mr.doob 已提交
2916
	function cacheUniformLocations( program, identifiers ) {
M
Mr.doob 已提交
2917

M
Mr.doob 已提交
2918
		var i, l, id;
M
Mr.doob 已提交
2919

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

2922 2923
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
2924

M
Mr.doob 已提交
2925
		}
M
Mr.doob 已提交
2926

M
Mr.doob 已提交
2927
	};
M
Mr.doob 已提交
2928

2929
	function cacheAttributeLocations( program, identifiers ) {
2930

2931
		var i, l, id;
M
Mr.doob 已提交
2932

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

2935 2936
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
2937

2938
		}
M
Mr.doob 已提交
2939

M
Mr.doob 已提交
2940
	};
M
Mr.doob 已提交
2941

N
Nicolas Garcia Belmonte 已提交
2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966
	function getShader( type, string ) {

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

2968
	};
N
Nicolas Garcia Belmonte 已提交
2969

2970
	function paramThreeToGL( p ) {
M
Mr.doob 已提交
2971

2972
		switch ( p ) {
M
Mr.doob 已提交
2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985

			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;

2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999
			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;

3000
		}
M
Mr.doob 已提交
3001

3002
		return 0;
M
Mr.doob 已提交
3003

3004 3005
	};

3006 3007 3008 3009 3010 3011
	function isPowerOfTwo( value ) {

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

	};

3012 3013 3014 3015
	function materialNeedsSmoothNormals( material ) {

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

3016
	};
M
Mr.doob 已提交
3017

3018
	function bufferNeedsSmoothNormals( geometryGroup, object ) {
M
Mr.doob 已提交
3019

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

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

M
Mr.doob 已提交
3024
			meshMaterial = object.materials[ m ];
3025 3026 3027

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

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

3030
					if ( materialNeedsSmoothNormals( geometryGroup.materials[ i ] ) ) {
3031

3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052
						needsSmoothNormals = true;
						break;

					}

				}

			} else {

				if ( materialNeedsSmoothNormals( meshMaterial ) ) {

					needsSmoothNormals = true;
					break;

				}

			}

			if ( needsSmoothNormals ) break;

		}
M
Mr.doob 已提交
3053

3054
		return needsSmoothNormals;
M
Mr.doob 已提交
3055

3056
	};
M
Mr.doob 已提交
3057

3058
	function allocateLights( lights, maxLights ) {
3059

3060 3061
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
3062

3063
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
3064

3065
			light = lights[ l ];
3066

3067 3068
			if ( light instanceof THREE.DirectionalLight ) dirLights++;
			if ( light instanceof THREE.PointLight ) pointLights++;
3069

3070
		}
3071

3072
		if ( ( pointLights + dirLights ) <= maxLights ) {
3073

3074 3075
			maxDirLights = dirLights;
			maxPointLights = pointLights;
3076

3077
		} else {
3078

3079 3080
			maxDirLights = Math.ceil( maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = maxLights - maxDirLights;
3081 3082 3083

		}

3084
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
3085 3086

	};
M
Mr.doob 已提交
3087

A
alteredq 已提交
3088
	/* DEBUG
3089
	function getGLParams() {
M
Mr.doob 已提交
3090

3091
		var params  = {
M
Mr.doob 已提交
3092

3093 3094
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
3095

3096 3097 3098
			'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 已提交
3099

3100 3101 3102
			'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 已提交
3103

3104 3105
		return params;
	};
M
Mr.doob 已提交
3106

3107
	function dumpObject( obj ) {
M
Mr.doob 已提交
3108

3109 3110
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
3111

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

3114
		}
M
Mr.doob 已提交
3115

3116 3117
		return str;
	}
A
alteredq 已提交
3118
	*/
3119

3120
};
3121

3122
THREE.Snippets = {
M
Mr.doob 已提交
3123

3124
	// FOG
3125

3126
	fog_pars_fragment: [
M
Mr.doob 已提交
3127

3128
	"#ifdef USE_FOG",
3129

3130
		"uniform vec3 fogColor;",
3131

3132 3133 3134 3135 3136 3137
		"#ifdef FOG_EXP2",
			"uniform float fogDensity;",
		"#else",
			"uniform float fogNear;",
			"uniform float fogFar;",
		"#endif",
3138

3139
	"#endif"
3140

3141
	].join("\n"),
M
Mr.doob 已提交
3142

3143
	fog_fragment: [
3144

3145
	"#ifdef USE_FOG",
3146

3147 3148 3149 3150 3151 3152 3153 3154 3155
		"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",
3156

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

3159
	"#endif"
M
Mr.doob 已提交
3160

3161
	].join("\n"),
M
Mr.doob 已提交
3162

3163
	// ENVIRONMENT MAP
3164

3165
	envmap_pars_fragment: [
M
Mr.doob 已提交
3166

3167
	"#ifdef USE_ENVMAP",
M
Mr.doob 已提交
3168

3169 3170
		"varying vec3 vReflect;",
		"uniform float reflectivity;",
3171
		"uniform samplerCube envMap;",
3172
		"uniform int combine;",
M
Mr.doob 已提交
3173

3174
	"#endif"
M
Mr.doob 已提交
3175

3176
	].join("\n"),
M
Mr.doob 已提交
3177

3178
	envmap_fragment: [
M
Mr.doob 已提交
3179

3180 3181
	"#ifdef USE_ENVMAP",

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

3184 3185
		"if ( combine == 1 ) {",

3186 3187
			//"gl_FragColor = mix( gl_FragColor, cubeColor, reflectivity );",
			"gl_FragColor = vec4( mix( gl_FragColor.xyz, cubeColor.xyz, reflectivity ), opacity );",
3188 3189 3190 3191 3192

		"} else {",

			"gl_FragColor = gl_FragColor * cubeColor;",

M
Mr.doob 已提交
3193
		"}",
3194 3195

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

3197
	].join("\n"),
M
Mr.doob 已提交
3198

3199
	envmap_pars_vertex: [
M
Mr.doob 已提交
3200

3201
	"#ifdef USE_ENVMAP",
M
Mr.doob 已提交
3202

3203
		"varying vec3 vReflect;",
3204
		"uniform float refractionRatio;",
3205
		"uniform bool useRefract;",
M
Mr.doob 已提交
3206

3207
	"#endif"
M
Mr.doob 已提交
3208

3209 3210 3211
	].join("\n"),

	envmap_vertex : [
M
Mr.doob 已提交
3212

3213
	"#ifdef USE_ENVMAP",
M
Mr.doob 已提交
3214

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

3218 3219
		"if ( useRefract ) {",

3220
			"vReflect = refract( normalize( mPosition.xyz - cameraPosition ), normalize( nWorld.xyz ), refractionRatio );",
3221 3222 3223 3224 3225 3226 3227 3228

		"} else {",

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

		"}",

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

3230
	].join("\n"),
3231

3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248
	// COLOR MAP (particles)

	map_particle_pars_fragment: [

	"#ifdef USE_MAP",

		"uniform sampler2D map;",

	"#endif"

	].join("\n"),


	map_particle_fragment: [

	"#ifdef USE_MAP",

A
alteredq 已提交
3249
		"gl_FragColor = gl_FragColor * texture2D( map, gl_PointCoord );",
3250 3251 3252 3253 3254 3255

	"#endif"

	].join("\n"),

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

3257
	map_pars_fragment: [
M
Mr.doob 已提交
3258

3259
	"#ifdef USE_MAP",
M
Mr.doob 已提交
3260

3261 3262
		"varying vec2 vUv;",
		"uniform sampler2D map;",
M
Mr.doob 已提交
3263

3264
	"#endif"
M
Mr.doob 已提交
3265

3266
	].join("\n"),
M
Mr.doob 已提交
3267

3268
	map_pars_vertex: [
M
Mr.doob 已提交
3269

3270
	"#ifdef USE_MAP",
M
Mr.doob 已提交
3271

3272 3273 3274
		"varying vec2 vUv;",

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

3276
	].join("\n"),
M
Mr.doob 已提交
3277

3278 3279 3280 3281
	map_fragment: [

	"#ifdef USE_MAP",

A
alteredq 已提交
3282
		"gl_FragColor = gl_FragColor * texture2D( map, vUv );",
3283 3284

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

3286
	].join("\n"),
M
Mr.doob 已提交
3287

3288
	map_vertex: [
M
Mr.doob 已提交
3289

3290
	"#ifdef USE_MAP",
M
Mr.doob 已提交
3291

3292
		"vUv = uv;",
M
Mr.doob 已提交
3293

3294
	"#endif"
M
Mr.doob 已提交
3295

3296
	].join("\n"),
M
Mr.doob 已提交
3297

3298
	// LIGHT MAP
3299

3300 3301 3302 3303 3304
	lightmap_pars_fragment: [

	"#ifdef USE_LIGHTMAP",

		"varying vec2 vUv2;",
3305
		"uniform sampler2D lightMap;",
3306 3307 3308 3309

	"#endif"

	].join("\n"),
3310

3311 3312 3313 3314 3315 3316 3317 3318 3319
	lightmap_pars_vertex: [

	"#ifdef USE_LIGHTMAP",

		"varying vec2 vUv2;",

	"#endif"

	].join("\n"),
3320

3321 3322 3323 3324
	lightmap_fragment: [

	"#ifdef USE_LIGHTMAP",

3325
		"gl_FragColor = gl_FragColor * texture2D( lightMap, vUv2 );",
3326 3327 3328 3329

	"#endif"

	].join("\n"),
3330

3331 3332 3333 3334 3335 3336 3337 3338 3339 3340
	lightmap_vertex: [

	"#ifdef USE_LIGHTMAP",

		"vUv2 = uv2;",

	"#endif"

	].join("\n"),

3341
	lights_pars_vertex: [
M
Mr.doob 已提交
3342

3343 3344
	"uniform bool enableLighting;",
	"uniform vec3 ambientLightColor;",
M
Mr.doob 已提交
3345

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

3348 3349
		"uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
		"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
M
Mr.doob 已提交
3350

3351 3352 3353
	"#endif",

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

3355 3356
		"uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
		"uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
M
Mr.doob 已提交
3357

3358 3359 3360
		"#ifdef PHONG",
			"varying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];",
		"#endif",
M
Mr.doob 已提交
3361

3362
	"#endif"
M
Mr.doob 已提交
3363

3364
	].join("\n"),
M
Mr.doob 已提交
3365

3366
	// LIGHTS
3367

3368
	lights_vertex: [
M
Mr.doob 已提交
3369

3370 3371
	"if ( !enableLighting ) {",

A
alteredq 已提交
3372
		"vLightWeighting = vec3( 1.0 );",
3373 3374 3375 3376 3377 3378

	"} else {",

		"vLightWeighting = ambientLightColor;",

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

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

3382 3383 3384
			"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 已提交
3385

3386
		"}",
M
Mr.doob 已提交
3387

3388 3389 3390
		"#endif",

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

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

3394 3395 3396 3397
			"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 已提交
3398

3399 3400 3401
			"#ifdef PHONG",
				"vPointLightVector[ i ] = pointLightVector;",
			"#endif",
M
Mr.doob 已提交
3402

3403
		"}",
M
Mr.doob 已提交
3404

3405
		"#endif",
M
Mr.doob 已提交
3406

3407
	"}"
M
Mr.doob 已提交
3408

3409
	].join("\n"),
M
Mr.doob 已提交
3410

3411
	lights_pars_fragment: [
M
Mr.doob 已提交
3412

3413 3414 3415
	"#if MAX_DIR_LIGHTS > 0",
		"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
	"#endif",
M
Mr.doob 已提交
3416

3417 3418 3419
	"#if MAX_POINT_LIGHTS > 0",
		"varying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];",
	"#endif",
M
Mr.doob 已提交
3420

3421 3422
	"varying vec3 vViewPosition;",
	"varying vec3 vNormal;"
M
Mr.doob 已提交
3423

3424
	].join("\n"),
M
Mr.doob 已提交
3425

3426
	lights_fragment: [
M
Mr.doob 已提交
3427

3428 3429
	"vec3 normal = normalize( vNormal );",
	"vec3 viewPosition = normalize( vViewPosition );",
3430

A
alteredq 已提交
3431
	"vec4 mColor = vec4( diffuse, opacity );",
3432 3433 3434
	"vec4 mSpecular = vec4( specular, opacity );",

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

3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456
		"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 已提交
3457

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

3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481
		"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 已提交
3482

3483 3484 3485 3486 3487 3488 3489
	"#endif",

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

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

3491 3492
	"#if MAX_POINT_LIGHTS > 0",
		"totalLight += pointDiffuse + pointSpecular;",
A
alteredq 已提交
3493
	"#endif",
3494

A
alteredq 已提交
3495
	"gl_FragColor = gl_FragColor * totalLight;"
3496

A
alteredq 已提交
3497
	].join("\n"),
3498

A
alteredq 已提交
3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515
	// VERTEX COLORS

	color_pars_fragment: [

	"#ifdef USE_COLOR",

		"varying vec3 vColor;",

	"#endif"

	].join("\n"),


	color_fragment: [

	"#ifdef USE_COLOR",

A
alteredq 已提交
3516
		"gl_FragColor = gl_FragColor * vec4( vColor, opacity );",
A
alteredq 已提交
3517 3518 3519 3520

	"#endif"

	].join("\n"),
3521

A
alteredq 已提交
3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540
	color_pars_vertex: [

	"#ifdef USE_COLOR",

		"varying vec3 vColor;",

	"#endif"

	].join("\n"),


	color_vertex: [

	"#ifdef USE_COLOR",

		"vColor = color;",

	"#endif"

3541
	].join("\n"),
3542

3543
	// skinning
3544

3545
	skinning_pars_vertex: [
3546

3547
	"#ifdef USE_SKINNING",
3548

A
alteredq 已提交
3549
		"uniform mat4 boneGlobalMatrices[20];",
3550

3551
	"#endif"
3552

3553
	].join("\n"),
3554

3555
	skinning_vertex: [
3556

3557 3558
	"#ifdef USE_SKINNING",

A
alteredq 已提交
3559 3560
		"gl_Position  = ( boneGlobalMatrices[ int( skinIndex.x ) ] * skinVertexA ) * skinWeight.x;",
		"gl_Position += ( boneGlobalMatrices[ int( skinIndex.y ) ] * skinVertexB ) * skinWeight.y;",
3561

3562 3563
		// this doesn't work, no idea why
		//"gl_Position  = projectionMatrix * cameraInverseMatrix * objectMatrix * gl_Position;",
3564

3565
		"gl_Position  = projectionMatrix * viewMatrix * objectMatrix * gl_Position;",
3566

3567
	"#else",
3568

3569
		"gl_Position = projectionMatrix * mvPosition;",
3570

3571
	"#endif"
3572

3573
	].join("\n")
3574

3575
};
3576

3577
THREE.UniformsLib = {
M
Mr.doob 已提交
3578

3579
	common: {
M
Mr.doob 已提交
3580

A
alteredq 已提交
3581
	"diffuse" : { type: "c", value: new THREE.Color( 0xeeeeee ) },
3582
	"opacity" : { type: "f", value: 1.0 },
3583
	"map"     : { type: "t", value: 0, texture: null },
M
Mr.doob 已提交
3584

3585
	"lightMap"       : { type: "t", value: 2, texture: null },
3586

3587
	"envMap" 		  : { type: "t", value: 1, texture: null },
3588
	"useRefract"	  : { type: "i", value: 0 },
3589
	"reflectivity"    : { type: "f", value: 1.0 },
3590
	"refractionRatio": { type: "f", value: 0.98 },
3591
	"combine"		  : { type: "i", value: 0 },
M
Mr.doob 已提交
3592

3593 3594 3595 3596
	"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 已提交
3597

3598
	},
M
Mr.doob 已提交
3599

3600
	lights: {
M
Mr.doob 已提交
3601

3602 3603 3604 3605 3606 3607
	"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 已提交
3608

3609 3610 3611 3612
	},

	particle: {

A
alteredq 已提交
3613
	"psColor"   : { type: "c", value: new THREE.Color( 0xeeeeee ) },
3614 3615
	"opacity" : { type: "f", value: 1.0 },
	"size" 	  : { type: "f", value: 1.0 },
3616
	"map"     : { type: "t", value: 0, texture: null },
M
Mr.doob 已提交
3617

3618 3619 3620 3621
	"fogDensity": { type: "f", value: 0.00025 },
	"fogNear"	: { type: "f", value: 1 },
	"fogFar"	: { type: "f", value: 2000 },
	"fogColor"	: { type: "c", value: new THREE.Color( 0xffffff ) }
3622

3623
	}
3624

3625 3626
};

3627
THREE.ShaderLib = {
3628

3629
	'depth': {
M
Mr.doob 已提交
3630

3631
		uniforms: { "mNear": { type: "f", value: 1.0 },
3632
					"mFar" : { type: "f", value: 2000.0 },
A
alteredq 已提交
3633
					"opacity" : { type: "f", value: 1.0 }
3634
				  },
3635

3636
		fragmentShader: [
M
Mr.doob 已提交
3637

3638 3639
			"uniform float mNear;",
			"uniform float mFar;",
3640
			"uniform float opacity;",
M
Mr.doob 已提交
3641

3642
			"void main() {",
M
Mr.doob 已提交
3643

3644 3645
				"float depth = gl_FragCoord.z / gl_FragCoord.w;",
				"float color = 1.0 - smoothstep( mNear, mFar, depth );",
3646
				"gl_FragColor = vec4( vec3( color ), opacity );",
M
Mr.doob 已提交
3647

3648
			"}"
M
Mr.doob 已提交
3649

3650
		].join("\n"),
3651

3652
		vertexShader: [
3653

3654
			"void main() {",
3655

3656
				"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
3657

3658
			"}"
3659

3660
		].join("\n")
3661

3662
	},
3663

3664
	'normal': {
M
Mr.doob 已提交
3665

3666
		uniforms: { "opacity" : { type: "f", value: 1.0 } },
3667

3668
		fragmentShader: [
3669

3670
			"uniform float opacity;",
3671
			"varying vec3 vNormal;",
M
Mr.doob 已提交
3672

3673
			"void main() {",
3674

3675
				"gl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );",
M
Mr.doob 已提交
3676

3677
			"}"
M
Mr.doob 已提交
3678

3679
		].join("\n"),
M
Mr.doob 已提交
3680

3681
		vertexShader: [
3682

3683
			"varying vec3 vNormal;",
3684

3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696
			"void main() {",

				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
				"vNormal = normalize( normalMatrix * normal );",

				"gl_Position = projectionMatrix * mvPosition;",

			"}"

		].join("\n")

	},
3697

3698
	'basic': {
M
Mr.doob 已提交
3699

3700
		uniforms: THREE.UniformsLib[ "common" ],
M
Mr.doob 已提交
3701

3702
		fragmentShader: [
3703

A
alteredq 已提交
3704
			"uniform vec3 diffuse;",
3705
			"uniform float opacity;",
M
Mr.doob 已提交
3706

3707
			THREE.Snippets[ "color_pars_fragment" ],
3708
			THREE.Snippets[ "map_pars_fragment" ],
3709
			THREE.Snippets[ "lightmap_pars_fragment" ],
3710 3711
			THREE.Snippets[ "envmap_pars_fragment" ],
			THREE.Snippets[ "fog_pars_fragment" ],
M
Mr.doob 已提交
3712

3713
			"void main() {",
3714

A
alteredq 已提交
3715
				"gl_FragColor = vec4( diffuse, opacity );",
3716

3717
				THREE.Snippets[ "map_fragment" ],
3718
				THREE.Snippets[ "lightmap_fragment" ],
3719
				THREE.Snippets[ "color_fragment" ],
3720 3721
				THREE.Snippets[ "envmap_fragment" ],
				THREE.Snippets[ "fog_fragment" ],
M
Mr.doob 已提交
3722

3723
			"}"
3724

3725
		].join("\n"),
M
Mr.doob 已提交
3726

3727
		vertexShader: [
M
Mr.doob 已提交
3728

3729
			THREE.Snippets[ "map_pars_vertex" ],
3730
			THREE.Snippets[ "lightmap_pars_vertex" ],
3731
			THREE.Snippets[ "envmap_pars_vertex" ],
3732
			THREE.Snippets[ "color_pars_vertex" ],
3733
			THREE.Snippets[ "skinning_pars_vertex" ],
M
Mr.doob 已提交
3734

3735
			"void main() {",
M
Mr.doob 已提交
3736

3737
				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
M
Mr.doob 已提交
3738

3739
				THREE.Snippets[ "map_vertex" ],
3740
				THREE.Snippets[ "lightmap_vertex" ],
3741
				THREE.Snippets[ "envmap_vertex" ],
3742
				THREE.Snippets[ "color_vertex" ],
3743
				THREE.Snippets[ "skinning_vertex" ],
3744

3745
			"}"
3746

3747
		].join("\n")
M
Mr.doob 已提交
3748

3749
	},
3750

3751
	'lambert': {
M
Mr.doob 已提交
3752 3753

		uniforms: Uniforms.merge( [ THREE.UniformsLib[ "common" ],
3754
									THREE.UniformsLib[ "lights" ] ] ),
M
Mr.doob 已提交
3755

3756
		fragmentShader: [
M
Mr.doob 已提交
3757

A
alteredq 已提交
3758
			"uniform vec3 diffuse;",
3759
			"uniform float opacity;",
M
Mr.doob 已提交
3760

3761
			"varying vec3 vLightWeighting;",
M
Mr.doob 已提交
3762

A
alteredq 已提交
3763
			THREE.Snippets[ "color_pars_fragment" ],
3764
			THREE.Snippets[ "map_pars_fragment" ],
3765
			THREE.Snippets[ "lightmap_pars_fragment" ],
3766 3767
			THREE.Snippets[ "envmap_pars_fragment" ],
			THREE.Snippets[ "fog_pars_fragment" ],
M
Mr.doob 已提交
3768

3769
			"void main() {",
M
Mr.doob 已提交
3770

A
alteredq 已提交
3771 3772
				"gl_FragColor = vec4( diffuse, opacity );",
				"gl_FragColor = gl_FragColor * vec4( vLightWeighting, 1.0 );",
3773 3774

				THREE.Snippets[ "map_fragment" ],
3775
				THREE.Snippets[ "lightmap_fragment" ],
A
alteredq 已提交
3776
				THREE.Snippets[ "color_fragment" ],
3777
				THREE.Snippets[ "envmap_fragment" ],
3778 3779 3780 3781 3782 3783
				THREE.Snippets[ "fog_fragment" ],

			"}"

		].join("\n"),

3784
		vertexShader: [
M
Mr.doob 已提交
3785

3786
			"varying vec3 vLightWeighting;",
M
Mr.doob 已提交
3787

3788
			THREE.Snippets[ "map_pars_vertex" ],
3789
			THREE.Snippets[ "lightmap_pars_vertex" ],
3790 3791
			THREE.Snippets[ "envmap_pars_vertex" ],
			THREE.Snippets[ "lights_pars_vertex" ],
A
alteredq 已提交
3792
			THREE.Snippets[ "color_pars_vertex" ],
3793
			THREE.Snippets[ "skinning_pars_vertex" ],
A
alteredq 已提交
3794

3795
			"void main() {",
M
Mr.doob 已提交
3796

3797
				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
M
Mr.doob 已提交
3798

3799
				THREE.Snippets[ "map_vertex" ],
3800
				THREE.Snippets[ "lightmap_vertex" ],
3801
				THREE.Snippets[ "envmap_vertex" ],
A
alteredq 已提交
3802
				THREE.Snippets[ "color_vertex" ],
M
Mr.doob 已提交
3803

3804
				"vec3 transformedNormal = normalize( normalMatrix * normal );",
M
Mr.doob 已提交
3805

3806
				THREE.Snippets[ "lights_vertex" ],
3807
				THREE.Snippets[ "skinning_vertex" ],
3808 3809 3810 3811

			"}"

		].join("\n")
M
Mr.doob 已提交
3812

3813
	},
M
Mr.doob 已提交
3814

3815
	'phong': {
M
Mr.doob 已提交
3816 3817

		uniforms: Uniforms.merge( [ THREE.UniformsLib[ "common" ],
3818
									THREE.UniformsLib[ "lights" ],
M
Mr.doob 已提交
3819

3820
									{ "ambient"  : { type: "c", value: new THREE.Color( 0x050505 ) },
3821 3822 3823
									  "specular" : { type: "c", value: new THREE.Color( 0x111111 ) },
									  "shininess": { type: "f", value: 30 }
									}
M
Mr.doob 已提交
3824

3825
								] ),
M
Mr.doob 已提交
3826

3827
		fragmentShader: [
M
Mr.doob 已提交
3828

A
alteredq 已提交
3829
			"uniform vec3 diffuse;",
3830
			"uniform float opacity;",
M
Mr.doob 已提交
3831

3832 3833 3834
			"uniform vec3 ambient;",
			"uniform vec3 specular;",
			"uniform float shininess;",
M
Mr.doob 已提交
3835

3836
			"varying vec3 vLightWeighting;",
M
Mr.doob 已提交
3837

A
alteredq 已提交
3838
			THREE.Snippets[ "color_pars_fragment" ],
3839
			THREE.Snippets[ "map_pars_fragment" ],
3840
			THREE.Snippets[ "lightmap_pars_fragment" ],
3841 3842 3843
			THREE.Snippets[ "envmap_pars_fragment" ],
			THREE.Snippets[ "fog_pars_fragment" ],
			THREE.Snippets[ "lights_pars_fragment" ],
M
Mr.doob 已提交
3844

3845
			"void main() {",
M
Mr.doob 已提交
3846

A
alteredq 已提交
3847 3848
				"gl_FragColor = vec4( vLightWeighting, 1.0 );",
				THREE.Snippets[ "lights_fragment" ],
3849 3850

				THREE.Snippets[ "map_fragment" ],
3851
				THREE.Snippets[ "lightmap_fragment" ],
A
alteredq 已提交
3852
				THREE.Snippets[ "color_fragment" ],
3853 3854 3855 3856 3857 3858 3859
				THREE.Snippets[ "envmap_fragment" ],
				THREE.Snippets[ "fog_fragment" ],

			"}"

		].join("\n"),

3860
		vertexShader: [
M
Mr.doob 已提交
3861

3862
			"#define PHONG",
M
Mr.doob 已提交
3863

3864 3865 3866
			"varying vec3 vLightWeighting;",
			"varying vec3 vViewPosition;",
			"varying vec3 vNormal;",
M
Mr.doob 已提交
3867

3868
			THREE.Snippets[ "map_pars_vertex" ],
3869
			THREE.Snippets[ "lightmap_pars_vertex" ],
3870 3871
			THREE.Snippets[ "envmap_pars_vertex" ],
			THREE.Snippets[ "lights_pars_vertex" ],
A
alteredq 已提交
3872
			THREE.Snippets[ "color_pars_vertex" ],
3873
			THREE.Snippets[ "skinning_pars_vertex" ],
M
Mr.doob 已提交
3874

3875
			"void main() {",
M
Mr.doob 已提交
3876

3877
				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
M
Mr.doob 已提交
3878

3879
				THREE.Snippets[ "map_vertex" ],
3880
				THREE.Snippets[ "lightmap_vertex" ],
3881
				THREE.Snippets[ "envmap_vertex" ],
A
alteredq 已提交
3882
				THREE.Snippets[ "color_vertex" ],
M
Mr.doob 已提交
3883

3884 3885 3886
				"#ifndef USE_ENVMAP",
					"vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
				"#endif",
M
Mr.doob 已提交
3887

3888
				"vViewPosition = cameraPosition - mPosition.xyz;",
M
Mr.doob 已提交
3889

3890 3891
				"vec3 transformedNormal = normalize( normalMatrix * normal );",
				"vNormal = transformedNormal;",
3892

3893
				THREE.Snippets[ "lights_vertex" ],
3894
				THREE.Snippets[ "skinning_vertex" ],
3895 3896 3897 3898

			"}"

		].join("\n")
M
Mr.doob 已提交
3899

3900
	},
3901

3902 3903 3904 3905
	'particle_basic': {

		uniforms: THREE.UniformsLib[ "particle" ],

3906
		fragmentShader: [
3907

A
alteredq 已提交
3908
			"uniform vec3 psColor;",
3909 3910
			"uniform float opacity;",

A
alteredq 已提交
3911
			THREE.Snippets[ "color_pars_fragment" ],
3912 3913 3914 3915 3916
			THREE.Snippets[ "map_particle_pars_fragment" ],
			THREE.Snippets[ "fog_pars_fragment" ],

			"void main() {",

A
alteredq 已提交
3917
				"gl_FragColor = vec4( psColor, opacity );",
3918 3919

				THREE.Snippets[ "map_particle_fragment" ],
A
alteredq 已提交
3920
				THREE.Snippets[ "color_fragment" ],
3921 3922 3923 3924 3925 3926
				THREE.Snippets[ "fog_fragment" ],

			"}"

		].join("\n"),

3927
		vertexShader: [
3928 3929

			"uniform float size;",
3930

A
alteredq 已提交
3931
			THREE.Snippets[ "color_pars_vertex" ],
3932

3933 3934
			"void main() {",

A
alteredq 已提交
3935
				THREE.Snippets[ "color_vertex" ],
3936

3937 3938 3939 3940 3941 3942 3943 3944 3945 3946
				"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 已提交
3947
	}
A
alteredq 已提交
3948

3949 3950

};