WebGLRenderer.js 47.2 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/
N
Nicolas Garcia Belmonte 已提交
5 6
 */

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

M
Mr.doob 已提交
9 10
	// 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 已提交
11

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

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

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

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

M
Mr.doob 已提交
22
	var _canvas = document.createElement( 'canvas' ), _gl,
23
	_oldProgram, _uberProgram,
24
	_modelViewMatrix = new THREE.Matrix4(), _normalMatrix,
M
Mr.doob 已提交
25 26 27 28

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

M
Mr.doob 已提交
32
	// ubershader material constants
M
Mr.doob 已提交
33

34
	LAMBERT = 1, PHONG = 2,
35 36 37

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

39 40
	maxLightCount = allocateLights( parameters.scene, 4 );
	fog = parameters.scene ? parameters.scene.fog : null,
A
alteredq 已提交
41
	
42 43 44 45
	antialias = parameters.antialias != undefined ? parameters.antialias : true,
	
	clearColor = parameters.clearColor ? new THREE.Color( parameters.clearColor ) : new THREE.Color( 0x000000 ),
	clearAlpha = parameters.clearAlpha ? parameters.clearAlpha : 0;
46
	
N
Nicolas Garcia Belmonte 已提交
47 48 49
	this.domElement = _canvas;
	this.autoClear = true;

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

A
alteredq 已提交
52
	_uberProgram = initUbershader( maxLightCount.directional, maxLightCount.point, fog );
53
	_oldProgram = _uberProgram;
M
Mr.doob 已提交
54

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 66 67 68 69 70 71
	this.setClearColor = function( hex, alpha ) {
		
		var color = new THREE.Color( hex );
		_gl.clearColor( color.r, color.g, color.b, alpha );
		
	};
	
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, g, b,
A
alteredq 已提交
81
			ambientLights = [], pointLights = [], directionalLights = [],
82
			colors = [], positions = [];
83

84
		_gl.uniform1i( program.uniforms.enableLighting, lights.length );
85

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

88
			light = lights[ l ];
89 90 91

			if ( light instanceof THREE.AmbientLight ) {

92
				ambientLights.push( light );
93

94
			} else if ( light instanceof THREE.DirectionalLight ) {
95

96
				directionalLights.push( light );
97

98 99
			} else if( light instanceof THREE.PointLight ) {

100
				pointLights.push( light );
M
Mr.doob 已提交
101

102 103 104
			}

		}
M
Mr.doob 已提交
105

106 107
		// sum all ambient lights
		r = g = b = 0.0;
M
Mr.doob 已提交
108

109
		for ( l = 0, ll = ambientLights.length; l < ll; l++ ) {
M
Mr.doob 已提交
110

111 112 113
			r += ambientLights[ l ].color.r;
			g += ambientLights[ l ].color.g;
			b += ambientLights[ l ].color.b;
M
Mr.doob 已提交
114

115
		}
M
Mr.doob 已提交
116

M
Mr.doob 已提交
117
		_gl.uniform3f( program.uniforms.ambientLightColor, r, g, b );
118 119

		// pass directional lights as float arrays
M
Mr.doob 已提交
120

121
		colors = []; positions = [];
M
Mr.doob 已提交
122

123
		for ( l = 0, ll = directionalLights.length; l < ll; l++ ) {
M
Mr.doob 已提交
124

125
			light = directionalLights[ l ];
M
Mr.doob 已提交
126

127 128 129 130 131 132 133
			colors.push( light.color.r * light.intensity );
			colors.push( light.color.g * light.intensity );
			colors.push( light.color.b * light.intensity );

			positions.push( light.position.x );
			positions.push( light.position.y );
			positions.push( light.position.z );
M
Mr.doob 已提交
134

135
		}
M
Mr.doob 已提交
136

137 138
		if ( directionalLights.length ) {

M
Mr.doob 已提交
139 140 141
			_gl.uniform1i(  program.uniforms.directionalLightNumber, directionalLights.length );
			_gl.uniform3fv( program.uniforms.directionalLightDirection, positions );
			_gl.uniform3fv( program.uniforms.directionalLightColor, colors );
M
Mr.doob 已提交
142

143
		}
144

145
		// pass point lights as float arrays
M
Mr.doob 已提交
146

147
		colors = []; positions = [];
M
Mr.doob 已提交
148

149
		for ( l = 0, ll = pointLights.length; l < ll; l++ ) {
M
Mr.doob 已提交
150

151
			light = pointLights[ l ];
M
Mr.doob 已提交
152

153 154 155 156 157 158 159
			colors.push( light.color.r * light.intensity );
			colors.push( light.color.g * light.intensity );
			colors.push( light.color.b * light.intensity );

			positions.push( light.position.x );
			positions.push( light.position.y );
			positions.push( light.position.z );
M
Mr.doob 已提交
160

161
		}
M
Mr.doob 已提交
162

163 164
		if ( pointLights.length ) {

M
Mr.doob 已提交
165 166 167
			_gl.uniform1i(  program.uniforms.pointLightNumber, pointLights.length );
			_gl.uniform3fv( program.uniforms.pointLightPosition, positions );
			_gl.uniform3fv( program.uniforms.pointLightColor, colors );
M
Mr.doob 已提交
168

169
		}
M
Mr.doob 已提交
170

171
	};
M
Mr.doob 已提交
172

M
Mr.doob 已提交
173
	this.createBuffers = function ( object, g ) {
174

175
		var f, fl, fi, face, vertexNormals, normal, uv, v1, v2, v3, v4, t1, t2, t3, t4, m, ml, i,
176 177 178 179 180 181

		faceArray = [],
		lineArray = [],

		vertexArray = [],
		normalArray = [],
182
		tangentArray = [],
183 184
		uvArray = [],

185
		vertexIndex = 0,
186

M
Mr.doob 已提交
187
		geometryChunk = object.geometry.geometryChunks[ g ],
188

M
Mr.doob 已提交
189
		needsSmoothNormals = bufferNeedsSmoothNormals ( geometryChunk, object );
M
Mr.doob 已提交
190

M
Mr.doob 已提交
191
		for ( f = 0, fl = geometryChunk.faces.length; f < fl; f++ ) {
192

M
Mr.doob 已提交
193
			fi = geometryChunk.faces[ f ];
194 195 196

			face = object.geometry.faces[ fi ];
			vertexNormals = face.vertexNormals;
197
			faceNormal = face.normal;
198 199 200 201 202 203 204 205 206 207 208 209
			uv = object.geometry.uvs[ fi ];

			if ( face instanceof THREE.Face3 ) {

				v1 = object.geometry.vertices[ face.a ].position;
				v2 = object.geometry.vertices[ face.b ].position;
				v3 = object.geometry.vertices[ face.c ].position;

				vertexArray.push( v1.x, v1.y, v1.z );
				vertexArray.push( v2.x, v2.y, v2.z );
				vertexArray.push( v3.x, v3.y, v3.z );

210
				if ( object.geometry.hasTangents ) {
211

212 213 214 215 216 217 218
					t1 = object.geometry.vertices[ face.a ].tangent;
					t2 = object.geometry.vertices[ face.b ].tangent;
					t3 = object.geometry.vertices[ face.c ].tangent;

					tangentArray.push( t1.x, t1.y, t1.z, t1.w );
					tangentArray.push( t2.x, t2.y, t2.z, t2.w );
					tangentArray.push( t3.x, t3.y, t3.z, t3.w );
219

220 221
				}

222
				if ( vertexNormals.length == 3 && needsSmoothNormals ) {
223

224

M
Mr.doob 已提交
225 226 227 228 229
					for ( i = 0; i < 3; i ++ ) {

						normalArray.push( vertexNormals[ i ].x, vertexNormals[ i ].y, vertexNormals[ i ].z );

					}
230 231 232

				} else {

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

235
						normalArray.push( faceNormal.x, faceNormal.y, faceNormal.z );
M
Mr.doob 已提交
236 237

					}
238 239 240 241 242

				}

				if ( uv ) {

M
Mr.doob 已提交
243 244 245
					for ( i = 0; i < 3; i ++ ) {

						uvArray.push( uv[ i ].u, uv[ i ].v );
M
Mr.doob 已提交
246

M
Mr.doob 已提交
247
					}
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271

				}

				faceArray.push( vertexIndex, vertexIndex + 1, vertexIndex + 2 );

				// TODO: don't add lines that already exist (faces sharing edge)

				lineArray.push( vertexIndex, vertexIndex + 1 );
				lineArray.push( vertexIndex, vertexIndex + 2 );
				lineArray.push( vertexIndex + 1, vertexIndex + 2 );

				vertexIndex += 3;

			} else if ( face instanceof THREE.Face4 ) {

				v1 = object.geometry.vertices[ face.a ].position;
				v2 = object.geometry.vertices[ face.b ].position;
				v3 = object.geometry.vertices[ face.c ].position;
				v4 = object.geometry.vertices[ face.d ].position;

				vertexArray.push( v1.x, v1.y, v1.z );
				vertexArray.push( v2.x, v2.y, v2.z );
				vertexArray.push( v3.x, v3.y, v3.z );
				vertexArray.push( v4.x, v4.y, v4.z );
272

273
				if ( object.geometry.hasTangents ) {
274

275 276 277 278 279 280 281 282 283
					t1 = object.geometry.vertices[ face.a ].tangent;
					t2 = object.geometry.vertices[ face.b ].tangent;
					t3 = object.geometry.vertices[ face.c ].tangent;
					t4 = object.geometry.vertices[ face.d ].tangent;

					tangentArray.push( t1.x, t1.y, t1.z, t1.w );
					tangentArray.push( t2.x, t2.y, t2.z, t2.w );
					tangentArray.push( t3.x, t3.y, t3.z, t3.w );
					tangentArray.push( t4.x, t4.y, t4.z, t4.w );
284

285
				}
286

287
				if ( vertexNormals.length == 4 && needsSmoothNormals ) {
288

M
Mr.doob 已提交
289 290 291 292 293
					for ( i = 0; i < 4; i ++ ) {

						normalArray.push( vertexNormals[ i ].x, vertexNormals[ i ].y, vertexNormals[ i ].z );

					}
294

295 296
				} else {

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

299
						normalArray.push( faceNormal.x, faceNormal.y, faceNormal.z );
M
Mr.doob 已提交
300 301

					}
302 303 304 305 306

				}

				if ( uv ) {

M
Mr.doob 已提交
307 308 309
					for ( i = 0; i < 4; i ++ ) {

						uvArray.push( uv[ i ].u, uv[ i ].v );
M
Mr.doob 已提交
310

M
Mr.doob 已提交
311
					}
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326

				}

				faceArray.push( vertexIndex, vertexIndex + 1, vertexIndex + 2 );
				faceArray.push( vertexIndex, vertexIndex + 2, vertexIndex + 3 );

				// TODO: don't add lines that already exist (faces sharing edge)

				lineArray.push( vertexIndex, vertexIndex + 1 );
				lineArray.push( vertexIndex, vertexIndex + 2 );
				lineArray.push( vertexIndex, vertexIndex + 3 );
				lineArray.push( vertexIndex + 1, vertexIndex + 2 );
				lineArray.push( vertexIndex + 2, vertexIndex + 3 );

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

328
			}
M
Mr.doob 已提交
329

330 331 332 333 334 335 336 337
		}

		if ( !vertexArray.length ) {

			return;

		}

M
Mr.doob 已提交
338 339
		geometryChunk.__webGLVertexBuffer = _gl.createBuffer();
		_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLVertexBuffer );
340 341
		_gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( vertexArray ), _gl.STATIC_DRAW );

M
Mr.doob 已提交
342 343
		geometryChunk.__webGLNormalBuffer = _gl.createBuffer();
		_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLNormalBuffer );
344 345
		_gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( normalArray ), _gl.STATIC_DRAW );

346
		if ( object.geometry.hasTangents ) {
347

348 349 350
			geometryChunk.__webGLTangentBuffer = _gl.createBuffer();
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLTangentBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( tangentArray ), _gl.STATIC_DRAW );
351

352
		}
353

354
		if ( uvArray.length > 0 ) {
M
Mr.doob 已提交
355

356 357 358
			geometryChunk.__webGLUVBuffer = _gl.createBuffer();
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLUVBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( uvArray ), _gl.STATIC_DRAW );
M
Mr.doob 已提交
359

360
		}
M
Mr.doob 已提交
361

M
Mr.doob 已提交
362 363
		geometryChunk.__webGLFaceBuffer = _gl.createBuffer();
		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryChunk.__webGLFaceBuffer );
364 365
		_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( faceArray ), _gl.STATIC_DRAW );

M
Mr.doob 已提交
366 367
		geometryChunk.__webGLLineBuffer = _gl.createBuffer();
		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryChunk.__webGLLineBuffer );
368 369
		_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( lineArray ), _gl.STATIC_DRAW );

M
Mr.doob 已提交
370 371
		geometryChunk.__webGLFaceCount = faceArray.length;
		geometryChunk.__webGLLineCount = lineArray.length;
372 373

	};
374
	
M
Mr.doob 已提交
375
	function setMaterialShaders( material, shaders ) {
376

M
Mr.doob 已提交
377 378
		material.fragment_shader = shaders.fragment_shader;
		material.vertex_shader = shaders.vertex_shader;
379
		material.uniforms = Uniforms.clone( shaders.uniforms );
380

M
Mr.doob 已提交
381
	};
382

383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413
	function refreshUniforms( material, fog ) {
		
		material.uniforms.color.value.setHex( material.color.hex );
		material.uniforms.opacity.value = material.opacity;
		material.uniforms.map.texture = material.map;
		
		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;
		
		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;
				
			}

		}
		
	};
	
A
alteredq 已提交
414
	this.renderBuffer = function ( camera, lights, fog, material, geometryChunk ) {
415

416 417
		var mColor, mOpacity, mReflectivity,
			mWireframe, mLineWidth, mBlending,
A
alteredq 已提交
418
			mAmbient, mSpecular, mShininess,
419
			mMap, envMap, mixEnvMap,
M
Mr.doob 已提交
420
			mRefractionRatio, useRefract,
421
			program, u, identifiers, attributes;
M
Mr.doob 已提交
422

M
Mr.doob 已提交
423

M
Mr.doob 已提交
424 425
		if ( material instanceof THREE.MeshShaderMaterial ||
			 material instanceof THREE.MeshDepthMaterial ||
426 427
			 material instanceof THREE.MeshNormalMaterial || 
			 material instanceof THREE.MeshBasicMaterial ) {
M
Mr.doob 已提交
428

M
Mr.doob 已提交
429
			if ( !material.program ) {
M
Mr.doob 已提交
430

M
Mr.doob 已提交
431
				if ( material instanceof THREE.MeshDepthMaterial ) {
432

433
					setMaterialShaders( material, THREE.ShaderLib[ 'depth' ] );
434

435 436
					material.uniforms.mNear.value = camera.near;
					material.uniforms.mFar.value = camera.far;
437

M
Mr.doob 已提交
438
				} else if ( material instanceof THREE.MeshNormalMaterial ) {
439

440
					setMaterialShaders( material, THREE.ShaderLib[ 'normal' ] );
441

442 443 444 445 446 447
				} else if ( material instanceof THREE.MeshBasicMaterial ) {
					
					setMaterialShaders( material, THREE.ShaderLib[ 'basic' ] );
					
					refreshUniforms( material, fog );
					
448 449
				}

450
				material.program = buildProgram( material.fragment_shader, material.vertex_shader, { fog: fog, map: material.map, env_map: material.env_map } );
M
Mr.doob 已提交
451

M
Mr.doob 已提交
452
				identifiers = [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition' ];
453
				for( u in material.uniforms ) {
M
Mr.doob 已提交
454

455
					identifiers.push(u);
M
Mr.doob 已提交
456

457
				}
458

M
Mr.doob 已提交
459
				cacheUniformLocations( material.program, identifiers );
460
				cacheAttributeLocations( material.program, [ "position", "normal", "uv", "tangent" ] );
M
Mr.doob 已提交
461

M
Mr.doob 已提交
462
			}
M
Mr.doob 已提交
463

M
Mr.doob 已提交
464
			program = material.program;
M
Mr.doob 已提交
465

M
Mr.doob 已提交
466
		} else {
M
Mr.doob 已提交
467

468
			program = _uberProgram;
M
Mr.doob 已提交
469

M
Mr.doob 已提交
470
		}
M
Mr.doob 已提交
471

M
Mr.doob 已提交
472
		if( program != _oldProgram ) {
M
Mr.doob 已提交
473

M
Mr.doob 已提交
474 475
			_gl.useProgram( program );
			_oldProgram = program;
M
Mr.doob 已提交
476

M
Mr.doob 已提交
477
		}
M
Mr.doob 已提交
478

479 480 481
		if ( program == _uberProgram ) {

			this.setupLights( program, lights );
M
Mr.doob 已提交
482

483
		}
M
Mr.doob 已提交
484

485 486
		this.loadCamera( program, camera );
		this.loadMatrices( program );
M
Mr.doob 已提交
487

488 489 490 491 492 493
		if ( material instanceof THREE.MeshBasicMaterial ) {
			
			refreshUniforms( material, fog );
		
		}
		
494
		if ( material instanceof THREE.MeshShaderMaterial ||
M
Mr.doob 已提交
495
		     material instanceof THREE.MeshDepthMaterial ||
496 497
			 material instanceof THREE.MeshNormalMaterial ||
			 material instanceof THREE.MeshBasicMaterial ) {
M
Mr.doob 已提交
498

M
Mr.doob 已提交
499 500
			mWireframe = material.wireframe;
			mLineWidth = material.wireframe_linewidth;
501

502
			mBlending = material.blending;
503

M
Mr.doob 已提交
504
			setUniforms( program, material.uniforms );
M
Mr.doob 已提交
505 506 507

		}

508
		if ( material instanceof THREE.MeshPhongMaterial ||
509
			 material instanceof THREE.MeshLambertMaterial ) {
M
Mr.doob 已提交
510

A
alteredq 已提交
511 512
			mColor = material.color;
			mOpacity = material.opacity;
M
Mr.doob 已提交
513

A
alteredq 已提交
514 515
			mWireframe = material.wireframe;
			mLineWidth = material.wireframe_linewidth;
M
Mr.doob 已提交
516

A
alteredq 已提交
517
			mBlending = material.blending;
M
Mr.doob 已提交
518

A
alteredq 已提交
519
			mMap = material.map;
520
			envMap = material.env_map;
521

522
			mixEnvMap = material.combine == THREE.MixOperation;
523
			mReflectivity = material.reflectivity;
M
Mr.doob 已提交
524

525
			useRefract = material.env_map && material.env_map.mapping instanceof THREE.CubeRefractionMapping;
526
			mRefractionRatio = material.refraction_ratio;
M
Mr.doob 已提交
527

M
Mr.doob 已提交
528
			_gl.uniform4f( program.uniforms.mColor,  mColor.r * mOpacity, mColor.g * mOpacity, mColor.b * mOpacity, mOpacity );
M
Mr.doob 已提交
529

M
Mr.doob 已提交
530 531
			_gl.uniform1i( program.uniforms.mixEnvMap, mixEnvMap );
			_gl.uniform1f( program.uniforms.mReflectivity, mReflectivity );
M
Mr.doob 已提交
532

M
Mr.doob 已提交
533 534
			_gl.uniform1i( program.uniforms.useRefract, useRefract );
			_gl.uniform1f( program.uniforms.mRefractionRatio, mRefractionRatio );
535

A
alteredq 已提交
536
			if ( fog ) {
537

A
alteredq 已提交
538
				_gl.uniform3f( program.uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );
A
alteredq 已提交
539 540 541 542 543 544 545 546 547 548 549
				
				if ( fog instanceof THREE.Fog ) {
				
					_gl.uniform1f( program.uniforms.fogNear, fog.near );
					_gl.uniform1f( program.uniforms.fogFar, fog.far );
					
				} else if ( fog instanceof THREE.FogExp2 ) {
					
					_gl.uniform1f( program.uniforms.fogDensity, fog.density );
					
				}
550

A
alteredq 已提交
551
			}
M
Mr.doob 已提交
552

A
alteredq 已提交
553
		}
M
Mr.doob 已提交
554

M
Mr.doob 已提交
555
		if ( material instanceof THREE.MeshPhongMaterial ) {
556 557 558

			mAmbient  = material.ambient;
			mSpecular = material.specular;
A
alteredq 已提交
559
			mShininess = material.shininess;
M
Mr.doob 已提交
560

M
Mr.doob 已提交
561 562 563
			_gl.uniform4f( program.uniforms.mAmbient,  mAmbient.r,  mAmbient.g,  mAmbient.b,  mOpacity );
			_gl.uniform4f( program.uniforms.mSpecular, mSpecular.r, mSpecular.g, mSpecular.b, mOpacity );
			_gl.uniform1f( program.uniforms.mShininess, mShininess );
M
Mr.doob 已提交
564

M
Mr.doob 已提交
565
			_gl.uniform1i( program.uniforms.material, PHONG );
566

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

M
Mr.doob 已提交
569
			_gl.uniform1i( program.uniforms.material, LAMBERT );
570

M
Mr.doob 已提交
571
		}
M
Mr.doob 已提交
572

A
alteredq 已提交
573
		if ( mMap ) {
574

575
			setTexture( mMap, 0 );
M
Mr.doob 已提交
576

M
Mr.doob 已提交
577 578
			_gl.uniform1i( program.uniforms.tMap,  0 );
			_gl.uniform1i( program.uniforms.enableMap, 1 );
579

A
alteredq 已提交
580
		} else {
M
Mr.doob 已提交
581

M
Mr.doob 已提交
582
			_gl.uniform1i( program.uniforms.enableMap, 0 );
M
Mr.doob 已提交
583

584
		}
M
Mr.doob 已提交
585

586
		if ( envMap ) {
M
Mr.doob 已提交
587

588
			setCubeTexture( envMap, 1 );
M
Mr.doob 已提交
589

590
			_gl.uniform1i( program.uniforms.tCube, 1 );
M
Mr.doob 已提交
591
			_gl.uniform1i( program.uniforms.enableCubeMap, 1 );
M
Mr.doob 已提交
592

593
		} else {
M
Mr.doob 已提交
594

M
Mr.doob 已提交
595
			_gl.uniform1i( program.uniforms.enableCubeMap, 0 );
M
Mr.doob 已提交
596

597
		}
598

599
		attributes = program.attributes;
M
Mr.doob 已提交
600

601
		// vertices
M
Mr.doob 已提交
602

M
Mr.doob 已提交
603
		_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLVertexBuffer );
604
		_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
605
		_gl.enableVertexAttribArray( attributes.position );
606 607

		// normals
M
Mr.doob 已提交
608

609
		if ( attributes.normal >= 0 ) {
610

611 612
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLNormalBuffer );
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
613
			_gl.enableVertexAttribArray( attributes.normal );
614

615
		}
616

617 618 619
		// tangents

		if ( attributes.tangent >= 0 ) {
620

621 622
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLTangentBuffer );
			_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
623
			_gl.enableVertexAttribArray( attributes.tangent );
624

625
		}
626

627
		// uvs
M
Mr.doob 已提交
628

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

631
			if ( geometryChunk.__webGLUVBuffer ) {
632

633
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLUVBuffer );
634
				_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
635

636
				_gl.enableVertexAttribArray( attributes.uv );
637

638
			} else {
639

640
				_gl.disableVertexAttribArray( attributes.uv );
M
Mr.doob 已提交
641

642
			}
643 644 645 646

		}

		// render triangles
M
Mr.doob 已提交
647

A
alteredq 已提交
648
		if ( ! mWireframe ) {
649

M
Mr.doob 已提交
650 651
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryChunk.__webGLFaceBuffer );
			_gl.drawElements( _gl.TRIANGLES, geometryChunk.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
652 653

		// render lines
M
Mr.doob 已提交
654

A
alteredq 已提交
655
		} else {
656

A
alteredq 已提交
657
			_gl.lineWidth( mLineWidth );
M
Mr.doob 已提交
658 659
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryChunk.__webGLLineBuffer );
			_gl.drawElements( _gl.LINES, geometryChunk.__webGLLineCount, _gl.UNSIGNED_SHORT, 0 );
660 661 662 663 664

		}

	};

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

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

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

M
Mr.doob 已提交
671
			meshMaterial = object.materials[ m ];
672

M
Mr.doob 已提交
673
			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
674

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

					material = geometryChunk.materials[ i ];
678

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

M
Mr.doob 已提交
681
						this.setBlending( material.blending );
A
alteredq 已提交
682
						this.renderBuffer( camera, lights, fog, material, geometryChunk );
M
Mr.doob 已提交
683

684 685
					}

M
Mr.doob 已提交
686
				}
687

M
Mr.doob 已提交
688
			} else {
689

M
Mr.doob 已提交
690
				material = meshMaterial;
691
				if ( material && material.blending == blending && ( material.opacity < 1.0 == transparent ) ) {
M
Mr.doob 已提交
692

M
Mr.doob 已提交
693
					this.setBlending( material.blending );
A
alteredq 已提交
694
					this.renderBuffer( camera, lights, fog, material, geometryChunk );
M
Mr.doob 已提交
695

696 697 698
				}

			}
699 700

		}
M
Mr.doob 已提交
701

702
	};
M
Mr.doob 已提交
703

M
Mr.doob 已提交
704
	this.render = function( scene, camera ) {
M
Mr.doob 已提交
705

M
Mr.doob 已提交
706
		var o, ol, webGLObject, object, buffer,
A
alteredq 已提交
707 708
			lights = scene.lights,
			fog = scene.fog;
M
Mr.doob 已提交
709

M
Mr.doob 已提交
710
		this.initWebGLObjects( scene );
M
Mr.doob 已提交
711

712 713 714 715 716 717
		if ( this.autoClear ) {

			this.clear();

		}

718
		camera.autoUpdateMatrix && camera.updateMatrix();
M
Mr.doob 已提交
719

720 721
		_viewMatrixArray.set( camera.matrix.flatten() );
		_projectionMatrixArray.set( camera.projectionMatrix.flatten() );
M
Mr.doob 已提交
722

M
Mr.doob 已提交
723
		// opaque pass
M
Mr.doob 已提交
724

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

M
Mr.doob 已提交
727
			webGLObject = scene.__webGLObjects[ o ];
M
Mr.doob 已提交
728

M
Mr.doob 已提交
729 730
			object = webGLObject.object;
			buffer = webGLObject.buffer;
M
Mr.doob 已提交
731

M
Mr.doob 已提交
732
			if ( object.visible ) {
M
Mr.doob 已提交
733

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

737
			}
M
Mr.doob 已提交
738

M
Mr.doob 已提交
739
		}
M
Mr.doob 已提交
740

M
Mr.doob 已提交
741
		// transparent pass
M
Mr.doob 已提交
742

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

M
Mr.doob 已提交
745
			webGLObject = scene.__webGLObjects[ o ];
M
Mr.doob 已提交
746

M
Mr.doob 已提交
747 748
			object = webGLObject.object;
			buffer = webGLObject.buffer;
M
Mr.doob 已提交
749

M
Mr.doob 已提交
750
			if ( object.visible ) {
M
Mr.doob 已提交
751

M
Mr.doob 已提交
752
				this.setupMatrices( object, camera );
753

754
				// opaque blended materials
M
Mr.doob 已提交
755

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

759
				// transparent blended materials
M
Mr.doob 已提交
760

A
alteredq 已提交
761 762
				this.renderPass( camera, lights, fog, object, buffer, THREE.AdditiveBlending, true );
				this.renderPass( camera, lights, fog, object, buffer, THREE.SubtractiveBlending, true );
763

764
				// transparent normal materials
M
Mr.doob 已提交
765

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

768
			}
M
Mr.doob 已提交
769

M
Mr.doob 已提交
770
		}
M
Mr.doob 已提交
771

M
Mr.doob 已提交
772
	};
M
Mr.doob 已提交
773

M
Mr.doob 已提交
774
	this.initWebGLObjects = function( scene ) {
M
Mr.doob 已提交
775

M
Mr.doob 已提交
776
		var o, ol, object, globject, g, geometryChunk, objmap;
M
Mr.doob 已提交
777

M
Mr.doob 已提交
778
		if ( !scene.__webGLObjects ) {
M
Mr.doob 已提交
779

M
Mr.doob 已提交
780
			scene.__webGLObjects = [];
M
Mr.doob 已提交
781
			scene.__webGLObjectsMap = {};
M
Mr.doob 已提交
782

M
Mr.doob 已提交
783
		}
M
Mr.doob 已提交
784

785 786 787 788
		for ( o = 0, ol = scene.objects.length; o < ol; o++ ) {

			object = scene.objects[ o ];

M
Mr.doob 已提交
789
			if ( scene.__webGLObjectsMap[ object.id ] == undefined ) {
M
Mr.doob 已提交
790

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

M
Mr.doob 已提交
793
			}
M
Mr.doob 已提交
794

M
Mr.doob 已提交
795
			objmap = scene.__webGLObjectsMap[ object.id ];
M
Mr.doob 已提交
796

797 798
			if ( object instanceof THREE.Mesh ) {

M
Mr.doob 已提交
799
				// create separate VBOs per geometry chunk
M
Mr.doob 已提交
800

M
Mr.doob 已提交
801
				for ( g in object.geometry.geometryChunks ) {
M
Mr.doob 已提交
802

M
Mr.doob 已提交
803
					geometryChunk = object.geometry.geometryChunks[ g ];
M
Mr.doob 已提交
804

M
Mr.doob 已提交
805
					// initialise VBO on the first access
M
Mr.doob 已提交
806

M
Mr.doob 已提交
807
					if( ! geometryChunk.__webGLVertexBuffer ) {
M
Mr.doob 已提交
808

M
Mr.doob 已提交
809
						this.createBuffers( object, g );
M
Mr.doob 已提交
810 811

					}
M
Mr.doob 已提交
812

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

M
Mr.doob 已提交
815
					if ( objmap[ g ] == undefined ) {
M
Mr.doob 已提交
816

M
Mr.doob 已提交
817 818
						globject = { buffer: geometryChunk, object: object };
						scene.__webGLObjects.push( globject );
M
Mr.doob 已提交
819

M
Mr.doob 已提交
820
						objmap[ g ] = 1;
M
Mr.doob 已提交
821

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

M
Mr.doob 已提交
824
				}
825

M
Mr.doob 已提交
826 827
			}/* else if ( object instanceof THREE.Line ) {

M
Mr.doob 已提交
828
			} else if ( object instanceof THREE.Particle ) {
M
Mr.doob 已提交
829 830 831

			}*/

M
Mr.doob 已提交
832
		}
833 834 835 836 837 838

	};

	this.removeObject = function ( scene, object ) {

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

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

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

844
			if ( object == zobject ) {
845 846 847 848

				scene.__webGLObjects.splice( o, 1 );

			}
M
Mr.doob 已提交
849

850
		}
M
Mr.doob 已提交
851

M
Mr.doob 已提交
852
	};
M
Mr.doob 已提交
853

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

M
Mr.doob 已提交
856
		object.autoUpdateMatrix && object.updateMatrix();
857

M
Mr.doob 已提交
858
		_modelViewMatrix.multiply( camera.matrix, object.matrix );
M
Mr.doob 已提交
859
		_modelViewMatrixArray.set( _modelViewMatrix.flatten() );
860

M
Mr.doob 已提交
861
		_normalMatrix = THREE.Matrix4.makeInvert3x3( _modelViewMatrix ).transpose();
M
Mr.doob 已提交
862
		_normalMatrixArray.set( _normalMatrix.m );
863

M
Mr.doob 已提交
864
		_objectMatrixArray.set( object.matrix.flatten() );
M
Mr.doob 已提交
865

M
Mr.doob 已提交
866
	};
M
Mr.doob 已提交
867

M
Mr.doob 已提交
868
	this.loadMatrices = function ( program ) {
M
Mr.doob 已提交
869

M
Mr.doob 已提交
870 871 872 873
		_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 已提交
874
		_gl.uniformMatrix4fv( program.uniforms.objectMatrix, false, _objectMatrixArray );
M
Mr.doob 已提交
875

M
Mr.doob 已提交
876
	};
877

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

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

M
Mr.doob 已提交
882
	};
M
Mr.doob 已提交
883

M
Mr.doob 已提交
884
	this.setBlending = function( blending ) {
M
Mr.doob 已提交
885

M
Mr.doob 已提交
886
		switch ( blending ) {
887

M
Mr.doob 已提交
888
			case THREE.AdditiveBlending:
889

M
Mr.doob 已提交
890 891
				_gl.blendEquation( _gl.FUNC_ADD );
				_gl.blendFunc( _gl.ONE, _gl.ONE );
M
Mr.doob 已提交
892

M
Mr.doob 已提交
893
				break;
894

M
Mr.doob 已提交
895
			case THREE.SubtractiveBlending:
896

M
Mr.doob 已提交
897 898
				//_gl.blendEquation( _gl.FUNC_SUBTRACT );
				_gl.blendFunc( _gl.DST_COLOR, _gl.ZERO );
M
Mr.doob 已提交
899

M
Mr.doob 已提交
900
				break;
M
Mr.doob 已提交
901

M
Mr.doob 已提交
902
			default:
M
Mr.doob 已提交
903

M
Mr.doob 已提交
904 905
				_gl.blendEquation( _gl.FUNC_ADD );
				_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
M
Mr.doob 已提交
906

M
Mr.doob 已提交
907
				break;
N
Nicolas Garcia Belmonte 已提交
908
		}
M
Mr.doob 已提交
909

N
Nicolas Garcia Belmonte 已提交
910
	};
M
Mr.doob 已提交
911

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

914
		if ( cullFace ) {
M
Mr.doob 已提交
915

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

918
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
919

920
			} else {
M
Mr.doob 已提交
921

922
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
923

924
			}
M
Mr.doob 已提交
925

926
			if( cullFace == "back" ) {
M
Mr.doob 已提交
927

928
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
929

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

932
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
933

934
			} else {
M
Mr.doob 已提交
935

936
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
937

938
			}
M
Mr.doob 已提交
939

940
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
941

942
		} else {
M
Mr.doob 已提交
943

944
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
945

946 947 948
		}

	};
N
Nicolas Garcia Belmonte 已提交
949

950
	this.supportsVertexTextures = function() {
951

952
		return maxVertexTextures() > 0;
953

954
	};
955

956
	function maxVertexTextures() {
957

958 959 960
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
961 962


963
	function initGL( antialias, clearColor, clearAlpha ) {
N
Nicolas Garcia Belmonte 已提交
964 965 966

		try {

967
			_gl = _canvas.getContext( 'experimental-webgl', { antialias: antialias } );
N
Nicolas Garcia Belmonte 已提交
968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983

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

984 985
		_gl.frontFace( _gl.CCW );
		_gl.cullFace( _gl.BACK );
986
		_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
987

N
Nicolas Garcia Belmonte 已提交
988
		_gl.enable( _gl.BLEND );
989
		_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
990
		_gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
N
Nicolas Garcia Belmonte 已提交
991

992
	};
993
		
994
	function generateFragmentShader( maxDirLights, maxPointLights ) {
M
Mr.doob 已提交
995

996
		var chunks = [
997

998 999
			maxDirLights   ? "#define MAX_DIR_LIGHTS " + maxDirLights     : "",
			maxPointLights ? "#define MAX_POINT_LIGHTS " + maxPointLights : "",
M
Mr.doob 已提交
1000

1001
			"uniform int material;", // 1 - Lambert, 2 - Phong
1002

A
alteredq 已提交
1003
			"uniform bool enableMap;",
1004
			"uniform bool enableCubeMap;",
1005
			"uniform bool mixEnvMap;",
M
Mr.doob 已提交
1006

1007 1008 1009
			"uniform samplerCube tCube;",
			"uniform float mReflectivity;",

A
alteredq 已提交
1010
			"uniform sampler2D tMap;",
1011
			"uniform vec4 mColor;",
1012
			"uniform float mOpacity;",
1013

1014
			"uniform vec4 mAmbient;",
1015
			"uniform vec4 mSpecular;",
1016
			"uniform float mShininess;",
1017

1018 1019
			THREE.Snippets[ "fog_uniforms" ],
			
1020 1021
			"uniform int pointLightNumber;",
			"uniform int directionalLightNumber;",
M
Mr.doob 已提交
1022

1023
			maxDirLights ? "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];" : "",
M
Mr.doob 已提交
1024

1025
			"varying vec3 vNormal;",
1026
			"varying vec2 vUv;",
M
Mr.doob 已提交
1027

1028 1029
			"varying vec3 vLightWeighting;",

1030
			maxPointLights ? "varying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];"     : "",
M
Mr.doob 已提交
1031

1032
			"varying vec3 vViewPosition;",
M
Mr.doob 已提交
1033

1034
			"varying vec3 vReflect;",
M
Mr.doob 已提交
1035

1036
			"void main() {",
1037

A
alteredq 已提交
1038
				"vec4 mapColor = vec4( 1.0, 1.0, 1.0, 1.0 );",
1039
				"vec4 cubeColor = vec4( 1.0, 1.0, 1.0, 1.0 );",
1040

1041
				// diffuse map
M
Mr.doob 已提交
1042

A
alteredq 已提交
1043
				"if ( enableMap ) {",
M
Mr.doob 已提交
1044

A
alteredq 已提交
1045
					"mapColor = texture2D( tMap, vUv );",
M
Mr.doob 已提交
1046

A
alteredq 已提交
1047
				"}",
1048

1049
				// cube map
M
Mr.doob 已提交
1050

1051
				"if ( enableCubeMap ) {",
M
Mr.doob 已提交
1052

1053 1054 1055 1056
					"cubeColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );",
					// "cubeColor.r = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) ).r;",
					// "cubeColor.g = textureCube( tCube, vec3( -vReflect.x + 0.005, vReflect.yz ) ).g;",
					// "cubeColor.b = textureCube( tCube, vec3( -vReflect.x + 0.01, vReflect.yz ) ).b;",
M
Mr.doob 已提交
1057

1058 1059
				"}",

1060 1061
				// Blinn-Phong
				// based on o3d example
M
Mr.doob 已提交
1062

M
Mr.doob 已提交
1063
				"if ( material == 2 ) { ",
1064 1065 1066 1067

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

1068
					// point lights
M
Mr.doob 已提交
1069

1070 1071 1072
					maxPointLights ? "vec4 pointDiffuse  = vec4( 0.0, 0.0, 0.0, 0.0 );" : "",
					maxPointLights ? "vec4 pointSpecular = vec4( 0.0, 0.0, 0.0, 0.0 );" : "",

1073
					maxPointLights ? "for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {" : "",
M
Mr.doob 已提交
1074

1075 1076
					maxPointLights ? 	"vec3 pointVector = normalize( vPointLightVector[ i ] );" : "",
					maxPointLights ? 	"vec3 pointHalfVector = normalize( vPointLightVector[ i ] + vViewPosition );" : "",
M
Mr.doob 已提交
1077

1078 1079 1080 1081 1082 1083
					maxPointLights ? 	"float pointDotNormalHalf = dot( normal, pointHalfVector );" : "",
					maxPointLights ? 	"float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );" : "",

					// Ternary conditional is from the original o3d shader. Here it produces abrupt dark cutoff artefacts.
					// Using just pow works ok in Chrome, but makes different artefact in Firefox 4.
					// Zeroing on negative pointDotNormalHalf seems to work in both.
M
Mr.doob 已提交
1084

1085 1086
					//"float specularCompPoint = dot( normal, pointVector ) < 0.0 || pointDotNormalHalf < 0.0 ? 0.0 : pow( pointDotNormalHalf, mShininess );",
					//"float specularCompPoint = pow( pointDotNormalHalf, mShininess );",
1087
					//"float pointSpecularWeight = pointDotNormalHalf < 0.0 ? 0.0 : pow( pointDotNormalHalf, mShininess );",
1088

1089 1090
					// Ternary conditional inside for loop breaks Chrome shader linking.
					// Must do it with if.
1091

1092 1093 1094
					maxPointLights ? 	"float pointSpecularWeight = 0.0;" : "",
					maxPointLights ? 	"if ( pointDotNormalHalf >= 0.0 )" : "",
					maxPointLights ? 		"pointSpecularWeight = pow( pointDotNormalHalf, mShininess );" : "",
M
Mr.doob 已提交
1095

A
alteredq 已提交
1096
					maxPointLights ? 	"pointDiffuse  += mColor * pointDiffuseWeight;" : "",
1097
					maxPointLights ? 	"pointSpecular += mSpecular * pointSpecularWeight;" : "",
M
Mr.doob 已提交
1098

1099
					maxPointLights ? "}" : "",
1100

1101 1102 1103 1104
					// directional lights

					maxDirLights ? "vec4 dirDiffuse  = vec4( 0.0, 0.0, 0.0, 0.0 );" : "",
					maxDirLights ? "vec4 dirSpecular = vec4( 0.0, 0.0, 0.0, 0.0 );" : "",
M
Mr.doob 已提交
1105

1106
					maxDirLights ? "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {" : "",
1107

1108
					maxDirLights ?		"vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );" : "",
1109

1110 1111
					maxDirLights ? 		"vec3 dirVector = normalize( lDirection.xyz );" : "",
					maxDirLights ? 		"vec3 dirHalfVector = normalize( lDirection.xyz + vViewPosition );" : "",
M
Mr.doob 已提交
1112

1113
					maxDirLights ? 		"float dirDotNormalHalf = dot( normal, dirHalfVector );" : "",
1114

M
Mr.doob 已提交
1115 1116
					maxDirLights ? 		"float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );" : "",

1117 1118 1119
					maxDirLights ? 		"float dirSpecularWeight = 0.0;" : "",
					maxDirLights ? 		"if ( dirDotNormalHalf >= 0.0 )" : "",
					maxDirLights ? 			"dirSpecularWeight = pow( dirDotNormalHalf, mShininess );" : "",
1120

A
alteredq 已提交
1121
					maxDirLights ? 		"dirDiffuse  += mColor * dirDiffuseWeight;" : "",
1122 1123 1124 1125 1126
					maxDirLights ? 		"dirSpecular += mSpecular * dirSpecularWeight;" : "",

					maxDirLights ? "}" : "",

					// all lights contribution summation
M
Mr.doob 已提交
1127

1128 1129 1130 1131 1132
					"vec4 totalLight = mAmbient;",
					maxDirLights   ? "totalLight += dirDiffuse + dirSpecular;" : "",
					maxPointLights ? "totalLight += pointDiffuse + pointSpecular;" : "",

					// looks nicer with weighting
M
Mr.doob 已提交
1133

1134
					"if ( mixEnvMap ) {",
M
Mr.doob 已提交
1135

1136
						"gl_FragColor = vec4( mix( mapColor.rgb * totalLight.xyz * vLightWeighting, cubeColor.rgb, mReflectivity ), mapColor.a );",
M
Mr.doob 已提交
1137

1138
					"} else {",
M
Mr.doob 已提交
1139

1140
						"gl_FragColor = vec4( mapColor.rgb * cubeColor.rgb * totalLight.xyz * vLightWeighting, mapColor.a );",
M
Mr.doob 已提交
1141

1142
					"}",
M
Mr.doob 已提交
1143

A
alteredq 已提交
1144
				// Lambert: diffuse lighting
M
Mr.doob 已提交
1145 1146

				"} else if ( material == 1 ) {",
1147

M
Mr.doob 已提交
1148
					"if ( mixEnvMap ) {",
M
Mr.doob 已提交
1149

1150
						"gl_FragColor = vec4( mix( mColor.rgb * mapColor.rgb * vLightWeighting, cubeColor.rgb, mReflectivity ), mColor.a * mapColor.a );",
M
Mr.doob 已提交
1151

1152
					"} else {",
M
Mr.doob 已提交
1153

1154
						"gl_FragColor = vec4( mColor.rgb * mapColor.rgb * cubeColor.rgb * vLightWeighting, mColor.a * mapColor.a );",
M
Mr.doob 已提交
1155

1156
					"}",
M
Mr.doob 已提交
1157

1158
				"}",
1159

1160
				THREE.Snippets[ "fog_fragment" ],
A
alteredq 已提交
1161
				
1162
			"}" ];
M
Mr.doob 已提交
1163

1164
		return chunks.join("\n");
M
Mr.doob 已提交
1165

1166
	};
M
Mr.doob 已提交
1167

1168
	function generateVertexShader( maxDirLights, maxPointLights ) {
M
Mr.doob 已提交
1169

1170
		var chunks = [
M
Mr.doob 已提交
1171

1172 1173
			maxDirLights   ? "#define MAX_DIR_LIGHTS " + maxDirLights     : "",
			maxPointLights ? "#define MAX_POINT_LIGHTS " + maxPointLights : "",
M
Mr.doob 已提交
1174

1175
			"uniform bool enableLighting;",
1176
			"uniform bool useRefract;",
M
Mr.doob 已提交
1177

1178 1179
			"uniform int pointLightNumber;",
			"uniform int directionalLightNumber;",
M
Mr.doob 已提交
1180

1181
			"uniform vec3 ambientLightColor;",
M
Mr.doob 已提交
1182

1183 1184
			maxDirLights ? "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];"     : "",
			maxDirLights ? "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];" : "",
1185

1186 1187
			maxPointLights ? "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];"    : "",
			maxPointLights ? "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];" : "",
1188

1189
			"varying vec3 vNormal;",
1190
			"varying vec2 vUv;",
M
Mr.doob 已提交
1191

1192
			"varying vec3 vLightWeighting;",
1193

1194
			maxPointLights ? "varying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];"     : "",
M
Mr.doob 已提交
1195

1196
			"varying vec3 vViewPosition;",
M
Mr.doob 已提交
1197

1198
			"varying vec3 vReflect;",
1199
			"uniform float mRefractionRatio;",
1200

1201
			"void main(void) {",
1202

1203
				// world space
M
Mr.doob 已提交
1204

M
Mr.doob 已提交
1205
				"vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
1206
				"vViewPosition = cameraPosition - mPosition.xyz;",
M
Mr.doob 已提交
1207

A
alteredq 已提交
1208
				// this doesn't work on Mac
M
Mr.doob 已提交
1209 1210
				//"vec3 nWorld = mat3(objectMatrix) * normal;",
				"vec3 nWorld = mat3( objectMatrix[0].xyz, objectMatrix[1].xyz, objectMatrix[2].xyz ) * normal;",
M
Mr.doob 已提交
1211

1212
				// eye space
M
Mr.doob 已提交
1213

1214
				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
1215
				"vec3 transformedNormal = normalize( normalMatrix * normal );",
1216

1217
				"if ( !enableLighting ) {",
1218

1219
					"vLightWeighting = vec3( 1.0, 1.0, 1.0 );",
1220 1221 1222

				"} else {",

1223
					"vLightWeighting = ambientLightColor;",
M
Mr.doob 已提交
1224

1225
					// directional lights
M
Mr.doob 已提交
1226

1227
					maxDirLights ? "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {" : "",
1228
					maxDirLights ?		"vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );" : "",
1229
					maxDirLights ?		"float directionalLightWeighting = max( dot( transformedNormal, normalize( lDirection.xyz ) ), 0.0 );" : "",
1230 1231
					maxDirLights ?		"vLightWeighting += directionalLightColor[ i ] * directionalLightWeighting;" : "",
					maxDirLights ? "}" : "",
M
Mr.doob 已提交
1232

1233
					// point lights
M
Mr.doob 已提交
1234

1235
					maxPointLights ? "for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {" : "",
1236 1237 1238 1239 1240
					maxPointLights ? 	"vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );" : "",
					maxPointLights ? 	"vPointLightVector[ i ] = normalize( lPosition.xyz - mvPosition.xyz );" : "",
					maxPointLights ? 	"float pointLightWeighting = max( dot( transformedNormal, vPointLightVector[ i ] ), 0.0 );" : "",
					maxPointLights ? 	"vLightWeighting += pointLightColor[ i ] * pointLightWeighting;" : "",
					maxPointLights ? "}" : "",
M
Mr.doob 已提交
1241

1242
				"}",
1243

1244
				"vNormal = transformedNormal;",
1245
				"vUv = uv;",
1246

1247
				"if ( useRefract ) {",
M
Mr.doob 已提交
1248

1249
					"vReflect = refract( normalize(mPosition.xyz - cameraPosition), normalize(nWorld.xyz), mRefractionRatio );",
M
Mr.doob 已提交
1250

1251
				"} else {",
M
Mr.doob 已提交
1252

1253
					"vReflect = reflect( normalize(mPosition.xyz - cameraPosition), normalize(nWorld.xyz) );",
M
Mr.doob 已提交
1254

1255
				"}",
M
Mr.doob 已提交
1256

1257
				"gl_Position = projectionMatrix * mvPosition;",
1258

1259
			"}" ];
M
Mr.doob 已提交
1260

1261
		return chunks.join("\n");
M
Mr.doob 已提交
1262

1263
	};
M
Mr.doob 已提交
1264

1265
	function buildProgram( fragment_shader, vertex_shader, parameters ) {
M
Mr.doob 已提交
1266

M
Mr.doob 已提交
1267
		var program = _gl.createProgram(),
M
Mr.doob 已提交
1268

M
Mr.doob 已提交
1269 1270 1271 1272
		prefix_fragment = [
			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",
A
alteredq 已提交
1273

1274 1275 1276 1277 1278
			parameters.fog ? "#define USE_FOG" : "",
			parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "",
		
			parameters.map ? "#define USE_MAP" : "",
			parameters.env_map ? "#define USE_ENVMAP" : "",
1279

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

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

1288 1289 1290
			parameters.map ? "#define USE_MAP" : "",
			parameters.env_map ? "#define USE_ENVMAP" : "",

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

M
Mr.doob 已提交
1303 1304
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragment_shader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertex_shader ) );
M
Mr.doob 已提交
1305

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

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

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

N
Nicolas Garcia Belmonte 已提交
1313
		}
M
Mr.doob 已提交
1314

M
Mr.doob 已提交
1315
		program.uniforms = {};
1316
		program.attributes = {};
M
Mr.doob 已提交
1317

M
Mr.doob 已提交
1318
		return program;
M
Mr.doob 已提交
1319

M
Mr.doob 已提交
1320
	};
M
Mr.doob 已提交
1321

M
Mr.doob 已提交
1322
	function setUniforms( program, uniforms ) {
M
Mr.doob 已提交
1323

M
Mr.doob 已提交
1324
		var u, value, type, location, texture;
M
Mr.doob 已提交
1325

M
Mr.doob 已提交
1326
		for( u in uniforms ) {
M
Mr.doob 已提交
1327

M
Mr.doob 已提交
1328 1329 1330
			type = uniforms[u].type;
			value = uniforms[u].value;
			location = program.uniforms[u];
M
Mr.doob 已提交
1331

M
Mr.doob 已提交
1332
			if( type == "i" ) {
M
Mr.doob 已提交
1333

M
Mr.doob 已提交
1334
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
1335

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

M
Mr.doob 已提交
1338
				_gl.uniform1f( location, value );
1339

1340 1341 1342
			} else if( type == "v3" ) {

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

1344 1345 1346
			} else if( type == "c" ) {

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

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

M
Mr.doob 已提交
1350
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
1351

M
Mr.doob 已提交
1352
				texture = uniforms[u].texture;
M
Mr.doob 已提交
1353

1354
				if ( !texture ) continue;
M
Mr.doob 已提交
1355

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

1358
					setCubeTexture( texture, value );
M
Mr.doob 已提交
1359

1360
				} else {
M
Mr.doob 已提交
1361

1362
					setTexture( texture, value );
M
Mr.doob 已提交
1363

1364
				}
M
Mr.doob 已提交
1365

1366
			}
M
Mr.doob 已提交
1367

1368
		}
M
Mr.doob 已提交
1369

1370
	};
M
Mr.doob 已提交
1371

1372
	function setCubeTexture( texture, slot ) {
M
Mr.doob 已提交
1373

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

1376 1377
			if ( !texture.image.__webGLTextureCube &&
				 !texture.image.__cubeMapInitialized && texture.image.loadCount == 6 ) {
M
Mr.doob 已提交
1378

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

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

1383 1384
				_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 已提交
1385

1386 1387
				_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 已提交
1388

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

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

1393
				}
M
Mr.doob 已提交
1394

1395
				_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
1396

1397
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
M
Mr.doob 已提交
1398

1399
				texture.image.__cubeMapInitialized = true;
M
Mr.doob 已提交
1400

M
Mr.doob 已提交
1401
			}
1402 1403 1404

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

1406
		}
M
Mr.doob 已提交
1407

M
Mr.doob 已提交
1408
	};
M
Mr.doob 已提交
1409

1410
	function setTexture( texture, slot ) {
M
Mr.doob 已提交
1411

1412 1413 1414 1415 1416
		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 已提交
1417

1418 1419
			_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 已提交
1420 1421 1422

			_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 ) );
1423 1424 1425 1426 1427 1428 1429
			_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 已提交
1430

1431
	};
M
Mr.doob 已提交
1432

M
Mr.doob 已提交
1433
	function cacheUniformLocations( program, identifiers ) {
M
Mr.doob 已提交
1434

M
Mr.doob 已提交
1435
		var i, l, id;
M
Mr.doob 已提交
1436

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

1439 1440
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
1441

M
Mr.doob 已提交
1442
		}
M
Mr.doob 已提交
1443

M
Mr.doob 已提交
1444
	};
M
Mr.doob 已提交
1445

1446
	function cacheAttributeLocations( program, identifiers ) {
1447

1448
		var i, l, id;
M
Mr.doob 已提交
1449

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

1452 1453
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
1454

1455
		}
M
Mr.doob 已提交
1456

M
Mr.doob 已提交
1457
	};
M
Mr.doob 已提交
1458

A
alteredq 已提交
1459
	function initUbershader( maxDirLights, maxPointLights, fog ) {
1460
		
M
Mr.doob 已提交
1461
		var vertex_shader = generateVertexShader( maxDirLights, maxPointLights ),
1462 1463
			fragment_shader = generateFragmentShader( maxDirLights, maxPointLights ),
			program;
1464

1465 1466
		//console.log ( vertex_shader );
		//console.log ( fragment_shader );
M
Mr.doob 已提交
1467

1468
		program = buildProgram( fragment_shader, vertex_shader, { fog: fog } );
M
Mr.doob 已提交
1469

1470
		_gl.useProgram( program );
M
Mr.doob 已提交
1471

M
Mr.doob 已提交
1472 1473 1474
		// matrices
		// lights
		// material properties (Basic / Lambert / Blinn-Phong shader)
M
Mr.doob 已提交
1475

1476
		cacheUniformLocations( program, [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
M
Mr.doob 已提交
1477 1478 1479 1480
										   'enableLighting', 'ambientLightColor',
										   'material', 'mColor', 'mAmbient', 'mSpecular', 'mShininess', 'mOpacity',
										   'enableMap', 'tMap',
										   'enableCubeMap', 'tCube', 'mixEnvMap', 'mReflectivity',
M
Mr.doob 已提交
1481
										   'mRefractionRatio', 'useRefract'
M
Mr.doob 已提交
1482
		] );
1483

A
alteredq 已提交
1484
		if ( fog ) {
1485

A
alteredq 已提交
1486
			cacheUniformLocations( program, [ 'fogColor', 'fogNear', 'fogFar', 'fogDensity' ] );
1487

A
alteredq 已提交
1488
		}
M
Mr.doob 已提交
1489

M
Mr.doob 已提交
1490
		if ( maxDirLights ) {
M
Mr.doob 已提交
1491 1492

			cacheUniformLocations( program, [ 'directionalLightNumber', 'directionalLightColor', 'directionalLightDirection' ] );
M
Mr.doob 已提交
1493

M
Mr.doob 已提交
1494
		}
1495

M
Mr.doob 已提交
1496
		if ( maxPointLights ) {
M
Mr.doob 已提交
1497

M
Mr.doob 已提交
1498
			cacheUniformLocations( program, [ 'pointLightNumber', 'pointLightColor', 'pointLightPosition' ] );
M
Mr.doob 已提交
1499

M
Mr.doob 已提交
1500
		}
M
Mr.doob 已提交
1501

M
Mr.doob 已提交
1502
		// texture (diffuse map)
M
Mr.doob 已提交
1503

1504 1505
		_gl.uniform1i( program.uniforms.enableMap, 0 );
		_gl.uniform1i( program.uniforms.tMap, 0 );
M
Mr.doob 已提交
1506

M
Mr.doob 已提交
1507
		// cube texture
M
Mr.doob 已提交
1508

1509 1510 1511
		_gl.uniform1i( program.uniforms.enableCubeMap, 0 );
		_gl.uniform1i( program.uniforms.tCube, 1 ); // it's important to use non-zero texture unit, otherwise it doesn't work
		_gl.uniform1i( program.uniforms.mixEnvMap, 0 );
M
Mr.doob 已提交
1512

M
Mr.doob 已提交
1513
		// refraction
M
Mr.doob 已提交
1514

1515
		_gl.uniform1i( program.uniforms.useRefract, 0 );
M
Mr.doob 已提交
1516

1517
		// attribute arrays
M
Mr.doob 已提交
1518

1519
		cacheAttributeLocations( program, [ "position", "normal", "uv" ] );
M
Mr.doob 已提交
1520

1521
		return program;
N
Nicolas Garcia Belmonte 已提交
1522

1523
	};
N
Nicolas Garcia Belmonte 已提交
1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549

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

1551
	};
N
Nicolas Garcia Belmonte 已提交
1552

1553
	function paramThreeToGL( p ) {
M
Mr.doob 已提交
1554

1555
		switch ( p ) {
M
Mr.doob 已提交
1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568

			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;

1569
		}
M
Mr.doob 已提交
1570

1571
		return 0;
M
Mr.doob 已提交
1572

1573 1574 1575 1576 1577 1578
	};

	function materialNeedsSmoothNormals( material ) {

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

1579
	};
M
Mr.doob 已提交
1580

M
Mr.doob 已提交
1581
	function bufferNeedsSmoothNormals( geometryChunk, object ) {
M
Mr.doob 已提交
1582

1583
		var m, ml, i, l, needsSmoothNormals = false;
M
Mr.doob 已提交
1584

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

M
Mr.doob 已提交
1587
			meshMaterial = object.materials[ m ];
1588 1589 1590

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

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

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

1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615
						needsSmoothNormals = true;
						break;

					}

				}

			} else {

				if ( materialNeedsSmoothNormals( meshMaterial ) ) {

					needsSmoothNormals = true;
					break;

				}

			}

			if ( needsSmoothNormals ) break;

		}
M
Mr.doob 已提交
1616

1617
		return needsSmoothNormals;
M
Mr.doob 已提交
1618

1619
	};
M
Mr.doob 已提交
1620

1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654
	function allocateLights( scene, maxLights ) {

		if ( scene ) {

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

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

				light = scene.lights[ l ];

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

			}

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

				maxDirLights = dirLights;
				maxPointLights = pointLights;

			} else {

				maxDirLights = Math.ceil( maxLights * dirLights / ( pointLights + dirLights ) );
				maxPointLights = maxLights - maxDirLights;

			}

			return { 'directional' : maxDirLights, 'point' : maxPointLights };

		}

		return { 'directional' : 1, 'point' : maxLights - 1 };

	};
M
Mr.doob 已提交
1655

A
alteredq 已提交
1656
	/* DEBUG
1657
	function getGLParams() {
M
Mr.doob 已提交
1658

1659
		var params  = {
M
Mr.doob 已提交
1660

1661 1662
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
1663

1664 1665 1666
			'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 已提交
1667

1668 1669 1670
			'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 已提交
1671

1672 1673
		return params;
	};
M
Mr.doob 已提交
1674

1675
	function dumpObject( obj ) {
M
Mr.doob 已提交
1676

1677 1678
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
1679

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

1682
		}
M
Mr.doob 已提交
1683

1684 1685
		return str;
	}
A
alteredq 已提交
1686
	*/
1687

1688
};
1689

1690 1691 1692
THREE.Snippets = {
	
	fog_uniforms: [
M
Mr.doob 已提交
1693

1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707
	"#ifdef USE_FOG",
	
		"uniform vec3 fogColor;",
		
		"#ifdef FOG_EXP2",
			"uniform float fogDensity;",
		"#else",
			"uniform float fogNear;",
			"uniform float fogFar;",
		"#endif",
		
	"#endif"
	
	].join("\n"),
M
Mr.doob 已提交
1708

1709
	fog_fragment: [
1710

1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723
	"#ifdef USE_FOG",
	
		"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",
		
		"gl_FragColor = mix( gl_FragColor, vec4( fogColor, 1.0 ), fogFactor );",
M
Mr.doob 已提交
1724

1725 1726 1727 1728 1729
	"#endif"
	
	].join("\n")
	
};
1730

1731
THREE.ShaderLib = {
1732

1733
	'depth': {
M
Mr.doob 已提交
1734

1735 1736
		uniforms: { "mNear": { type: "f", value: 1.0 },
					"mFar" : { type: "f", value: 2000.0 } },
1737

1738
		fragment_shader: [
M
Mr.doob 已提交
1739

1740 1741
			"uniform float mNear;",
			"uniform float mFar;",
M
Mr.doob 已提交
1742

1743
			"void main() {",
M
Mr.doob 已提交
1744

1745 1746 1747
				"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 已提交
1748

1749
			"}"
M
Mr.doob 已提交
1750

1751
		].join("\n"),
1752

1753
		vertex_shader: [
1754

1755
			"void main() {",
1756

1757
				"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
1758

1759
			"}"
1760

1761
		].join("\n")
1762

1763
	},
1764

1765
	'normal': {
M
Mr.doob 已提交
1766

1767
		uniforms: { },
1768

1769
		fragment_shader: [
1770

1771
			"varying vec3 vNormal;",
M
Mr.doob 已提交
1772

1773
			"void main() {",
1774

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

1777
			"}"
M
Mr.doob 已提交
1778

1779
		].join("\n"),
M
Mr.doob 已提交
1780

1781
		vertex_shader: [
1782

1783
			"varying vec3 vNormal;",
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 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926
			"void main() {",

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

				"gl_Position = projectionMatrix * mvPosition;",

			"}"

		].join("\n")

	},
	
	'basic': {
		
		uniforms: { "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 ) }
				},
		
		fragment_shader: [
			
			"uniform vec3 color;",
			"uniform float opacity;",
			
			"#ifdef USE_MAP",
				
				"varying vec2 vUv;",
				"uniform sampler2D map;",
				  
			"#endif",
			
			"#ifdef USE_ENVMAP",
			
				"varying vec3 vReflect;",
				"uniform float reflectivity;",
				"uniform samplerCube env_map;",
				"uniform int combine;",
				
			"#endif",

			THREE.Snippets[ "fog_uniforms" ],
				
			"void main() {",
					
				"vec4 mColor = vec4( color, opacity );",
				"vec4 mapColor = vec4( 1.0, 1.0, 1.0, 1.0 );",
				"vec4 cubeColor = vec4( 1.0, 1.0, 1.0, 1.0 );",

				// diffuse map

				"#ifdef USE_MAP",

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

				"#endif",

				// environment map
				
				"#ifdef USE_ENVMAP",

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

						"gl_FragColor = mix( mColor * mapColor, cubeColor, reflectivity );",

					"} else {",

						"gl_FragColor = mColor * mapColor * cubeColor;",

					"}",
				
				"#else",
				
					"gl_FragColor = mColor * mapColor;",

				"#endif",
				
				THREE.Snippets[ "fog_fragment" ],
				
			"}"

		].join("\n"),
		
		vertex_shader: [
		
			"#ifdef USE_MAP",
			
				"varying vec2 vUv;",

			"#endif",
			
			"#ifdef USE_ENVMAP",
			
				"varying vec3 vReflect;",
				"uniform float refraction_ratio;",
				"uniform bool useRefract;",
				
			"#endif",
			
			"void main() {",
		
				"#ifdef USE_MAP",
				
					"vUv = uv;",
					
				"#endif",

				"#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",
				
				"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",

			"}"

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

N
Nicolas Garcia Belmonte 已提交
1928
};