WebGLRenderer.js 55.3 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,
26
	_modelViewMatrix = new THREE.Matrix4(), _normalMatrix,
M
Mr.doob 已提交
27 28 29 30

	_viewMatrixArray = new Float32Array(16),
	_modelViewMatrixArray = new Float32Array(16),
	_projectionMatrixArray = new Float32Array(16),
M
Mr.doob 已提交
31
	_normalMatrixArray = new Float32Array(9),
M
Mr.doob 已提交
32
	_objectMatrixArray = new Float32Array(16),
M
Mr.doob 已提交
33

34 35 36 37 38
	// parameters defaults
	
	antialias = true,
	clearColor = new THREE.Color( 0x000000 ),
	clearAlpha = 0;
39

40 41 42 43 44 45 46 47
	if ( parameters ) {
		
		if ( parameters.antialias !== undefined ) antialias = parameters.antialias;
		if ( parameters.clearColor !== undefined ) clearColor.setHex( parameters.clearColor );
		if ( parameters.clearAlpha !== undefined ) clearAlpha = parameters.clearAlpha;
		
	}
		
N
Nicolas Garcia Belmonte 已提交
48 49 50
	this.domElement = _canvas;
	this.autoClear = true;

51
	initGL( antialias, clearColor, clearAlpha );
M
Mr.doob 已提交
52

53 54
	this.context = _gl;

55
	//alert( dumpObject( getGLParams() ) );
M
Mr.doob 已提交
56

N
Nicolas Garcia Belmonte 已提交
57 58 59 60 61 62 63 64
	this.setSize = function ( width, height ) {

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

	};

65
	this.setClearColor = function( hex, alpha ) {
66

67 68
		var color = new THREE.Color( hex );
		_gl.clearColor( color.r, color.g, color.b, alpha );
69

70
	};
71

N
Nicolas Garcia Belmonte 已提交
72 73 74 75 76 77
	this.clear = function () {

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

	};

78
	this.setupLights = function ( program, lights ) {
79

80
		var l, ll, light, r = 0, g = 0, b = 0,
81
			color, position, intensity,
82 83
			dcolors = [], dpositions = [],
			pcolors = [], ppositions = [];
84

85

86
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
87

88
			light = lights[ l ];
89 90 91
			color = light.color;
			position = light.position;
			intensity = light.intensity;
92 93 94

			if ( light instanceof THREE.AmbientLight ) {

95 96 97
				r += color.r;
				g += color.g;
				b += color.b;
98
				
99
			} else if ( light instanceof THREE.DirectionalLight ) {
100

101 102 103
				dcolors.push( color.r * intensity,
							  color.g * intensity,
							  color.b * intensity );
104

105 106 107
				dpositions.push( position.x,
								 position.y,
								 position.z );
108

109 110
			} else if( light instanceof THREE.PointLight ) {

111 112 113
				pcolors.push( color.r * intensity,
							  color.g * intensity,
							  color.b * intensity );
M
Mr.doob 已提交
114

115 116 117
				ppositions.push( position.x,
								 position.y,
								 position.z );
118
				
119 120 121
			}

		}
122 123
		
		return { ambient: [ r, g, b ], directional: { colors: dcolors, positions: dpositions }, point: { colors: pcolors, positions: ppositions } };
M
Mr.doob 已提交
124

125
	};
M
Mr.doob 已提交
126

127 128 129 130 131
	this.createParticleBuffers = function( geometry ) {
		
		geometry.__webGLVertexBuffer = _gl.createBuffer();
		geometry.__webGLFaceBuffer = _gl.createBuffer();
	
132 133
	};
	
134
	this.createLineBuffers = function( geometry ) {
135
		
136 137
		geometry.__webGLVertexBuffer = _gl.createBuffer();
		geometry.__webGLLineBuffer = _gl.createBuffer();
138 139
		
	};
140 141

	this.createMeshBuffers = function( geometryChunk ) {
142 143 144 145 146 147 148 149 150
		
		geometryChunk.__webGLVertexBuffer = _gl.createBuffer();
		geometryChunk.__webGLNormalBuffer = _gl.createBuffer();
		geometryChunk.__webGLTangentBuffer = _gl.createBuffer();
		geometryChunk.__webGLUVBuffer = _gl.createBuffer();
		geometryChunk.__webGLFaceBuffer = _gl.createBuffer();
		geometryChunk.__webGLLineBuffer = _gl.createBuffer();
		
	};
151 152 153 154 155 156 157 158 159

	this.initLineBuffers = function( geometry ) {
		
		var nvertices = geometry.vertices.length;

		geometry.__vertexArray = new Float32Array( nvertices * 3 );
		geometry.__lineArray = new Uint16Array( nvertices );
		
		geometry.__webGLLineCount = nvertices;
160
	
161 162 163
	};
	
	this.initMeshBuffers = function( geometryChunk, object ) {
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
		
		var f, fl, nvertices = 0, ntris = 0, nlines = 0,
			obj_faces = object.geometry.faces, 
			chunk_faces = geometryChunk.faces;
		
		for ( f = 0, fl = chunk_faces.length; f < fl; f++ ) {
			
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
			
			if ( face instanceof THREE.Face3 ) {
				
				nvertices += 3;
				ntris += 1;
				nlines += 3;
				
			} else if ( face instanceof THREE.Face4 ) {
				
				nvertices += 4;
				ntris += 2;
				nlines += 5;
				
			}
		
		}
		
		// TODO: only create arrays for attributes existing in the object
		
		geometryChunk.__vertexArray  = new Float32Array( nvertices * 3 );
		geometryChunk.__normalArray  = new Float32Array( nvertices * 3 );
		geometryChunk.__tangentArray = new Float32Array( nvertices * 4 );
		geometryChunk.__uvArray = new Float32Array( nvertices * 2 );
		
		geometryChunk.__faceArray = new Uint16Array( ntris * 3 );
		geometryChunk.__lineArray = new Uint16Array( nlines * 2 );
		
		geometryChunk.__needsSmoothNormals = bufferNeedsSmoothNormals ( geometryChunk, object );
		
		geometryChunk.__webGLFaceCount = ntris * 3;
		geometryChunk.__webGLLineCount = nlines * 2;
204
	
205 206
	};
	
207
	this.setMeshBuffers = function ( geometryChunk, object, hint, dirtyVertices, dirtyElements, dirtyUvs, dirtyNormals, dirtyTangents ) {
208

209
		var f, fl, fi, face, vertexNormals, faceNormal, normal, uv, v1, v2, v3, v4, t1, t2, t3, t4, m, ml, i,
210
			vn, uvi,
211
		
212
		vertexIndex = 0,
213

214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
		offset = 0,
		offset_uv = 0,
		offset_face = 0,
		offset_normal = 0,
		offset_tangent = 0,
		offset_line = 0,
		
		vertexArray = geometryChunk.__vertexArray,
		uvArray = geometryChunk.__uvArray,
		normalArray = geometryChunk.__normalArray,
		tangentArray = geometryChunk.__tangentArray,
		
		faceArray = geometryChunk.__faceArray,
		lineArray = geometryChunk.__lineArray,
		
		needsSmoothNormals = geometryChunk.__needsSmoothNormals,
		
231 232 233 234 235
		geometry = object.geometry,
		vertices = geometry.vertices,
		chunk_faces = geometryChunk.faces,
		obj_faces = geometry.faces,
		obj_uvs = geometry.uvs;
236
		
237 238 239 240 241
		for ( f = 0, fl = chunk_faces.length; f < fl; f++ ) {
			
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
			uv = obj_uvs[ fi ];
242
			
243
			vertexNormals = face.vertexNormals;
244
			faceNormal = face.normal;
245 246 247

			if ( face instanceof THREE.Face3 ) {

248 249 250 251 252 253 254 255 256 257 258 259 260
				if ( dirtyVertices ) {
					
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
					
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
					
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
261

262 263 264 265 266 267 268
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
					
					offset += 9;
					
				}
269

270
				if ( dirtyTangents && geometry.hasTangents ) {
271

272 273 274
					t1 = vertices[ face.a ].tangent;
					t2 = vertices[ face.b ].tangent;
					t3 = vertices[ face.c ].tangent;
275

276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
					tangentArray[ offset_tangent ]     = t1.x;
					tangentArray[ offset_tangent + 1 ] = t1.y;
					tangentArray[ offset_tangent + 2 ] = t1.z;
					tangentArray[ offset_tangent + 3 ] = t1.w;
					
					tangentArray[ offset_tangent + 4 ] = t2.x;
					tangentArray[ offset_tangent + 5 ] = t2.y;
					tangentArray[ offset_tangent + 6 ] = t2.z;
					tangentArray[ offset_tangent + 7 ] = t2.w;
					
					tangentArray[ offset_tangent + 8 ]  = t3.x;
					tangentArray[ offset_tangent + 9 ]  = t3.y;
					tangentArray[ offset_tangent + 10 ] = t3.z;
					tangentArray[ offset_tangent + 11 ] = t3.w;
					
					offset_tangent += 12;
					
293 294
				}

295 296 297 298
				if( dirtyNormals ) {
				
					if ( vertexNormals.length == 3 && needsSmoothNormals ) {

299

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

302 303 304 305 306 307 308
							vn = vertexNormals[ i ];
							
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
							
							offset_normal += 3;
M
Mr.doob 已提交
309

310
						}
M
Mr.doob 已提交
311

312
					} else {
313

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

316 317 318 319 320
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
							
							offset_normal += 3;
M
Mr.doob 已提交
321

322
						}
M
Mr.doob 已提交
323 324

					}
325
					
326 327
				}

328
				if ( dirtyUvs && uv ) {
329

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

332 333 334 335 336 337
						uvi = uv[ i ];
						
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
						
						offset_uv += 2;
M
Mr.doob 已提交
338

M
Mr.doob 已提交
339
					}
340 341 342

				}

343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
				if( dirtyElements ) {
					
					faceArray[ offset_face ] = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
					
					offset_face += 3;
				
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
					
					lineArray[ offset_line + 2 ] = vertexIndex;
					lineArray[ offset_line + 3 ] = vertexIndex + 2;
					
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
					
					offset_line += 6;
361

362 363 364 365
					vertexIndex += 3;
					
				}
				
366 367 368

			} else if ( face instanceof THREE.Face4 ) {

369 370 371 372 373 374 375 376 377 378 379 380 381 382
				if ( dirtyVertices ) {
					
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
					v4 = vertices[ face.d ].position;
			
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
					
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
383

384 385 386
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
387

388 389 390 391 392 393 394
					vertexArray[ offset + 9 ] = v4.x;
					vertexArray[ offset + 10 ] = v4.y;
					vertexArray[ offset + 11 ] = v4.z;
				
					offset += 12;
					
				}
395

396
				if ( dirtyTangents && geometry.hasTangents ) {
397

398 399 400 401
					t1 = vertices[ face.a ].tangent;
					t2 = vertices[ face.b ].tangent;
					t3 = vertices[ face.c ].tangent;
					t4 = vertices[ face.d ].tangent;
402

403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424
					tangentArray[ offset_tangent ]     = t1.x;
					tangentArray[ offset_tangent + 1 ] = t1.y;
					tangentArray[ offset_tangent + 2 ] = t1.z;
					tangentArray[ offset_tangent + 3 ] = t1.w;
					
					tangentArray[ offset_tangent + 4 ] = t2.x;
					tangentArray[ offset_tangent + 5 ] = t2.y;
					tangentArray[ offset_tangent + 6 ] = t2.z;
					tangentArray[ offset_tangent + 7 ] = t2.w;
					
					tangentArray[ offset_tangent + 8 ] = t3.x;
					tangentArray[ offset_tangent + 9 ] = t3.y;
					tangentArray[ offset_tangent + 10 ] = t3.z;
					tangentArray[ offset_tangent + 11 ] = t3.w;
					
					tangentArray[ offset_tangent + 12 ] = t4.x;
					tangentArray[ offset_tangent + 13 ] = t4.y;
					tangentArray[ offset_tangent + 14 ] = t4.z;
					tangentArray[ offset_tangent + 15 ] = t4.w;
					
					offset_tangent += 16;
					
425
				}
426 427 428 429
				
				if( dirtyNormals ) {
					
					if ( vertexNormals.length == 4 && needsSmoothNormals ) {
430

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

433 434 435 436 437 438 439
							vn = vertexNormals[ i ];
							
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
							
							offset_normal += 3;
M
Mr.doob 已提交
440

441
						}
M
Mr.doob 已提交
442

443
					} else {
444

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

447 448 449 450 451
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
							
							offset_normal += 3;
M
Mr.doob 已提交
452

453
						}
M
Mr.doob 已提交
454 455

					}
456
					
457 458
				}

459
				if ( dirtyUvs && uv ) {
460

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

463 464 465 466 467 468
						uvi = uv[ i ];
						
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
						
						offset_uv += 2;
M
Mr.doob 已提交
469

M
Mr.doob 已提交
470
					}
471 472

				}
473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505
		
				if( dirtyElements ) {
					
					faceArray[ offset_face ]     = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
					
					faceArray[ offset_face + 3 ] = vertexIndex;
					faceArray[ offset_face + 4 ] = vertexIndex + 2;
					faceArray[ offset_face + 5 ] = vertexIndex + 3;
					
					offset_face += 6;
					
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
					
					lineArray[ offset_line + 2 ] = vertexIndex;
					lineArray[ offset_line + 3 ] = vertexIndex + 2;
					
					lineArray[ offset_line + 4 ] = vertexIndex;
					lineArray[ offset_line + 5 ] = vertexIndex + 3;
					
					lineArray[ offset_line + 6 ] = vertexIndex + 1;
					lineArray[ offset_line + 7 ] = vertexIndex + 2;
					
					lineArray[ offset_line + 8 ] = vertexIndex + 2;
					lineArray[ offset_line + 9 ] = vertexIndex + 3;
					
					offset_line += 10;
					
					vertexIndex += 4;
					
				}
M
Mr.doob 已提交
506

507
			}
M
Mr.doob 已提交
508

509 510
		}

511 512 513 514 515 516 517 518 519 520 521 522
		if ( dirtyVertices ) {
		
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
			
		}
		
		if ( dirtyNormals ) {
		
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLNormalBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
			
523 524
		}

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

527
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLTangentBuffer );
528 529
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
		
530
		}
531

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

534
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLUVBuffer );
535
			_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
M
Mr.doob 已提交
536

537
		}
M
Mr.doob 已提交
538

539 540 541 542
		if( dirtyElements ) {
			
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryChunk.__webGLFaceBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
543

544 545 546 547
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryChunk.__webGLLineBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
			
		}
548 549

	};
550

551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599
	this.setLineBuffers = function( geometry, hint, dirtyVertices, dirtyElements ) {
		
		var v, vertex, offset,
			vertices = geometry.vertices,
			vl = vertices.length,
		
			vertexArray = geometry.__vertexArray, 
			lineArray = geometry.__lineArray;
		
		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;
				
			}

		}
		
		// yeah, this is silly as order of element indices is currently fixed
		// though this could change if some use case arises
		
		if ( dirtyElements ) {
			
			for ( v = 0; v < vl; v++ ) {
				
				lineArray[ v ] = v;
				
			}
			
		}

		_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLVertexBuffer );
		_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
		
		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometry.__webGLLineBuffer );
		_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
		
	};
	
	this.setParticleBuffers = function( geometry, hint, dirtyVertices, dirtyElements ) {
	};
	
M
Mr.doob 已提交
600
	function setMaterialShaders( material, shaders ) {
601

M
Mr.doob 已提交
602 603
		material.fragment_shader = shaders.fragment_shader;
		material.vertex_shader = shaders.vertex_shader;
604
		material.uniforms = Uniforms.clone( shaders.uniforms );
605

M
Mr.doob 已提交
606
	};
607

608
	function refreshUniformsCommon( material, fog ) {
609
		
610 611 612 613 614 615
		// premultiply alpha
		material.uniforms.color.value.setRGB( material.color.r * material.opacity, material.color.g * material.opacity, material.color.b * material.opacity );
		
		// pure color
		//material.uniforms.color.value.setHex( material.color.hex );
		
616 617
		material.uniforms.opacity.value = material.opacity;
		material.uniforms.map.texture = material.map;
618

619 620 621 622 623
		material.uniforms.env_map.texture = material.env_map;
		material.uniforms.reflectivity.value = material.reflectivity;
		material.uniforms.refraction_ratio.value = material.refraction_ratio;
		material.uniforms.combine.value = material.combine;
		material.uniforms.useRefract.value = material.env_map && material.env_map.mapping instanceof THREE.CubeRefractionMapping;
624

625 626 627
		if ( fog ) {

			material.uniforms.fogColor.value.setHex( fog.color.hex );
628

629
			if ( fog instanceof THREE.Fog ) {
630

631 632
				material.uniforms.fogNear.value = fog.near;
				material.uniforms.fogFar.value = fog.far;
633

634
			} else if ( fog instanceof THREE.FogExp2 ) {
635

636
				material.uniforms.fogDensity.value = fog.density;
637

638 639 640
			}

		}
641

642
	};
643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666

	function refreshUniformsLine( material, fog ) {
		
		material.uniforms.color.value.setRGB( material.color.r * material.opacity, material.color.g * material.opacity, material.color.b * material.opacity );		
		material.uniforms.opacity.value = material.opacity;

		if ( fog ) {

			material.uniforms.fogColor.value.setHex( fog.color.hex );

			if ( fog instanceof THREE.Fog ) {

				material.uniforms.fogNear.value = fog.near;
				material.uniforms.fogFar.value = fog.far;

			} else if ( fog instanceof THREE.FogExp2 ) {

				material.uniforms.fogDensity.value = fog.density;

			}

		}

	};
667
	
668 669 670 671 672 673 674 675 676 677 678
	function refreshUniformsPhong( material ) {
		
		//material.uniforms.ambient.value.setHex( material.ambient.hex );
		//material.uniforms.specular.value.setHex( material.specular.hex );
		material.uniforms.ambient.value.setRGB( material.ambient.r, material.ambient.g, material.ambient.b );
		material.uniforms.specular.value.setRGB( material.specular.r, material.specular.g, material.specular.b );
		material.uniforms.shininess.value = material.shininess;
		
	};
	
	
679 680 681 682 683 684 685 686 687
	function refreshLights( material, lights ) {
		
		material.uniforms.enableLighting.value = lights.directional.positions.length + lights.point.positions.length;
		material.uniforms.ambientLightColor.value = lights.ambient;
		material.uniforms.directionalLightColor.value = lights.directional.colors;
		material.uniforms.directionalLightDirection.value = lights.directional.positions;
		material.uniforms.pointLightColor.value = lights.point.colors;
		material.uniforms.pointLightPosition.value = lights.point.positions;
		
A
alteredq 已提交
688
	};
689
	
690
	this.renderBuffer = function ( camera, lights, fog, material, geometryChunk, object ) {
691

692
		var program, u, identifiers, attributes, parameters, vector_lights, maxLightCount, linewidth, primitives;
M
Mr.doob 已提交
693

694
		if ( !material.program ) {
M
Mr.doob 已提交
695

696
			if ( material instanceof THREE.MeshDepthMaterial ) {
697

698
				setMaterialShaders( material, THREE.ShaderLib[ 'depth' ] );
699

700 701
				material.uniforms.mNear.value = camera.near;
				material.uniforms.mFar.value = camera.far;
702

703
			} else if ( material instanceof THREE.MeshNormalMaterial ) {
704

705
				setMaterialShaders( material, THREE.ShaderLib[ 'normal' ] );
706

707
			} else if ( material instanceof THREE.MeshBasicMaterial ) {
708

709
				setMaterialShaders( material, THREE.ShaderLib[ 'basic' ] );
710

711 712 713 714 715 716 717 718 719 720 721 722 723 724
				refreshUniformsCommon( material, fog );
				
			} else if ( material instanceof THREE.MeshLambertMaterial ) {
				
				setMaterialShaders( material, THREE.ShaderLib[ 'lambert' ] );
				
				refreshUniformsCommon( material, fog );
				
			} else if ( material instanceof THREE.MeshPhongMaterial ) {
				
				setMaterialShaders( material, THREE.ShaderLib[ 'phong' ] );
				
				refreshUniformsCommon( material, fog );
				
725 726 727 728 729 730
			} else if ( material instanceof THREE.LineBasicMaterial ) {
				
				setMaterialShaders( material, THREE.ShaderLib[ 'basic' ] );

				refreshUniformsLine( material, fog );
				
731
			}
732

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

736
			maxLightCount = allocateLights( lights, 4 );
M
Mr.doob 已提交
737

738 739
			parameters = { fog: fog, map: material.map, env_map: material.env_map, maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point };
			material.program = buildProgram( material.fragment_shader, material.vertex_shader, parameters );
M
Mr.doob 已提交
740

741 742
			identifiers = [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition' ];
			for( u in material.uniforms ) {
743

744
				identifiers.push(u);
M
Mr.doob 已提交
745

M
Mr.doob 已提交
746
			}
M
Mr.doob 已提交
747

748 749
			cacheUniformLocations( material.program, identifiers );
			cacheAttributeLocations( material.program, [ "position", "normal", "uv", "tangent" ] );
M
Mr.doob 已提交
750

M
Mr.doob 已提交
751
		}
M
Mr.doob 已提交
752

753 754
		program = material.program;

M
Mr.doob 已提交
755
		if( program != _oldProgram ) {
M
Mr.doob 已提交
756

M
Mr.doob 已提交
757 758
			_gl.useProgram( program );
			_oldProgram = program;
M
Mr.doob 已提交
759

M
Mr.doob 已提交
760
		}
M
Mr.doob 已提交
761

762 763
		this.loadCamera( program, camera );
		this.loadMatrices( program );
M
Mr.doob 已提交
764

765
		if ( material instanceof THREE.MeshPhongMaterial || 
766
			 material instanceof THREE.MeshLambertMaterial ) {
767

768 769
			vector_lights = this.setupLights( program, lights );
			refreshLights( material, vector_lights );
M
Mr.doob 已提交
770 771 772

		}

773 774 775 776 777
		if ( material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
			 material instanceof THREE.MeshPhongMaterial ) {
			
			refreshUniformsCommon( material, fog );
M
Mr.doob 已提交
778

A
alteredq 已提交
779
		}
780
		
781 782 783 784 785
		if ( material instanceof THREE.LineBasicMaterial ) {
			
			refreshUniformsLine( material, fog );
		}
		
M
Mr.doob 已提交
786
		if ( material instanceof THREE.MeshPhongMaterial ) {
787
			
788
			refreshUniformsPhong( material );
M
Mr.doob 已提交
789

790
		}
M
Mr.doob 已提交
791

792
		setUniforms( program, material.uniforms );
793

794
		attributes = program.attributes;
M
Mr.doob 已提交
795

796
		// vertices
M
Mr.doob 已提交
797

M
Mr.doob 已提交
798
		_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLVertexBuffer );
799
		_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
800
		_gl.enableVertexAttribArray( attributes.position );
801 802

		// normals
M
Mr.doob 已提交
803

804
		if ( attributes.normal >= 0 ) {
805

806 807
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLNormalBuffer );
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
808
			_gl.enableVertexAttribArray( attributes.normal );
809

810
		}
811

812 813 814
		// tangents

		if ( attributes.tangent >= 0 ) {
815

816 817
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLTangentBuffer );
			_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
818
			_gl.enableVertexAttribArray( attributes.tangent );
819

820
		}
821

822
		// uvs
M
Mr.doob 已提交
823

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

826
			if ( geometryChunk.__webGLUVBuffer ) {
827

828
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLUVBuffer );
829
				_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
830

831
				_gl.enableVertexAttribArray( attributes.uv );
832

833
			} else {
834

835
				_gl.disableVertexAttribArray( attributes.uv );
M
Mr.doob 已提交
836

837
			}
838 839 840

		}

841
		// render lines
M
Mr.doob 已提交
842

843
		if ( material.wireframe || material instanceof THREE.LineBasicMaterial ) {
844

845
			linewidth = material.wireframe_linewidth !== undefined ? material.wireframe_linewidth : 
846
						material.linewidth !== undefined ? material.linewidth : 1;
847
			
848
			primitives = material instanceof THREE.LineBasicMaterial && object.type == THREE.LineStrip ? _gl.LINE_STRIP : _gl.LINES;
849
			
850 851
			_gl.lineWidth( linewidth );
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryChunk.__webGLLineBuffer );
852
			_gl.drawElements( primitives, geometryChunk.__webGLLineCount, _gl.UNSIGNED_SHORT, 0 );
853

854
		// render triangles
M
Mr.doob 已提交
855

A
alteredq 已提交
856
		} else {
857

858 859
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryChunk.__webGLFaceBuffer );
			_gl.drawElements( _gl.TRIANGLES, geometryChunk.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
860 861 862 863 864

		}

	};

A
alteredq 已提交
865
	this.renderPass = function ( camera, lights, fog, object, geometryChunk, blending, transparent ) {
M
Mr.doob 已提交
866

M
Mr.doob 已提交
867
		var i, l, m, ml, material, meshMaterial;
M
Mr.doob 已提交
868

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

M
Mr.doob 已提交
871
			meshMaterial = object.materials[ m ];
872

M
Mr.doob 已提交
873
			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
874

M
Mr.doob 已提交
875 876 877
				for ( i = 0, l = geometryChunk.materials.length; i < l; i++ ) {

					material = geometryChunk.materials[ i ];
878

879
					if ( material && material.blending == blending && ( material.opacity < 1.0 == transparent ) ) {
M
Mr.doob 已提交
880

M
Mr.doob 已提交
881
						this.setBlending( material.blending );
882
						this.renderBuffer( camera, lights, fog, material, geometryChunk, object );
M
Mr.doob 已提交
883

884 885
					}

M
Mr.doob 已提交
886
				}
887

M
Mr.doob 已提交
888
			} else {
889

M
Mr.doob 已提交
890
				material = meshMaterial;
891
				if ( material && material.blending == blending && ( material.opacity < 1.0 == transparent ) ) {
M
Mr.doob 已提交
892

M
Mr.doob 已提交
893
					this.setBlending( material.blending );
894
					this.renderBuffer( camera, lights, fog, material, geometryChunk, object );
M
Mr.doob 已提交
895

896 897 898
				}

			}
899 900

		}
M
Mr.doob 已提交
901

902
	};
M
Mr.doob 已提交
903

A
alteredq 已提交
904
	this.render = function( scene, camera, renderTarget, clear ) {
M
Mr.doob 已提交
905

M
Mr.doob 已提交
906
		var o, ol, webGLObject, object, buffer,
A
alteredq 已提交
907 908
			lights = scene.lights,
			fog = scene.fog;
M
Mr.doob 已提交
909

M
Mr.doob 已提交
910
		this.initWebGLObjects( scene );
M
Mr.doob 已提交
911

A
alteredq 已提交
912
		setRenderTarget( renderTarget, clear !==undefined ? clear : true );
913
		
914
		if ( this.autoClear ) {
915
			
916
			this.clear();
917
			
918 919
		}

920
		camera.autoUpdateMatrix && camera.updateMatrix();
M
Mr.doob 已提交
921

922 923
		_viewMatrixArray.set( camera.matrix.flatten() );
		_projectionMatrixArray.set( camera.projectionMatrix.flatten() );
924
		
M
Mr.doob 已提交
925
		// opaque pass
M
Mr.doob 已提交
926

M
Mr.doob 已提交
927
		for ( o = 0, ol = scene.__webGLObjects.length; o < ol; o++ ) {
M
Mr.doob 已提交
928

M
Mr.doob 已提交
929
			webGLObject = scene.__webGLObjects[ o ];
M
Mr.doob 已提交
930

M
Mr.doob 已提交
931 932
			object = webGLObject.object;
			buffer = webGLObject.buffer;
M
Mr.doob 已提交
933

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

M
Mr.doob 已提交
936
				this.setupMatrices( object, camera );
A
alteredq 已提交
937
				this.renderPass( camera, lights, fog, object, buffer, THREE.NormalBlending, false );
M
Mr.doob 已提交
938

939
			}
M
Mr.doob 已提交
940

M
Mr.doob 已提交
941
		}
M
Mr.doob 已提交
942

M
Mr.doob 已提交
943
		// transparent pass
M
Mr.doob 已提交
944

M
Mr.doob 已提交
945
		for ( o = 0, ol = scene.__webGLObjects.length; o < ol; o++ ) {
M
Mr.doob 已提交
946

M
Mr.doob 已提交
947
			webGLObject = scene.__webGLObjects[ o ];
M
Mr.doob 已提交
948

M
Mr.doob 已提交
949 950
			object = webGLObject.object;
			buffer = webGLObject.buffer;
M
Mr.doob 已提交
951

M
Mr.doob 已提交
952
			if ( object.visible ) {
M
Mr.doob 已提交
953

M
Mr.doob 已提交
954
				this.setupMatrices( object, camera );
955

956
				// opaque blended materials
M
Mr.doob 已提交
957

A
alteredq 已提交
958 959
				this.renderPass( camera, lights, fog, object, buffer, THREE.AdditiveBlending, false );
				this.renderPass( camera, lights, fog, object, buffer, THREE.SubtractiveBlending, false );
M
Mr.doob 已提交
960

961
				// transparent blended materials
M
Mr.doob 已提交
962

A
alteredq 已提交
963 964
				this.renderPass( camera, lights, fog, object, buffer, THREE.AdditiveBlending, true );
				this.renderPass( camera, lights, fog, object, buffer, THREE.SubtractiveBlending, true );
965

966
				// transparent normal materials
M
Mr.doob 已提交
967

A
alteredq 已提交
968
				this.renderPass( camera, lights, fog, object, buffer, THREE.NormalBlending, true );
M
Mr.doob 已提交
969

970
			}
M
Mr.doob 已提交
971

M
Mr.doob 已提交
972
		}
M
Mr.doob 已提交
973

974 975 976
		// Generate mipmap if we're using any kind of mipmap filtering
		
		if ( renderTarget && renderTarget.min_filter !== THREE.NearestFilter && renderTarget.min_filter !== THREE.LinearFilter ) {
M
Mr.doob 已提交
977

978 979 980
			updateRenderTargetMipmap( renderTarget );
			
		}
981

M
Mr.doob 已提交
982
	};
983
	
M
Mr.doob 已提交
984
	this.initWebGLObjects = function( scene ) {
M
Mr.doob 已提交
985

986 987 988 989 990 991 992 993 994 995 996
		function add_buffer( objmap, id, buffer, object ) {
			
			if ( objmap[ id ] == undefined ) {

				scene.__webGLObjects.push( { buffer: buffer, object: object } );
				objmap[ id ] = 1;

			}
			
		};
		
997
		var o, ol, object, g, geometry, geometryChunk, objmap;
M
Mr.doob 已提交
998

M
Mr.doob 已提交
999
		if ( !scene.__webGLObjects ) {
M
Mr.doob 已提交
1000

M
Mr.doob 已提交
1001
			scene.__webGLObjects = [];
M
Mr.doob 已提交
1002
			scene.__webGLObjectsMap = {};
M
Mr.doob 已提交
1003

M
Mr.doob 已提交
1004
		}
1005
		
1006 1007 1008
		for ( o = 0, ol = scene.objects.length; o < ol; o++ ) {

			object = scene.objects[ o ];
1009 1010
			geometry = object.geometry;
			
1011
			if ( scene.__webGLObjectsMap[ object.id ] == undefined ) {
M
Mr.doob 已提交
1012

1013
				scene.__webGLObjectsMap[ object.id ] = {};
M
Mr.doob 已提交
1014

1015
			}
1016

1017 1018 1019
			objmap = scene.__webGLObjectsMap[ object.id ];
			
			if ( object instanceof THREE.Mesh ) {
1020
				
M
Mr.doob 已提交
1021
				// create separate VBOs per geometry chunk
M
Mr.doob 已提交
1022

1023
				for ( g in geometry.geometryChunks ) {
M
Mr.doob 已提交
1024

1025
					geometryChunk = geometry.geometryChunks[ g ];
M
Mr.doob 已提交
1026

M
Mr.doob 已提交
1027
					// initialise VBO on the first access
M
Mr.doob 已提交
1028

M
Mr.doob 已提交
1029
					if( ! geometryChunk.__webGLVertexBuffer ) {
M
Mr.doob 已提交
1030

1031 1032
						this.createMeshBuffers( geometryChunk );
						this.initMeshBuffers( geometryChunk, object );
1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043
						
						geometry.__dirtyVertices = true;
						geometry.__dirtyElements = true;
						geometry.__dirtyUvs = true;
						geometry.__dirtyNormals = true;
						geometry.__dirtyTangents = true;

					}

					if( geometry.__dirtyVertices || geometry.__dirtyElements || geometry.__dirtyUvs ) {

1044
						this.setMeshBuffers( geometryChunk, object, _gl.DYNAMIC_DRAW,
1045 1046 1047
										 geometry.__dirtyVertices, geometry.__dirtyElements, geometry.__dirtyUvs,
										 geometry.__dirtyNormals, geometry.__dirtyTangents );
						
M
Mr.doob 已提交
1048 1049

					}
M
Mr.doob 已提交
1050

M
Mr.doob 已提交
1051
					// create separate wrapper per each use of VBO
M
Mr.doob 已提交
1052

1053
					add_buffer( objmap, g, geometryChunk, object );
M
Mr.doob 已提交
1054

M
Mr.doob 已提交
1055
				}
1056

1057 1058 1059 1060 1061 1062
				geometry.__dirtyVertices = false;
				geometry.__dirtyElements = false;
				geometry.__dirtyUvs = false;
				geometry.__dirtyNormals = false;
				geometry.__dirtyTangents = false;

1063 1064 1065
			} else if ( object instanceof THREE.Line ) {
				
				
1066
				if( ! geometry.__webGLVertexBuffer ) {
1067
				
1068 1069 1070 1071 1072
					this.createLineBuffers( geometry );
					this.initLineBuffers( geometry );
					
					geometry.__dirtyVertices = true;
					geometry.__dirtyElements = true;
1073 1074 1075
					
				}
				
1076 1077 1078 1079 1080
				if( geometry.__dirtyVertices ) {
					
					this.setLineBuffers( geometry, _gl.DYNAMIC_DRAW, geometry.__dirtyVertices, geometry.__dirtyElements );
					
				}
1081
				
1082 1083 1084 1085
				add_buffer( objmap, 0, geometry, object );
				
				geometry.__dirtyVertices = false;
				geometry.__dirtyElements = false;
1086

1087
			} else if ( object instanceof THREE.ParticleSystem ) {
1088

1089
				if( ! geometry.__webGLVertexBuffer ) {
1090
				
1091
					this.createParticleBuffers( geometry );
1092
					
1093
				}
1094
				
1095
				add_buffer( objmap, 0, geometry, object );
1096 1097 1098
				
				
			}/*else if ( object instanceof THREE.Particle ) {
M
Mr.doob 已提交
1099 1100 1101

			}*/

M
Mr.doob 已提交
1102
		}
1103 1104 1105 1106 1107 1108

	};

	this.removeObject = function ( scene, object ) {

		var o, ol, zobject;
M
Mr.doob 已提交
1109

1110
		for ( o = scene.__webGLObjects.length - 1; o >= 0; o-- ) {
M
Mr.doob 已提交
1111

M
Mr.doob 已提交
1112
			zobject = scene.__webGLObjects[ o ].object;
M
Mr.doob 已提交
1113

1114
			if ( object == zobject ) {
1115 1116 1117 1118

				scene.__webGLObjects.splice( o, 1 );

			}
M
Mr.doob 已提交
1119

1120
		}
M
Mr.doob 已提交
1121

M
Mr.doob 已提交
1122
	};
M
Mr.doob 已提交
1123

M
Mr.doob 已提交
1124
	this.setupMatrices = function ( object, camera ) {
1125

M
Mr.doob 已提交
1126
		object.autoUpdateMatrix && object.updateMatrix();
1127

M
Mr.doob 已提交
1128
		_modelViewMatrix.multiply( camera.matrix, object.matrix );
M
Mr.doob 已提交
1129
		_modelViewMatrixArray.set( _modelViewMatrix.flatten() );
1130

M
Mr.doob 已提交
1131
		_normalMatrix = THREE.Matrix4.makeInvert3x3( _modelViewMatrix ).transpose();
M
Mr.doob 已提交
1132
		_normalMatrixArray.set( _normalMatrix.m );
1133

M
Mr.doob 已提交
1134
		_objectMatrixArray.set( object.matrix.flatten() );
M
Mr.doob 已提交
1135

M
Mr.doob 已提交
1136
	};
M
Mr.doob 已提交
1137

M
Mr.doob 已提交
1138
	this.loadMatrices = function ( program ) {
M
Mr.doob 已提交
1139

M
Mr.doob 已提交
1140 1141 1142 1143
		_gl.uniformMatrix4fv( program.uniforms.viewMatrix, false, _viewMatrixArray );
		_gl.uniformMatrix4fv( program.uniforms.modelViewMatrix, false, _modelViewMatrixArray );
		_gl.uniformMatrix4fv( program.uniforms.projectionMatrix, false, _projectionMatrixArray );
		_gl.uniformMatrix3fv( program.uniforms.normalMatrix, false, _normalMatrixArray );
M
Mr.doob 已提交
1144
		_gl.uniformMatrix4fv( program.uniforms.objectMatrix, false, _objectMatrixArray );
M
Mr.doob 已提交
1145

M
Mr.doob 已提交
1146
	};
1147

M
Mr.doob 已提交
1148
	this.loadCamera = function( program, camera ) {
M
Mr.doob 已提交
1149

M
Mr.doob 已提交
1150
		_gl.uniform3f( program.uniforms.cameraPosition, camera.position.x, camera.position.y, camera.position.z );
M
Mr.doob 已提交
1151

M
Mr.doob 已提交
1152
	};
M
Mr.doob 已提交
1153

M
Mr.doob 已提交
1154
	this.setBlending = function( blending ) {
M
Mr.doob 已提交
1155

M
Mr.doob 已提交
1156
		switch ( blending ) {
1157

M
Mr.doob 已提交
1158
			case THREE.AdditiveBlending:
1159

M
Mr.doob 已提交
1160 1161
				_gl.blendEquation( _gl.FUNC_ADD );
				_gl.blendFunc( _gl.ONE, _gl.ONE );
M
Mr.doob 已提交
1162

M
Mr.doob 已提交
1163
				break;
1164

M
Mr.doob 已提交
1165
			case THREE.SubtractiveBlending:
1166

M
Mr.doob 已提交
1167 1168
				//_gl.blendEquation( _gl.FUNC_SUBTRACT );
				_gl.blendFunc( _gl.DST_COLOR, _gl.ZERO );
M
Mr.doob 已提交
1169

M
Mr.doob 已提交
1170
				break;
M
Mr.doob 已提交
1171

M
Mr.doob 已提交
1172
			default:
M
Mr.doob 已提交
1173

M
Mr.doob 已提交
1174 1175
				_gl.blendEquation( _gl.FUNC_ADD );
				_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
M
Mr.doob 已提交
1176

M
Mr.doob 已提交
1177
				break;
N
Nicolas Garcia Belmonte 已提交
1178
		}
M
Mr.doob 已提交
1179

N
Nicolas Garcia Belmonte 已提交
1180
	};
M
Mr.doob 已提交
1181

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

1184
		if ( cullFace ) {
M
Mr.doob 已提交
1185

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

1188
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
1189

1190
			} else {
M
Mr.doob 已提交
1191

1192
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
1193

1194
			}
M
Mr.doob 已提交
1195

1196
			if( cullFace == "back" ) {
M
Mr.doob 已提交
1197

1198
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
1199

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

1202
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
1203

1204
			} else {
M
Mr.doob 已提交
1205

1206
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
1207

1208
			}
M
Mr.doob 已提交
1209

1210
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
1211

1212
		} else {
M
Mr.doob 已提交
1213

1214
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
1215

1216 1217 1218
		}

	};
N
Nicolas Garcia Belmonte 已提交
1219

1220
	this.supportsVertexTextures = function() {
1221

1222
		return maxVertexTextures() > 0;
1223

1224
	};
1225

1226
	function maxVertexTextures() {
1227

1228 1229 1230
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
1231

1232
	function initGL( antialias, clearColor, clearAlpha ) {
N
Nicolas Garcia Belmonte 已提交
1233 1234 1235

		try {

1236
			_gl = _canvas.getContext( 'experimental-webgl', { antialias: antialias } );
N
Nicolas Garcia Belmonte 已提交
1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252

		} catch(e) { }

		if (!_gl) {

			alert("WebGL not supported");
			throw "cannot create webgl context";

		}

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

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

1253 1254
		_gl.frontFace( _gl.CCW );
		_gl.cullFace( _gl.BACK );
1255
		_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
1256

N
Nicolas Garcia Belmonte 已提交
1257
		_gl.enable( _gl.BLEND );
1258
		_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
1259
		_gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
N
Nicolas Garcia Belmonte 已提交
1260

1261
	};
1262
	
1263
	function buildProgram( fragment_shader, vertex_shader, parameters ) {
M
Mr.doob 已提交
1264

M
Mr.doob 已提交
1265
		var program = _gl.createProgram(),
M
Mr.doob 已提交
1266

M
Mr.doob 已提交
1267 1268 1269 1270
		prefix_fragment = [
			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",
1271 1272 1273
		
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
1274

1275 1276
			parameters.fog ? "#define USE_FOG" : "",
			parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "",
1277

1278 1279
			parameters.map ? "#define USE_MAP" : "",
			parameters.env_map ? "#define USE_ENVMAP" : "",
1280

1281
			"uniform mat4 viewMatrix;",
1282
			"uniform vec3 cameraPosition;",
M
Mr.doob 已提交
1283 1284
			""
		].join("\n"),
1285

M
Mr.doob 已提交
1286
		prefix_vertex = [
1287
			maxVertexTextures() > 0 ? "#define VERTEX_TEXTURES" : "",
1288

1289 1290 1291
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

1292 1293 1294
			parameters.map ? "#define USE_MAP" : "",
			parameters.env_map ? "#define USE_ENVMAP" : "",

M
Mr.doob 已提交
1295 1296 1297
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
1298 1299
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
1300
			"uniform vec3 cameraPosition;",
M
Mr.doob 已提交
1301 1302 1303
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
M
Mr.doob 已提交
1304 1305
			""
		].join("\n");
1306

M
Mr.doob 已提交
1307 1308
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragment_shader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertex_shader ) );
M
Mr.doob 已提交
1309

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

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

M
Mr.doob 已提交
1314 1315
			alert( "Could not initialise shaders\n"+
					"VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
1316 1317 1318
			
			//console.log( prefix_fragment + fragment_shader );
			//console.log( prefix_vertex + vertex_shader );
M
Mr.doob 已提交
1319

N
Nicolas Garcia Belmonte 已提交
1320
		}
M
Mr.doob 已提交
1321

M
Mr.doob 已提交
1322
		program.uniforms = {};
1323
		program.attributes = {};
M
Mr.doob 已提交
1324

M
Mr.doob 已提交
1325
		return program;
M
Mr.doob 已提交
1326

M
Mr.doob 已提交
1327
	};
M
Mr.doob 已提交
1328

M
Mr.doob 已提交
1329
	function setUniforms( program, uniforms ) {
M
Mr.doob 已提交
1330

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

M
Mr.doob 已提交
1333
		for( u in uniforms ) {
M
Mr.doob 已提交
1334

1335 1336 1337
			location = program.uniforms[u];
			if ( !location ) continue;
			
1338 1339 1340 1341
			uniform = uniforms[u];
			
			type = uniform.type;
			value = uniform.value;
1342
			
M
Mr.doob 已提交
1343
			if( type == "i" ) {
M
Mr.doob 已提交
1344

M
Mr.doob 已提交
1345
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
1346

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

M
Mr.doob 已提交
1349
				_gl.uniform1f( location, value );
1350

A
alteredq 已提交
1351 1352 1353 1354
			} else if( type == "fv1" ) {

				_gl.uniform1fv( location, value );
				
1355 1356 1357 1358
			} else if( type == "fv" ) {

				_gl.uniform3fv( location, value );

1359 1360 1361 1362
			} else if( type == "v2" ) {

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

1363 1364 1365
			} else if( type == "v3" ) {

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

1367 1368 1369
			} else if( type == "c" ) {

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

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

M
Mr.doob 已提交
1373
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
1374

1375
				texture = uniform.texture;
M
Mr.doob 已提交
1376

1377
				if ( !texture ) continue;
M
Mr.doob 已提交
1378

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

1381
					setCubeTexture( texture, value );
M
Mr.doob 已提交
1382

1383
				} else {
M
Mr.doob 已提交
1384

1385
					setTexture( texture, value );
M
Mr.doob 已提交
1386

1387
				}
M
Mr.doob 已提交
1388

1389
			}
M
Mr.doob 已提交
1390

1391
		}
M
Mr.doob 已提交
1392

1393
	};
M
Mr.doob 已提交
1394

1395
	function setCubeTexture( texture, slot ) {
M
Mr.doob 已提交
1396

1397
		if ( texture.image.length == 6 ) {
N
Nicolas Garcia Belmonte 已提交
1398

1399 1400
			if ( !texture.image.__webGLTextureCube &&
				 !texture.image.__cubeMapInitialized && texture.image.loadCount == 6 ) {
M
Mr.doob 已提交
1401

1402
				texture.image.__webGLTextureCube = _gl.createTexture();
N
Nicolas Garcia Belmonte 已提交
1403

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

1406 1407
				_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 );
M
Mr.doob 已提交
1408

1409 1410
				_gl.texParameteri( _gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_MAG_FILTER, _gl.LINEAR );
				_gl.texParameteri( _gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_MIN_FILTER, _gl.LINEAR_MIPMAP_LINEAR );
M
Mr.doob 已提交
1411

1412
				for ( var i = 0; i < 6; ++i ) {
M
Mr.doob 已提交
1413

1414
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
M
Mr.doob 已提交
1415

1416
				}
M
Mr.doob 已提交
1417

1418
				_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
1419

1420
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
M
Mr.doob 已提交
1421

1422
				texture.image.__cubeMapInitialized = true;
M
Mr.doob 已提交
1423

M
Mr.doob 已提交
1424
			}
1425 1426 1427

			_gl.activeTexture( _gl.TEXTURE0 + slot );
			_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube );
M
Mr.doob 已提交
1428

1429
		}
M
Mr.doob 已提交
1430

M
Mr.doob 已提交
1431
	};
M
Mr.doob 已提交
1432

1433
	function setTexture( texture, slot ) {
M
Mr.doob 已提交
1434

1435 1436 1437 1438 1439
		if ( !texture.__webGLTexture && texture.image.loaded ) {

			texture.__webGLTexture = _gl.createTexture();
			_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 已提交
1440

1441 1442
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrap_s ) );
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrap_t ) );
M
Mr.doob 已提交
1443 1444 1445

			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.mag_filter ) );
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.min_filter ) );
1446 1447 1448 1449 1450 1451 1452
			_gl.generateMipmap( _gl.TEXTURE_2D );
			_gl.bindTexture( _gl.TEXTURE_2D, null );

		}

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

1454
	};
M
Mr.doob 已提交
1455

A
alteredq 已提交
1456
	function setRenderTarget( renderTexture, clear ) {
1457 1458

		if ( renderTexture && !renderTexture.__webGLFramebuffer ) {
1459
			
1460 1461 1462 1463 1464
			renderTexture.__webGLFramebuffer = _gl.createFramebuffer();
			renderTexture.__webGLRenderbuffer = _gl.createRenderbuffer();
			renderTexture.__webGLTexture = _gl.createTexture();

			// Setup renderbuffer
1465
			
1466 1467 1468 1469
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTexture.__webGLRenderbuffer );
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTexture.width, renderTexture.height );

			// Setup texture
1470
			
1471 1472 1473 1474 1475
			_gl.bindTexture( _gl.TEXTURE_2D, renderTexture.__webGLTexture );
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, paramThreeToGL( renderTexture.wrap_s ) );
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, paramThreeToGL( renderTexture.wrap_t ) );
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( renderTexture.mag_filter ) );
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( renderTexture.min_filter ) );
1476
			_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTexture.format ), renderTexture.width, renderTexture.height, 0, paramThreeToGL( renderTexture.format ), paramThreeToGL( renderTexture.type ), null );
1477 1478

			// Setup framebuffer
1479
			
1480 1481
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTexture.__webGLFramebuffer );
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, renderTexture.__webGLTexture, 0 );
1482
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webGLRenderbuffer );
1483 1484

			// Release everything
1485
			
1486 1487 1488
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
1489
			
1490 1491
		}

1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511
		var framebuffer, width, height;
		
		if ( renderTexture ) {
			
			framebuffer = renderTexture.__webGLFramebuffer;
			width = renderTexture.width;
			height = renderTexture.height;
			
		} else {
			
			framebuffer = null;
			width = _canvas.width;
			height = _canvas.height;
			
		}
		
		if( framebuffer != _oldFramebuffer ) {
			
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
			_gl.viewport( 0, 0, width, height );
A
alteredq 已提交
1512 1513 1514 1515 1516 1517
			
			if ( clear ) {
			
				_gl.clear( _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT );
				
			}
1518 1519 1520 1521
			
			_oldFramebuffer = framebuffer;
			
		}
1522

1523 1524 1525 1526 1527 1528 1529 1530 1531
	};
	
	function updateRenderTargetMipmap( renderTarget ) {
		
		_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webGLTexture );
		_gl.generateMipmap( _gl.TEXTURE_2D );
		_gl.bindTexture( _gl.TEXTURE_2D, null );
		
	};	
1532

M
Mr.doob 已提交
1533
	function cacheUniformLocations( program, identifiers ) {
M
Mr.doob 已提交
1534

M
Mr.doob 已提交
1535
		var i, l, id;
M
Mr.doob 已提交
1536

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

1539 1540
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
1541

M
Mr.doob 已提交
1542
		}
M
Mr.doob 已提交
1543

M
Mr.doob 已提交
1544
	};
M
Mr.doob 已提交
1545

1546
	function cacheAttributeLocations( program, identifiers ) {
1547

1548
		var i, l, id;
M
Mr.doob 已提交
1549

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

1552 1553
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
1554

1555
		}
M
Mr.doob 已提交
1556

M
Mr.doob 已提交
1557
	};
M
Mr.doob 已提交
1558

N
Nicolas Garcia Belmonte 已提交
1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583
	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 已提交
1584

1585
	};
N
Nicolas Garcia Belmonte 已提交
1586

1587
	function paramThreeToGL( p ) {
M
Mr.doob 已提交
1588

1589
		switch ( p ) {
M
Mr.doob 已提交
1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602

			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;

1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616
			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;

1617
		}
M
Mr.doob 已提交
1618

1619
		return 0;
M
Mr.doob 已提交
1620

1621 1622 1623 1624 1625 1626
	};

	function materialNeedsSmoothNormals( material ) {

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

1627
	};
M
Mr.doob 已提交
1628

M
Mr.doob 已提交
1629
	function bufferNeedsSmoothNormals( geometryChunk, object ) {
M
Mr.doob 已提交
1630

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

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

M
Mr.doob 已提交
1635
			meshMaterial = object.materials[ m ];
1636 1637 1638

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

M
Mr.doob 已提交
1639
				for ( i = 0, l = geometryChunk.materials.length; i < l; i++ ) {
1640

M
Mr.doob 已提交
1641
					if ( materialNeedsSmoothNormals( geometryChunk.materials[ i ] ) ) {
1642

1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663
						needsSmoothNormals = true;
						break;

					}

				}

			} else {

				if ( materialNeedsSmoothNormals( meshMaterial ) ) {

					needsSmoothNormals = true;
					break;

				}

			}

			if ( needsSmoothNormals ) break;

		}
M
Mr.doob 已提交
1664

1665
		return needsSmoothNormals;
M
Mr.doob 已提交
1666

1667
	};
M
Mr.doob 已提交
1668

1669
	function allocateLights( lights, maxLights ) {
1670

1671 1672
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
1673

1674
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
1675

1676
			light = lights[ l ];
1677

1678 1679
			if ( light instanceof THREE.DirectionalLight ) dirLights++;
			if ( light instanceof THREE.PointLight ) pointLights++;
1680

1681
		}
1682

1683
		if ( ( pointLights + dirLights ) <= maxLights ) {
1684

1685 1686
			maxDirLights = dirLights;
			maxPointLights = pointLights;
1687

1688
		} else {
1689

1690 1691
			maxDirLights = Math.ceil( maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = maxLights - maxDirLights;
1692 1693 1694

		}

1695
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
1696 1697

	};
M
Mr.doob 已提交
1698

A
alteredq 已提交
1699
	/* DEBUG
1700
	function getGLParams() {
M
Mr.doob 已提交
1701

1702
		var params  = {
M
Mr.doob 已提交
1703

1704 1705
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
1706

1707 1708 1709
			'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 已提交
1710

1711 1712 1713
			'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 已提交
1714

1715 1716
		return params;
	};
M
Mr.doob 已提交
1717

1718
	function dumpObject( obj ) {
M
Mr.doob 已提交
1719

1720 1721
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
1722

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

1725
		}
M
Mr.doob 已提交
1726

1727 1728
		return str;
	}
A
alteredq 已提交
1729
	*/
1730

1731
};
1732

1733 1734
THREE.Snippets = {
	
1735
	fog_pars_fragment: [
M
Mr.doob 已提交
1736

1737
	"#ifdef USE_FOG",
1738

1739
		"uniform vec3 fogColor;",
1740

1741 1742 1743 1744 1745 1746
		"#ifdef FOG_EXP2",
			"uniform float fogDensity;",
		"#else",
			"uniform float fogNear;",
			"uniform float fogFar;",
		"#endif",
1747

1748
	"#endif"
1749

1750
	].join("\n"),
M
Mr.doob 已提交
1751

1752
	fog_fragment: [
1753

1754
	"#ifdef USE_FOG",
1755

1756 1757 1758 1759 1760 1761 1762 1763 1764
		"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",
1765

1766
		"gl_FragColor = mix( gl_FragColor, vec4( fogColor, 1.0 ), fogFactor );",
M
Mr.doob 已提交
1767

1768 1769
	"#endif"
	
1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907
	].join("\n"),
	
	envmap_pars_fragment: [
	
	"#ifdef USE_ENVMAP",
	
		"varying vec3 vReflect;",
		"uniform float reflectivity;",
		"uniform samplerCube env_map;",
		"uniform int combine;",
	
	"#endif"
	
	].join("\n"),
	
	envmap_fragment: [
	
	"#ifdef USE_ENVMAP",

		"cubeColor = textureCube( env_map, vec3( -vReflect.x, vReflect.yz ) );",
		
		"if ( combine == 1 ) {",

			"gl_FragColor = mix( gl_FragColor, cubeColor, reflectivity );",

		"} else {",

			"gl_FragColor = gl_FragColor * cubeColor;",

		"}",	

	"#endif"
	
	].join("\n"),
	
	envmap_pars_vertex: [
	
	"#ifdef USE_ENVMAP",
	
		"varying vec3 vReflect;",
		"uniform float refraction_ratio;",
		"uniform bool useRefract;",
		
	"#endif"
	
	].join("\n"),

	envmap_vertex : [
	
	"#ifdef USE_ENVMAP",
	
		"vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
		"vec3 nWorld = mat3( objectMatrix[0].xyz, objectMatrix[1].xyz, objectMatrix[2].xyz ) * normal;",
	
		"if ( useRefract ) {",

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

		"} else {",

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

		"}",

	"#endif"
	
	].join("\n"),
	
	map_pars_fragment: [
	
	"#ifdef USE_MAP",
		
		"varying vec2 vUv;",
		"uniform sampler2D map;",
		  
	"#endif"
	
	].join("\n"),
	
	map_pars_vertex: [
	
	"#ifdef USE_MAP",
	
		"varying vec2 vUv;",

	"#endif"
	
	].join("\n"),
	
	map_fragment: [

	"#ifdef USE_MAP",

		"mapColor = texture2D( map, vUv );",

	"#endif"
	
	].join("\n"),
	
	map_vertex: [
	
	"#ifdef USE_MAP",
	
		"vUv = uv;",
		
	"#endif"
	
	].join("\n"),
	
	lights_pars_vertex: [
	
	"uniform bool enableLighting;",
	"uniform vec3 ambientLightColor;",
	
	"#if MAX_DIR_LIGHTS > 0",
	
		"uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
		"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
		
	"#endif",

	"#if MAX_POINT_LIGHTS > 0",
	
		"uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
		"uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
		
		"#ifdef PHONG",
			"varying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];",
		"#endif",
		
	"#endif"
	
	].join("\n"),
	
	lights_vertex: [
	
	"if ( !enableLighting ) {",

A
alteredq 已提交
1908
		"vLightWeighting = vec3( 1.0 );",
1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943

	"} else {",

		"vLightWeighting = ambientLightColor;",

		"#if MAX_DIR_LIGHTS > 0",
		
		"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
		
			"vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
			"float directionalLightWeighting = max( dot( transformedNormal, normalize( lDirection.xyz ) ), 0.0 );",
			"vLightWeighting += directionalLightColor[ i ] * directionalLightWeighting;",
			
		"}",
		
		"#endif",

		"#if MAX_POINT_LIGHTS > 0",
		
		"for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {",
		
			"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;",
			
			"#ifdef PHONG",
				"vPointLightVector[ i ] = pointLightVector;",
			"#endif",
			
		"}",
		
		"#endif",
		
	"}"
1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028
	
	].join("\n"),
	
	lights_pars_fragment: [
	
	"#if MAX_DIR_LIGHTS > 0",
		"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
	"#endif",
	
	"#if MAX_POINT_LIGHTS > 0",
		"varying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];",
	"#endif",
	
	"varying vec3 vViewPosition;",
	"varying vec3 vNormal;"
	
	].join("\n"),
	
	lights_fragment: [
	
	"vec3 normal = normalize( vNormal );",
	"vec3 viewPosition = normalize( vViewPosition );",
	
	"vec4 mSpecular = vec4( specular, opacity );",

	"#if MAX_POINT_LIGHTS > 0",
		
		"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",
	
	"#if MAX_DIR_LIGHTS > 0",
	
		"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;",

		"}",
	
	"#endif",

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

	"#if MAX_DIR_LIGHTS > 0",
		"totalLight += dirDiffuse + dirSpecular;",
	"#endif",
	
	"#if MAX_POINT_LIGHTS > 0",
		"totalLight += pointDiffuse + pointSpecular;",
	"#endif"
2029

2030
	].join("\n")
2031

2032
};
2033

2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067
THREE.UniformsLib = {
	
	common: {
		
	"color"   : { type: "c", value: new THREE.Color( 0xeeeeee ) },
	"opacity" : { type: "f", value: 1 },
	"map"     : { type: "t", value: 0, texture: null },
	
	"env_map" 		  : { type: "t", value: 1, texture: null },
	"useRefract"	  : { type: "i", value: 0 },
	"reflectivity"    : { type: "f", value: 1 },
	"refraction_ratio": { type: "f", value: 0.98 },
	"combine"		  : { type: "i", value: 0 },
	
	"fogDensity": { type: "f", value: 0.00025 },
	"fogNear"	: { type: "f", value: 1 },
	"fogFar"	: { type: "f", value: 2000 },
	"fogColor"	: { type: "c", value: new THREE.Color( 0xffffff ) }
	
	},
	
	lights: {
		
	"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: [] }
	
	}
	
};

2068
THREE.ShaderLib = {
2069

2070
	'depth': {
M
Mr.doob 已提交
2071

2072 2073
		uniforms: { "mNear": { type: "f", value: 1.0 },
					"mFar" : { type: "f", value: 2000.0 } },
2074

2075
		fragment_shader: [
M
Mr.doob 已提交
2076

2077 2078
			"uniform float mNear;",
			"uniform float mFar;",
M
Mr.doob 已提交
2079

2080
			"void main() {",
M
Mr.doob 已提交
2081

2082 2083 2084
				"float depth = gl_FragCoord.z / gl_FragCoord.w;",
				"float color = 1.0 - smoothstep( mNear, mFar, depth );",
				"gl_FragColor = vec4( vec3( color ), 1.0 );",
M
Mr.doob 已提交
2085

2086
			"}"
M
Mr.doob 已提交
2087

2088
		].join("\n"),
2089

2090
		vertex_shader: [
2091

2092
			"void main() {",
2093

2094
				"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
2095

2096
			"}"
2097

2098
		].join("\n")
2099

2100
	},
2101

2102
	'normal': {
M
Mr.doob 已提交
2103

2104
		uniforms: { },
2105

2106
		fragment_shader: [
2107

2108
			"varying vec3 vNormal;",
M
Mr.doob 已提交
2109

2110
			"void main() {",
2111

2112
				"gl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, 1.0 );",
M
Mr.doob 已提交
2113

2114
			"}"
M
Mr.doob 已提交
2115

2116
		].join("\n"),
M
Mr.doob 已提交
2117

2118
		vertex_shader: [
2119

2120
			"varying vec3 vNormal;",
2121

2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133
			"void main() {",

				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
				"vNormal = normalize( normalMatrix * normal );",

				"gl_Position = projectionMatrix * mvPosition;",

			"}"

		].join("\n")

	},
2134

2135
	'basic': {
2136 2137 2138
		
		uniforms: THREE.UniformsLib[ "common" ],
		
2139
		fragment_shader: [
2140

2141 2142 2143
			"uniform vec3 color;",
			"uniform float opacity;",
			
2144 2145 2146
			THREE.Snippets[ "map_pars_fragment" ],
			THREE.Snippets[ "envmap_pars_fragment" ],
			THREE.Snippets[ "fog_pars_fragment" ],
2147 2148
				
			"void main() {",
2149

2150
				"vec4 mColor = vec4( color, opacity );",
A
alteredq 已提交
2151 2152
				"vec4 mapColor = vec4( 1.0 );",
				"vec4 cubeColor = vec4( 1.0 );",
2153

2154
				THREE.Snippets[ "map_fragment" ],
2155
				
2156 2157 2158 2159 2160 2161
				"gl_FragColor = mColor * mapColor;",
				
				THREE.Snippets[ "envmap_fragment" ],
				THREE.Snippets[ "fog_fragment" ],
				
			"}"
2162

2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177
		].join("\n"),
		
		vertex_shader: [
			
			THREE.Snippets[ "map_pars_vertex" ],
			THREE.Snippets[ "envmap_pars_vertex" ],
			
			"void main() {",
		
				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
				
				THREE.Snippets[ "map_vertex" ],
				THREE.Snippets[ "envmap_vertex" ],
				
				"gl_Position = projectionMatrix * mvPosition;",
2178

2179
			"}"
2180

2181 2182 2183
		].join("\n")
		
	},
2184

2185 2186
	'lambert': {
		
2187 2188
		uniforms: Uniforms.merge( [ THREE.UniformsLib[ "common" ], 
									THREE.UniformsLib[ "lights" ] ] ),
2189 2190 2191 2192 2193 2194 2195
		
		fragment_shader: [
			
			"uniform vec3 color;",
			"uniform float opacity;",
			
			"varying vec3 vLightWeighting;",
2196
				
2197 2198 2199
			THREE.Snippets[ "map_pars_fragment" ],
			THREE.Snippets[ "envmap_pars_fragment" ],
			THREE.Snippets[ "fog_pars_fragment" ],
2200
				
2201 2202 2203
			"void main() {",
					
				"vec4 mColor = vec4( color, opacity );",
A
alteredq 已提交
2204 2205
				"vec4 mapColor = vec4( 1.0 );",
				"vec4 cubeColor = vec4( 1.0 );",
2206 2207

				THREE.Snippets[ "map_fragment" ],
2208

2209
				"gl_FragColor =  mColor * mapColor * vec4( vLightWeighting, 1.0 );",
2210
				
2211
				THREE.Snippets[ "envmap_fragment" ],
2212 2213 2214 2215 2216 2217 2218 2219
				THREE.Snippets[ "fog_fragment" ],

			"}"

		].join("\n"),

		vertex_shader: [
		
2220
			"varying vec3 vLightWeighting;",
2221
			
2222 2223 2224
			THREE.Snippets[ "map_pars_vertex" ],
			THREE.Snippets[ "envmap_pars_vertex" ],
			THREE.Snippets[ "lights_pars_vertex" ],
2225 2226 2227
			
			"void main() {",
		
2228
				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
2229
				
2230 2231
				THREE.Snippets[ "map_vertex" ],
				THREE.Snippets[ "envmap_vertex" ],
2232
				
2233
				"vec3 transformedNormal = normalize( normalMatrix * normal );",
2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246
				
				THREE.Snippets[ "lights_vertex" ],
				
				"gl_Position = projectionMatrix * mvPosition;",

			"}"

		].join("\n")
		
	},
	
	'phong': {
		
2247 2248 2249
		uniforms: Uniforms.merge( [ THREE.UniformsLib[ "common" ], 
									THREE.UniformsLib[ "lights" ],
									
2250
									{ "ambient"  : { type: "c", value: new THREE.Color( 0x050505 ) },
2251 2252 2253 2254 2255
									  "specular" : { type: "c", value: new THREE.Color( 0x111111 ) },
									  "shininess": { type: "f", value: 30 }
									}
									
								] ),
2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317
		
		fragment_shader: [
			
			"uniform vec3 color;",
			"uniform float opacity;",
			
			"uniform vec3 ambient;",
			"uniform vec3 specular;",
			"uniform float shininess;",
				
			"varying vec3 vLightWeighting;",
				
			THREE.Snippets[ "map_pars_fragment" ],
			THREE.Snippets[ "envmap_pars_fragment" ],
			THREE.Snippets[ "fog_pars_fragment" ],
			THREE.Snippets[ "lights_pars_fragment" ],
				
			"void main() {",
					
				"vec4 mColor = vec4( color, opacity );",
				"vec4 mapColor = vec4( 1.0 );",
				"vec4 cubeColor = vec4( 1.0 );",

				THREE.Snippets[ "map_fragment" ],
				THREE.Snippets[ "lights_fragment" ],

				"gl_FragColor =  mapColor * totalLight * vec4( vLightWeighting, 1.0 );",
				
				THREE.Snippets[ "envmap_fragment" ],
				THREE.Snippets[ "fog_fragment" ],

			"}"

		].join("\n"),

		vertex_shader: [
		
			"#define PHONG",
			
			"varying vec3 vLightWeighting;",
			"varying vec3 vViewPosition;",
			"varying vec3 vNormal;",
			
			THREE.Snippets[ "map_pars_vertex" ],
			THREE.Snippets[ "envmap_pars_vertex" ],
			THREE.Snippets[ "lights_pars_vertex" ],
			
			"void main() {",
		
				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
				
				THREE.Snippets[ "map_vertex" ],
				THREE.Snippets[ "envmap_vertex" ],
				
				"#ifndef USE_ENVMAP",
					"vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
				"#endif",
				
				"vViewPosition = cameraPosition - mPosition.xyz;",
				
				"vec3 transformedNormal = normalize( normalMatrix * normal );",
				"vNormal = transformedNormal;",
2318

2319
				THREE.Snippets[ "lights_vertex" ],
2320
				
2321
				"gl_Position = projectionMatrix * mvPosition;",
2322 2323 2324 2325 2326

			"}"

		].join("\n")
		
2327
	}	
A
alteredq 已提交
2328

N
Nicolas Garcia Belmonte 已提交
2329
};