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

7
THREE.WebGLRenderer = function ( scene ) {
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

M
Mr.doob 已提交
34
	BASIC = 0, 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
	maxLightCount = allocateLights( scene, 4 );
M
Mr.doob 已提交
40

N
Nicolas Garcia Belmonte 已提交
41 42 43 44
	this.domElement = _canvas;
	this.autoClear = true;

	initGL();
M
Mr.doob 已提交
45

46 47
	_uberProgram = initUbershader( maxLightCount.directional, maxLightCount.point );
	_oldProgram = _uberProgram;
M
Mr.doob 已提交
48

49
	//alert( dumpObject( getGLParams() ) );
M
Mr.doob 已提交
50

N
Nicolas Garcia Belmonte 已提交
51 52 53 54 55 56 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 );

	};

	this.clear = function () {

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

	};

65
	this.setupLights = function ( program, lights ) {
66

67
		var l, ll, light, r, g, b,
A
alteredq 已提交
68
			ambientLights = [], pointLights = [], directionalLights = [],
69
			colors = [], positions = [];
70

71
		_gl.uniform1i( program.uniforms.enableLighting, lights.length );
72

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

75
			light = lights[ l ];
76 77 78

			if ( light instanceof THREE.AmbientLight ) {

79
				ambientLights.push( light );
80

81
			} else if ( light instanceof THREE.DirectionalLight ) {
82

83
				directionalLights.push( light );
84

85 86
			} else if( light instanceof THREE.PointLight ) {

87
				pointLights.push( light );
M
Mr.doob 已提交
88

89 90 91
			}

		}
M
Mr.doob 已提交
92

93 94
		// sum all ambient lights
		r = g = b = 0.0;
M
Mr.doob 已提交
95

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

98 99 100
			r += ambientLights[ l ].color.r;
			g += ambientLights[ l ].color.g;
			b += ambientLights[ l ].color.b;
M
Mr.doob 已提交
101

102
		}
M
Mr.doob 已提交
103

M
Mr.doob 已提交
104
		_gl.uniform3f( program.uniforms.ambientLightColor, r, g, b );
105 106

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

108
		colors = []; positions = [];
M
Mr.doob 已提交
109

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

112
			light = directionalLights[ l ];
M
Mr.doob 已提交
113

114 115 116 117 118 119 120
			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 已提交
121

122
		}
M
Mr.doob 已提交
123

124 125
		if ( directionalLights.length ) {

M
Mr.doob 已提交
126 127 128
			_gl.uniform1i(  program.uniforms.directionalLightNumber, directionalLights.length );
			_gl.uniform3fv( program.uniforms.directionalLightDirection, positions );
			_gl.uniform3fv( program.uniforms.directionalLightColor, colors );
M
Mr.doob 已提交
129

130
		}
131

132
		// pass point lights as float arrays
M
Mr.doob 已提交
133

134
		colors = []; positions = [];
M
Mr.doob 已提交
135

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

138
			light = pointLights[ l ];
M
Mr.doob 已提交
139

140 141 142 143 144 145 146
			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 已提交
147

148
		}
M
Mr.doob 已提交
149

150 151
		if ( pointLights.length ) {

M
Mr.doob 已提交
152 153 154
			_gl.uniform1i(  program.uniforms.pointLightNumber, pointLights.length );
			_gl.uniform3fv( program.uniforms.pointLightPosition, positions );
			_gl.uniform3fv( program.uniforms.pointLightColor, colors );
M
Mr.doob 已提交
155

156
		}
M
Mr.doob 已提交
157

158
	};
M
Mr.doob 已提交
159

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

162
		var f, fl, fi, face, vertexNormals, normal, uv, v1, v2, v3, v4, t1, t2, t3, t4, m, ml, i,
163 164 165 166 167 168

		faceArray = [],
		lineArray = [],

		vertexArray = [],
		normalArray = [],
169
		tangentArray = [],
170 171
		uvArray = [],

172
		vertexIndex = 0,
173

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

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

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

M
Mr.doob 已提交
180
			fi = geometryChunk.faces[ f ];
181 182 183

			face = object.geometry.faces[ fi ];
			vertexNormals = face.vertexNormals;
184
			faceNormal = face.normal;
185 186 187 188 189 190 191 192 193 194 195 196
			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 );

197
				if ( object.geometry.hasTangents ) {
198

199 200 201 202 203 204 205
					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 );
206

207 208
				}

209
				if ( vertexNormals.length == 3 && needsSmoothNormals ) {
210

211

M
Mr.doob 已提交
212 213 214 215 216
					for ( i = 0; i < 3; i ++ ) {

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

					}
217 218 219

				} else {

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

222
						normalArray.push( faceNormal.x, faceNormal.y, faceNormal.z );
M
Mr.doob 已提交
223 224

					}
225 226 227 228 229

				}

				if ( uv ) {

M
Mr.doob 已提交
230 231 232
					for ( i = 0; i < 3; i ++ ) {

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

M
Mr.doob 已提交
234
					}
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258

				}

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

260
				if ( object.geometry.hasTangents ) {
261

262 263 264 265 266 267 268 269 270
					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 );
271

272
				}
273

274
				if ( vertexNormals.length == 4 && needsSmoothNormals ) {
275

M
Mr.doob 已提交
276 277 278 279 280
					for ( i = 0; i < 4; i ++ ) {

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

					}
281

282 283
				} else {

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

286
						normalArray.push( faceNormal.x, faceNormal.y, faceNormal.z );
M
Mr.doob 已提交
287 288

					}
289 290 291 292 293

				}

				if ( uv ) {

M
Mr.doob 已提交
294 295 296
					for ( i = 0; i < 4; i ++ ) {

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

M
Mr.doob 已提交
298
					}
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313

				}

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

315
			}
M
Mr.doob 已提交
316

317 318 319 320 321 322 323 324
		}

		if ( !vertexArray.length ) {

			return;

		}

M
Mr.doob 已提交
325 326
		geometryChunk.__webGLVertexBuffer = _gl.createBuffer();
		_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLVertexBuffer );
327 328
		_gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( vertexArray ), _gl.STATIC_DRAW );

M
Mr.doob 已提交
329 330
		geometryChunk.__webGLNormalBuffer = _gl.createBuffer();
		_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLNormalBuffer );
331 332
		_gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( normalArray ), _gl.STATIC_DRAW );

333
		if ( object.geometry.hasTangents ) {
334

335 336 337
			geometryChunk.__webGLTangentBuffer = _gl.createBuffer();
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLTangentBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( tangentArray ), _gl.STATIC_DRAW );
338

339
		}
340

341
		if ( uvArray.length > 0 ) {
M
Mr.doob 已提交
342

343 344 345
			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 已提交
346

347
		}
M
Mr.doob 已提交
348

M
Mr.doob 已提交
349 350
		geometryChunk.__webGLFaceBuffer = _gl.createBuffer();
		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryChunk.__webGLFaceBuffer );
351 352
		_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( faceArray ), _gl.STATIC_DRAW );

M
Mr.doob 已提交
353 354
		geometryChunk.__webGLLineBuffer = _gl.createBuffer();
		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryChunk.__webGLLineBuffer );
355 356
		_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( lineArray ), _gl.STATIC_DRAW );

M
Mr.doob 已提交
357 358
		geometryChunk.__webGLFaceCount = faceArray.length;
		geometryChunk.__webGLLineCount = lineArray.length;
359 360 361

	};

M
Mr.doob 已提交
362 363 364 365 366 367 368 369
	function setMaterialShaders( material, shaders ) {
		
		material.fragment_shader = shaders.fragment_shader;
		material.vertex_shader = shaders.vertex_shader;
		material.uniforms = shaders.uniforms;
		
	};
	
370
	this.renderBuffer = function ( camera, lights, material, geometryChunk ) {
371

372 373
		var mColor, mOpacity, mReflectivity,
			mWireframe, mLineWidth, mBlending,
A
alteredq 已提交
374
			mAmbient, mSpecular, mShininess,
375
			mMap, envMap, mixEnvMap,
M
Mr.doob 已提交
376
			mRefractionRatio, useRefract,
377
			program, u, identifiers, attributes;
M
Mr.doob 已提交
378

M
Mr.doob 已提交
379

M
Mr.doob 已提交
380 381 382
		if ( material instanceof THREE.MeshShaderMaterial ||
			 material instanceof THREE.MeshDepthMaterial ||
			 material instanceof THREE.MeshNormalMaterial ) {
M
Mr.doob 已提交
383

M
Mr.doob 已提交
384
			if ( !material.program ) {
M
Mr.doob 已提交
385

M
Mr.doob 已提交
386 387 388 389 390 391 392 393 394 395 396 397 398
				if ( material instanceof THREE.MeshDepthMaterial ) {
					
					setMaterialShaders( material, ShaderLib[ 'depth' ] );
					
					material.uniforms.mNear.value = material.near;
					material.uniforms.mFar.value = material.far;
					
				} else if ( material instanceof THREE.MeshNormalMaterial ) {
					
					setMaterialShaders( material, ShaderLib[ 'normal' ] );
					
				}					
				
M
Mr.doob 已提交
399
				material.program = buildProgram( material.fragment_shader, material.vertex_shader );
M
Mr.doob 已提交
400

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

404
					identifiers.push(u);
M
Mr.doob 已提交
405

406
				}
M
Mr.doob 已提交
407
				
M
Mr.doob 已提交
408
				cacheUniformLocations( material.program, identifiers );
409
				cacheAttributeLocations( material.program, [ "position", "normal", "uv", "tangent" ] );
M
Mr.doob 已提交
410

M
Mr.doob 已提交
411
			}
M
Mr.doob 已提交
412

M
Mr.doob 已提交
413
			program = material.program;
M
Mr.doob 已提交
414

M
Mr.doob 已提交
415
		} else {
M
Mr.doob 已提交
416

417
			program = _uberProgram;
M
Mr.doob 已提交
418

M
Mr.doob 已提交
419
		}
M
Mr.doob 已提交
420

M
Mr.doob 已提交
421
		if( program != _oldProgram ) {
M
Mr.doob 已提交
422

M
Mr.doob 已提交
423 424
			_gl.useProgram( program );
			_oldProgram = program;
M
Mr.doob 已提交
425

M
Mr.doob 已提交
426
		}
M
Mr.doob 已提交
427

428 429 430
		if ( program == _uberProgram ) {

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

432
		}
M
Mr.doob 已提交
433

434 435
		this.loadCamera( program, camera );
		this.loadMatrices( program );
M
Mr.doob 已提交
436

M
Mr.doob 已提交
437 438 439
		if ( material instanceof THREE.MeshShaderMaterial || 
		     material instanceof THREE.MeshDepthMaterial ||
			 material instanceof THREE.MeshNormalMaterial ) {
M
Mr.doob 已提交
440

M
Mr.doob 已提交
441 442
			mWireframe = material.wireframe;
			mLineWidth = material.wireframe_linewidth;
443

444
			mBlending = material.blending;
445

M
Mr.doob 已提交
446
			setUniforms( program, material.uniforms );
M
Mr.doob 已提交
447 448 449

		}

450
		if ( material instanceof THREE.MeshPhongMaterial ||
A
alteredq 已提交
451 452
			 material instanceof THREE.MeshLambertMaterial ||
			 material instanceof THREE.MeshBasicMaterial ) {
M
Mr.doob 已提交
453

A
alteredq 已提交
454 455
			mColor = material.color;
			mOpacity = material.opacity;
M
Mr.doob 已提交
456

A
alteredq 已提交
457 458
			mWireframe = material.wireframe;
			mLineWidth = material.wireframe_linewidth;
M
Mr.doob 已提交
459

A
alteredq 已提交
460
			mBlending = material.blending;
M
Mr.doob 已提交
461

A
alteredq 已提交
462
			mMap = material.map;
463
			envMap = material.env_map;
464

465
			mixEnvMap = material.combine == THREE.MixOperation;
466
			mReflectivity = material.reflectivity;
M
Mr.doob 已提交
467

468
			useRefract = material.env_map && material.env_map.mapping instanceof THREE.CubeRefractionMapping;
469
			mRefractionRatio = material.refraction_ratio;
M
Mr.doob 已提交
470

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

M
Mr.doob 已提交
473 474
			_gl.uniform1i( program.uniforms.mixEnvMap, mixEnvMap );
			_gl.uniform1f( program.uniforms.mReflectivity, mReflectivity );
M
Mr.doob 已提交
475

M
Mr.doob 已提交
476 477
			_gl.uniform1i( program.uniforms.useRefract, useRefract );
			_gl.uniform1f( program.uniforms.mRefractionRatio, mRefractionRatio );
M
Mr.doob 已提交
478

A
alteredq 已提交
479
		}
M
Mr.doob 已提交
480

M
Mr.doob 已提交
481
		if ( material instanceof THREE.MeshPhongMaterial ) {
482 483 484

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

M
Mr.doob 已提交
487 488 489
			_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 已提交
490

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

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

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

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

M
Mr.doob 已提交
499
			_gl.uniform1i( program.uniforms.material, BASIC );
500

M
Mr.doob 已提交
501
		}
M
Mr.doob 已提交
502

A
alteredq 已提交
503
		if ( mMap ) {
504

505
			setTexture( mMap, 0 );
M
Mr.doob 已提交
506

M
Mr.doob 已提交
507 508
			_gl.uniform1i( program.uniforms.tMap,  0 );
			_gl.uniform1i( program.uniforms.enableMap, 1 );
509

A
alteredq 已提交
510
		} else {
M
Mr.doob 已提交
511

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

514
		}
M
Mr.doob 已提交
515

516
		if ( envMap ) {
M
Mr.doob 已提交
517

518
			setCubeTexture( envMap, 1 );
M
Mr.doob 已提交
519

520
			_gl.uniform1i( program.uniforms.tCube, 1 );
M
Mr.doob 已提交
521
			_gl.uniform1i( program.uniforms.enableCubeMap, 1 );
M
Mr.doob 已提交
522

523
		} else {
M
Mr.doob 已提交
524

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

527
		}
M
Mr.doob 已提交
528

529
		attributes = program.attributes;
M
Mr.doob 已提交
530

531
		// vertices
M
Mr.doob 已提交
532

M
Mr.doob 已提交
533
		_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLVertexBuffer );
534
		_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
535
		_gl.enableVertexAttribArray( attributes.position );
536 537

		// normals
M
Mr.doob 已提交
538

539
		if ( attributes.normal >= 0 ) {
540

541 542
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLNormalBuffer );
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
543
			_gl.enableVertexAttribArray( attributes.normal );
544

545
		}
546

547 548 549
		// tangents

		if ( attributes.tangent >= 0 ) {
550

551 552
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLTangentBuffer );
			_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
553 554
			_gl.enableVertexAttribArray( attributes.tangent );
			
555
		}
556

557
		// uvs
M
Mr.doob 已提交
558

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

561
			if ( geometryChunk.__webGLUVBuffer ) {
562
				
563
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLUVBuffer );
564
				_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
565

566
				_gl.enableVertexAttribArray( attributes.uv );
567

568
			} else {
569

570
				_gl.disableVertexAttribArray( attributes.uv );
M
Mr.doob 已提交
571

572
			}
573 574 575 576

		}

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

A
alteredq 已提交
578
		if ( ! mWireframe ) {
579

M
Mr.doob 已提交
580 581
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryChunk.__webGLFaceBuffer );
			_gl.drawElements( _gl.TRIANGLES, geometryChunk.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
582 583

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

A
alteredq 已提交
585
		} else {
586

A
alteredq 已提交
587
			_gl.lineWidth( mLineWidth );
M
Mr.doob 已提交
588 589
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryChunk.__webGLLineBuffer );
			_gl.drawElements( _gl.LINES, geometryChunk.__webGLLineCount, _gl.UNSIGNED_SHORT, 0 );
590 591 592 593 594

		}

	};

595
	this.renderPass = function ( camera, lights, object, geometryChunk, blending, transparent ) {
M
Mr.doob 已提交
596

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

M
Mr.doob 已提交
599
		for ( m = 0, ml = object.material.length; m < ml; m++ ) {
600

M
Mr.doob 已提交
601
			meshMaterial = object.material[ m ];
602

M
Mr.doob 已提交
603
			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
604

M
Mr.doob 已提交
605
				for ( i = 0, l = geometryChunk.material.length; i < l; i++ ) {
606

M
Mr.doob 已提交
607
					material = geometryChunk.material[ i ];
608
					if ( material && material.blending == blending && ( material.opacity < 1.0 == transparent ) ) {
M
Mr.doob 已提交
609

M
Mr.doob 已提交
610
						this.setBlending( material.blending );
611
						this.renderBuffer( camera, lights, material, geometryChunk );
M
Mr.doob 已提交
612

613 614
					}

M
Mr.doob 已提交
615
				}
616

M
Mr.doob 已提交
617
			} else {
618

M
Mr.doob 已提交
619
				material = meshMaterial;
620
				if ( material && material.blending == blending && ( material.opacity < 1.0 == transparent ) ) {
M
Mr.doob 已提交
621

M
Mr.doob 已提交
622
					this.setBlending( material.blending );
623
					this.renderBuffer( camera, lights, material, geometryChunk );
M
Mr.doob 已提交
624

625 626 627
				}

			}
628 629

		}
M
Mr.doob 已提交
630

631
	};
M
Mr.doob 已提交
632

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

M
Mr.doob 已提交
635
		var o, ol, webGLObject, object, buffer,
636
			lights = scene.lights;
M
Mr.doob 已提交
637

M
Mr.doob 已提交
638
		this.initWebGLObjects( scene );
M
Mr.doob 已提交
639

640 641 642 643 644 645
		if ( this.autoClear ) {

			this.clear();

		}

646
		camera.autoUpdateMatrix && camera.updateMatrix();
647 648 649
		
		_viewMatrixArray.set( camera.matrix.flatten() );
		_projectionMatrixArray.set( camera.projectionMatrix.flatten() );
M
Mr.doob 已提交
650

M
Mr.doob 已提交
651
		// opaque pass
M
Mr.doob 已提交
652

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

M
Mr.doob 已提交
655
			webGLObject = scene.__webGLObjects[ o ];
M
Mr.doob 已提交
656

M
Mr.doob 已提交
657 658
			object = webGLObject.object;
			buffer = webGLObject.buffer;
M
Mr.doob 已提交
659

M
Mr.doob 已提交
660
			if ( object.visible ) {
M
Mr.doob 已提交
661

M
Mr.doob 已提交
662
				this.setupMatrices( object, camera );
663
				this.renderPass( camera, lights, object, buffer, THREE.NormalBlending, false );
M
Mr.doob 已提交
664

665
			}
M
Mr.doob 已提交
666

M
Mr.doob 已提交
667
		}
M
Mr.doob 已提交
668

M
Mr.doob 已提交
669
		// transparent pass
M
Mr.doob 已提交
670

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

M
Mr.doob 已提交
673
			webGLObject = scene.__webGLObjects[ o ];
M
Mr.doob 已提交
674

M
Mr.doob 已提交
675 676
			object = webGLObject.object;
			buffer = webGLObject.buffer;
M
Mr.doob 已提交
677

M
Mr.doob 已提交
678
			if ( object.visible ) {
M
Mr.doob 已提交
679

M
Mr.doob 已提交
680
				this.setupMatrices( object, camera );
681

682
				// opaque blended materials
M
Mr.doob 已提交
683

684 685
				this.renderPass( camera, lights, object, buffer, THREE.AdditiveBlending, false );
				this.renderPass( camera, lights, object, buffer, THREE.SubtractiveBlending, false );
M
Mr.doob 已提交
686

687
				// transparent blended materials
M
Mr.doob 已提交
688

689 690
				this.renderPass( camera, lights, object, buffer, THREE.AdditiveBlending, true );
				this.renderPass( camera, lights, object, buffer, THREE.SubtractiveBlending, true );
691

692
				// transparent normal materials
M
Mr.doob 已提交
693

694
				this.renderPass( camera, lights, object, buffer, THREE.NormalBlending, true );
M
Mr.doob 已提交
695

696
			}
M
Mr.doob 已提交
697

M
Mr.doob 已提交
698
		}
M
Mr.doob 已提交
699

M
Mr.doob 已提交
700
	};
M
Mr.doob 已提交
701

M
Mr.doob 已提交
702
	this.initWebGLObjects = function( scene ) {
M
Mr.doob 已提交
703

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

M
Mr.doob 已提交
706
		if ( !scene.__webGLObjects ) {
M
Mr.doob 已提交
707

M
Mr.doob 已提交
708
			scene.__webGLObjects = [];
M
Mr.doob 已提交
709
			scene.__webGLObjectsMap = {};
M
Mr.doob 已提交
710

M
Mr.doob 已提交
711
		}
M
Mr.doob 已提交
712

713 714 715 716
		for ( o = 0, ol = scene.objects.length; o < ol; o++ ) {

			object = scene.objects[ o ];

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

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

M
Mr.doob 已提交
721
			}
M
Mr.doob 已提交
722

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

725 726
			if ( object instanceof THREE.Mesh ) {

M
Mr.doob 已提交
727
				// create separate VBOs per geometry chunk
M
Mr.doob 已提交
728

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

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

M
Mr.doob 已提交
733
					// initialise VBO on the first access
M
Mr.doob 已提交
734

M
Mr.doob 已提交
735
					if( ! geometryChunk.__webGLVertexBuffer ) {
M
Mr.doob 已提交
736

M
Mr.doob 已提交
737
						this.createBuffers( object, g );
M
Mr.doob 已提交
738 739

					}
M
Mr.doob 已提交
740

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

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

M
Mr.doob 已提交
745 746
						globject = { buffer: geometryChunk, object: object };
						scene.__webGLObjects.push( globject );
M
Mr.doob 已提交
747

M
Mr.doob 已提交
748
						objmap[ g ] = 1;
M
Mr.doob 已提交
749

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

M
Mr.doob 已提交
752
				}
753

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

M
Mr.doob 已提交
756
			} else if ( object instanceof THREE.Particle ) {
M
Mr.doob 已提交
757 758 759

			}*/

M
Mr.doob 已提交
760
		}
761 762 763 764 765 766

	};

	this.removeObject = function ( scene, object ) {

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

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

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

772
			if ( object == zobject ) {
773 774 775 776

				scene.__webGLObjects.splice( o, 1 );

			}
M
Mr.doob 已提交
777

778
		}
M
Mr.doob 已提交
779

M
Mr.doob 已提交
780
	};
M
Mr.doob 已提交
781

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

M
Mr.doob 已提交
784
		object.autoUpdateMatrix && object.updateMatrix();
785

M
Mr.doob 已提交
786
		_modelViewMatrix.multiply( camera.matrix, object.matrix );
M
Mr.doob 已提交
787
		_modelViewMatrixArray.set( _modelViewMatrix.flatten() );
788

M
Mr.doob 已提交
789
		_normalMatrix = THREE.Matrix4.makeInvert3x3( _modelViewMatrix ).transpose();
M
Mr.doob 已提交
790
		_normalMatrixArray.set( _normalMatrix.m );
791

M
Mr.doob 已提交
792
		_objectMatrixArray.set( object.matrix.flatten() );
M
Mr.doob 已提交
793

M
Mr.doob 已提交
794
	};
M
Mr.doob 已提交
795

M
Mr.doob 已提交
796
	this.loadMatrices = function ( program ) {
M
Mr.doob 已提交
797

M
Mr.doob 已提交
798 799 800 801
		_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 已提交
802
		_gl.uniformMatrix4fv( program.uniforms.objectMatrix, false, _objectMatrixArray );
M
Mr.doob 已提交
803

M
Mr.doob 已提交
804
	};
805

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

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

M
Mr.doob 已提交
810
	};
M
Mr.doob 已提交
811

M
Mr.doob 已提交
812
	this.setBlending = function( blending ) {
M
Mr.doob 已提交
813

M
Mr.doob 已提交
814
		switch ( blending ) {
815

M
Mr.doob 已提交
816
			case THREE.AdditiveBlending:
817

M
Mr.doob 已提交
818 819
				_gl.blendEquation( _gl.FUNC_ADD );
				_gl.blendFunc( _gl.ONE, _gl.ONE );
M
Mr.doob 已提交
820

M
Mr.doob 已提交
821
				break;
822

M
Mr.doob 已提交
823
			case THREE.SubtractiveBlending:
824

M
Mr.doob 已提交
825 826
				//_gl.blendEquation( _gl.FUNC_SUBTRACT );
				_gl.blendFunc( _gl.DST_COLOR, _gl.ZERO );
M
Mr.doob 已提交
827

M
Mr.doob 已提交
828
				break;
M
Mr.doob 已提交
829

M
Mr.doob 已提交
830
			default:
M
Mr.doob 已提交
831

M
Mr.doob 已提交
832 833
				_gl.blendEquation( _gl.FUNC_ADD );
				_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
M
Mr.doob 已提交
834

M
Mr.doob 已提交
835
				break;
N
Nicolas Garcia Belmonte 已提交
836
		}
M
Mr.doob 已提交
837

N
Nicolas Garcia Belmonte 已提交
838
	};
M
Mr.doob 已提交
839

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

842
		if ( cullFace ) {
M
Mr.doob 已提交
843

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

846
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
847

848
			} else {
M
Mr.doob 已提交
849

850
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
851

852
			}
M
Mr.doob 已提交
853

854
			if( cullFace == "back" ) {
M
Mr.doob 已提交
855

856
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
857

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

860
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
861

862
			} else {
M
Mr.doob 已提交
863

864
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
865

866
			}
M
Mr.doob 已提交
867

868
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
869

870
		} else {
M
Mr.doob 已提交
871

872
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
873

874 875 876
		}

	};
N
Nicolas Garcia Belmonte 已提交
877

878
	this.supportsVertexTextures = function() {
879

880
		return maxVertexTextures() > 0;
881

882
	};
883

884
	function maxVertexTextures() {
885

886 887 888
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
889 890


N
Nicolas Garcia Belmonte 已提交
891 892 893 894
	function initGL() {

		try {

U
unknown 已提交
895
			_gl = _canvas.getContext( 'experimental-webgl', { antialias: true} );
N
Nicolas Garcia Belmonte 已提交
896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911

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

912 913
		_gl.frontFace( _gl.CCW );
		_gl.cullFace( _gl.BACK );
914
		_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
915

N
Nicolas Garcia Belmonte 已提交
916
		_gl.enable( _gl.BLEND );
917
		_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
N
Nicolas Garcia Belmonte 已提交
918 919
		_gl.clearColor( 0, 0, 0, 0 );

920
	};
N
Nicolas Garcia Belmonte 已提交
921

922
	function generateFragmentShader( maxDirLights, maxPointLights ) {
M
Mr.doob 已提交
923

924
		var chunks = [
925

926 927
			maxDirLights   ? "#define MAX_DIR_LIGHTS " + maxDirLights     : "",
			maxPointLights ? "#define MAX_POINT_LIGHTS " + maxPointLights : "",
M
Mr.doob 已提交
928

M
Mr.doob 已提交
929
			"uniform int material;", // 0 - Basic, 1 - Lambert, 2 - Phong
930

A
alteredq 已提交
931
			"uniform bool enableMap;",
932
			"uniform bool enableCubeMap;",
933
			"uniform bool mixEnvMap;",
M
Mr.doob 已提交
934

935 936 937
			"uniform samplerCube tCube;",
			"uniform float mReflectivity;",

A
alteredq 已提交
938
			"uniform sampler2D tMap;",
939
			"uniform vec4 mColor;",
940
			"uniform float mOpacity;",
941

942
			"uniform vec4 mAmbient;",
943
			"uniform vec4 mSpecular;",
944
			"uniform float mShininess;",
945

946 947
			"uniform int pointLightNumber;",
			"uniform int directionalLightNumber;",
M
Mr.doob 已提交
948

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

951
			"varying vec3 vNormal;",
952
			"varying vec2 vUv;",
M
Mr.doob 已提交
953

954 955
			"varying vec3 vLightWeighting;",

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

958
			"varying vec3 vViewPosition;",
M
Mr.doob 已提交
959

960
			"varying vec3 vReflect;",
M
Mr.doob 已提交
961

962
			"void main() {",
963

A
alteredq 已提交
964
				"vec4 mapColor = vec4( 1.0, 1.0, 1.0, 1.0 );",
965
				"vec4 cubeColor = vec4( 1.0, 1.0, 1.0, 1.0 );",
966

967
				// diffuse map
M
Mr.doob 已提交
968

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

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

A
alteredq 已提交
973
				"}",
974

975
				// cube map
M
Mr.doob 已提交
976

977
				"if ( enableCubeMap ) {",
M
Mr.doob 已提交
978

979 980 981 982
					"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 已提交
983

984 985
				"}",

986 987
				// Blinn-Phong
				// based on o3d example
M
Mr.doob 已提交
988

M
Mr.doob 已提交
989
				"if ( material == 2 ) { ",
990 991 992 993

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

994
					// point lights
M
Mr.doob 已提交
995

996 997 998
					maxPointLights ? "vec4 pointDiffuse  = vec4( 0.0, 0.0, 0.0, 0.0 );" : "",
					maxPointLights ? "vec4 pointSpecular = vec4( 0.0, 0.0, 0.0, 0.0 );" : "",

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

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

1004 1005 1006 1007 1008 1009
					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 已提交
1010

1011 1012
					//"float specularCompPoint = dot( normal, pointVector ) < 0.0 || pointDotNormalHalf < 0.0 ? 0.0 : pow( pointDotNormalHalf, mShininess );",
					//"float specularCompPoint = pow( pointDotNormalHalf, mShininess );",
1013
					//"float pointSpecularWeight = pointDotNormalHalf < 0.0 ? 0.0 : pow( pointDotNormalHalf, mShininess );",
1014

1015 1016
					// Ternary conditional inside for loop breaks Chrome shader linking.
					// Must do it with if.
1017

1018 1019 1020
					maxPointLights ? 	"float pointSpecularWeight = 0.0;" : "",
					maxPointLights ? 	"if ( pointDotNormalHalf >= 0.0 )" : "",
					maxPointLights ? 		"pointSpecularWeight = pow( pointDotNormalHalf, mShininess );" : "",
M
Mr.doob 已提交
1021

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

1025
					maxPointLights ? "}" : "",
1026

1027 1028 1029 1030
					// 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 已提交
1031

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

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

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

1039
					maxDirLights ? 		"float dirDotNormalHalf = dot( normal, dirHalfVector );" : "",
1040

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

1043 1044 1045
					maxDirLights ? 		"float dirSpecularWeight = 0.0;" : "",
					maxDirLights ? 		"if ( dirDotNormalHalf >= 0.0 )" : "",
					maxDirLights ? 			"dirSpecularWeight = pow( dirDotNormalHalf, mShininess );" : "",
1046

A
alteredq 已提交
1047
					maxDirLights ? 		"dirDiffuse  += mColor * dirDiffuseWeight;" : "",
1048 1049 1050 1051 1052
					maxDirLights ? 		"dirSpecular += mSpecular * dirSpecularWeight;" : "",

					maxDirLights ? "}" : "",

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

1054 1055 1056 1057 1058
					"vec4 totalLight = mAmbient;",
					maxDirLights   ? "totalLight += dirDiffuse + dirSpecular;" : "",
					maxPointLights ? "totalLight += pointDiffuse + pointSpecular;" : "",

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

1060
					"if ( mixEnvMap ) {",
M
Mr.doob 已提交
1061

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

1064
					"} else {",
M
Mr.doob 已提交
1065

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

1068
					"}",
M
Mr.doob 已提交
1069

A
alteredq 已提交
1070
				// Lambert: diffuse lighting
M
Mr.doob 已提交
1071 1072

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

M
Mr.doob 已提交
1074
					"if ( mixEnvMap ) {",
M
Mr.doob 已提交
1075

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

1078
					"} else {",
M
Mr.doob 已提交
1079

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

1082
					"}",
M
Mr.doob 已提交
1083

A
alteredq 已提交
1084
				// Basic: unlit color / texture
M
Mr.doob 已提交
1085 1086

				"} else {",
1087

1088 1089 1090
					"if ( mixEnvMap ) {",

						"gl_FragColor = mix( mColor * mapColor, cubeColor, mReflectivity );",
M
Mr.doob 已提交
1091

1092 1093 1094
					"} else {",

						"gl_FragColor = mColor * mapColor * cubeColor;",
M
Mr.doob 已提交
1095

1096
					"}",
M
Mr.doob 已提交
1097

1098 1099
				"}",

1100
			"}" ];
M
Mr.doob 已提交
1101

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

1104
	};
M
Mr.doob 已提交
1105

1106
	function generateVertexShader( maxDirLights, maxPointLights ) {
M
Mr.doob 已提交
1107

1108
		var chunks = [
M
Mr.doob 已提交
1109

1110 1111
			maxDirLights   ? "#define MAX_DIR_LIGHTS " + maxDirLights     : "",
			maxPointLights ? "#define MAX_POINT_LIGHTS " + maxPointLights : "",
M
Mr.doob 已提交
1112

1113
			"uniform bool enableLighting;",
1114
			"uniform bool useRefract;",
M
Mr.doob 已提交
1115

1116 1117
			"uniform int pointLightNumber;",
			"uniform int directionalLightNumber;",
M
Mr.doob 已提交
1118

1119
			"uniform vec3 ambientLightColor;",
M
Mr.doob 已提交
1120

1121 1122
			maxDirLights ? "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];"     : "",
			maxDirLights ? "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];" : "",
1123

1124 1125
			maxPointLights ? "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];"    : "",
			maxPointLights ? "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];" : "",
1126

1127
			"varying vec3 vNormal;",
1128
			"varying vec2 vUv;",
M
Mr.doob 已提交
1129

1130
			"varying vec3 vLightWeighting;",
1131

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

1134
			"varying vec3 vViewPosition;",
M
Mr.doob 已提交
1135

1136
			"varying vec3 vReflect;",
1137
			"uniform float mRefractionRatio;",
1138

1139
			"void main(void) {",
1140

1141
				// world space
M
Mr.doob 已提交
1142

M
Mr.doob 已提交
1143
				"vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
1144
				"vViewPosition = cameraPosition - mPosition.xyz;",
M
Mr.doob 已提交
1145

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

1150
				// eye space
M
Mr.doob 已提交
1151

1152
				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
1153
				"vec3 transformedNormal = normalize( normalMatrix * normal );",
1154

1155
				"if ( !enableLighting ) {",
1156

1157
					"vLightWeighting = vec3( 1.0, 1.0, 1.0 );",
1158 1159 1160

				"} else {",

1161
					"vLightWeighting = ambientLightColor;",
M
Mr.doob 已提交
1162

1163
					// directional lights
M
Mr.doob 已提交
1164

1165
					maxDirLights ? "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {" : "",
1166
					maxDirLights ?		"vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );" : "",
1167
					maxDirLights ?		"float directionalLightWeighting = max( dot( transformedNormal, normalize( lDirection.xyz ) ), 0.0 );" : "",
1168 1169
					maxDirLights ?		"vLightWeighting += directionalLightColor[ i ] * directionalLightWeighting;" : "",
					maxDirLights ? "}" : "",
M
Mr.doob 已提交
1170

1171
					// point lights
M
Mr.doob 已提交
1172

1173
					maxPointLights ? "for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {" : "",
1174 1175 1176 1177 1178
					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 已提交
1179

1180
				"}",
1181

1182
				"vNormal = transformedNormal;",
1183
				"vUv = uv;",
1184

1185
				"if ( useRefract ) {",
M
Mr.doob 已提交
1186

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

1189
				"} else {",
M
Mr.doob 已提交
1190

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

1193
				"}",
M
Mr.doob 已提交
1194

1195
				"gl_Position = projectionMatrix * mvPosition;",
1196

1197
			"}" ];
M
Mr.doob 已提交
1198

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

1201
	};
M
Mr.doob 已提交
1202

M
Mr.doob 已提交
1203
	function buildProgram( fragment_shader, vertex_shader ) {
M
Mr.doob 已提交
1204

M
Mr.doob 已提交
1205
		var program = _gl.createProgram(),
M
Mr.doob 已提交
1206

M
Mr.doob 已提交
1207 1208 1209 1210
		prefix_fragment = [
			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",
1211
			"uniform mat4 viewMatrix;",
1212
			"uniform vec3 cameraPosition;",
M
Mr.doob 已提交
1213 1214 1215 1216
			""
		].join("\n"),

		prefix_vertex = [
1217
			maxVertexTextures() > 0 ? "#define VERTEX_TEXTURES" : "",
1218

M
Mr.doob 已提交
1219 1220 1221
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
1222 1223
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
1224
			"uniform vec3 cameraPosition;",
M
Mr.doob 已提交
1225 1226 1227
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
M
Mr.doob 已提交
1228 1229
			""
		].join("\n");
M
Mr.doob 已提交
1230

M
Mr.doob 已提交
1231 1232
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragment_shader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertex_shader ) );
M
Mr.doob 已提交
1233

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

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

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

N
Nicolas Garcia Belmonte 已提交
1241
		}
M
Mr.doob 已提交
1242

M
Mr.doob 已提交
1243
		program.uniforms = {};
1244
		program.attributes = {};
M
Mr.doob 已提交
1245

M
Mr.doob 已提交
1246
		return program;
M
Mr.doob 已提交
1247

M
Mr.doob 已提交
1248
	};
M
Mr.doob 已提交
1249

M
Mr.doob 已提交
1250
	function setUniforms( program, uniforms ) {
M
Mr.doob 已提交
1251

M
Mr.doob 已提交
1252
		var u, value, type, location, texture;
M
Mr.doob 已提交
1253

M
Mr.doob 已提交
1254
		for( u in uniforms ) {
M
Mr.doob 已提交
1255

M
Mr.doob 已提交
1256 1257 1258
			type = uniforms[u].type;
			value = uniforms[u].value;
			location = program.uniforms[u];
M
Mr.doob 已提交
1259

M
Mr.doob 已提交
1260
			if( type == "i" ) {
M
Mr.doob 已提交
1261

M
Mr.doob 已提交
1262
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
1263

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

M
Mr.doob 已提交
1266
				_gl.uniform1f( location, value );
1267

1268 1269 1270
			} else if( type == "v3" ) {

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

1272 1273 1274
			} else if( type == "c" ) {

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

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

M
Mr.doob 已提交
1278
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
1279

M
Mr.doob 已提交
1280
				texture = uniforms[u].texture;
M
Mr.doob 已提交
1281

1282
				if ( !texture ) continue;
M
Mr.doob 已提交
1283

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

1286
					setCubeTexture( texture, value );
M
Mr.doob 已提交
1287

1288
				} else {
M
Mr.doob 已提交
1289

1290
					setTexture( texture, value );
M
Mr.doob 已提交
1291

1292
				}
M
Mr.doob 已提交
1293

1294
			}
M
Mr.doob 已提交
1295

1296
		}
M
Mr.doob 已提交
1297

1298
	};
M
Mr.doob 已提交
1299

1300
	function setCubeTexture( texture, slot ) {
M
Mr.doob 已提交
1301

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

1304 1305
			if ( !texture.image.__webGLTextureCube &&
				 !texture.image.__cubeMapInitialized && texture.image.loadCount == 6 ) {
M
Mr.doob 已提交
1306

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

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

1311 1312
				_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 已提交
1313

1314 1315
				_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 已提交
1316

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

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

1321
				}
M
Mr.doob 已提交
1322

1323
				_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
1324

1325
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
M
Mr.doob 已提交
1326

1327
				texture.image.__cubeMapInitialized = true;
M
Mr.doob 已提交
1328

M
Mr.doob 已提交
1329
			}
1330 1331 1332

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

1334
		}
M
Mr.doob 已提交
1335

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

1338
	function setTexture( texture, slot ) {
M
Mr.doob 已提交
1339

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

1346 1347
			_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 已提交
1348 1349 1350

			_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 ) );
1351 1352 1353 1354 1355 1356 1357
			_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 已提交
1358

1359
	};
M
Mr.doob 已提交
1360

M
Mr.doob 已提交
1361
	function cacheUniformLocations( program, identifiers ) {
M
Mr.doob 已提交
1362

M
Mr.doob 已提交
1363
		var i, l, id;
M
Mr.doob 已提交
1364

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

1367 1368
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
1369

M
Mr.doob 已提交
1370
		}
M
Mr.doob 已提交
1371

M
Mr.doob 已提交
1372
	};
M
Mr.doob 已提交
1373

1374
	function cacheAttributeLocations( program, identifiers ) {
1375

1376
		var i, l, id;
M
Mr.doob 已提交
1377

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

1380 1381
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
1382

1383
		}
M
Mr.doob 已提交
1384

M
Mr.doob 已提交
1385
	};
M
Mr.doob 已提交
1386

M
Mr.doob 已提交
1387
	function initUbershader( maxDirLights, maxPointLights ) {
M
Mr.doob 已提交
1388

M
Mr.doob 已提交
1389
		var vertex_shader = generateVertexShader( maxDirLights, maxPointLights ),
1390 1391
			fragment_shader = generateFragmentShader( maxDirLights, maxPointLights ),
			program;
1392

M
Mr.doob 已提交
1393 1394
		//log ( vertex_shader );
		//log ( fragment_shader );
M
Mr.doob 已提交
1395

1396
		program = buildProgram( fragment_shader, vertex_shader );
M
Mr.doob 已提交
1397

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

M
Mr.doob 已提交
1400 1401 1402
		// matrices
		// lights
		// material properties (Basic / Lambert / Blinn-Phong shader)
M
Mr.doob 已提交
1403

1404
		cacheUniformLocations( program, [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
M
Mr.doob 已提交
1405 1406 1407 1408
										   'enableLighting', 'ambientLightColor',
										   'material', 'mColor', 'mAmbient', 'mSpecular', 'mShininess', 'mOpacity',
										   'enableMap', 'tMap',
										   'enableCubeMap', 'tCube', 'mixEnvMap', 'mReflectivity',
M
Mr.doob 已提交
1409
										   'mRefractionRatio', 'useRefract'
M
Mr.doob 已提交
1410
		] );
1411

M
Mr.doob 已提交
1412

M
Mr.doob 已提交
1413
		if ( maxDirLights ) {
M
Mr.doob 已提交
1414 1415

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

M
Mr.doob 已提交
1417
		}
1418

M
Mr.doob 已提交
1419
		if ( maxPointLights ) {
M
Mr.doob 已提交
1420

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

M
Mr.doob 已提交
1423
		}
M
Mr.doob 已提交
1424

M
Mr.doob 已提交
1425
		// texture (diffuse map)
M
Mr.doob 已提交
1426

1427 1428
		_gl.uniform1i( program.uniforms.enableMap, 0 );
		_gl.uniform1i( program.uniforms.tMap, 0 );
M
Mr.doob 已提交
1429

M
Mr.doob 已提交
1430
		// cube texture
M
Mr.doob 已提交
1431

1432 1433 1434
		_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 已提交
1435

M
Mr.doob 已提交
1436
		// refraction
M
Mr.doob 已提交
1437

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

1440
		// attribute arrays
M
Mr.doob 已提交
1441

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

1444
		return program;
N
Nicolas Garcia Belmonte 已提交
1445

1446
	};
N
Nicolas Garcia Belmonte 已提交
1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472

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

1474
	};
N
Nicolas Garcia Belmonte 已提交
1475

1476
	function paramThreeToGL( p ) {
M
Mr.doob 已提交
1477

1478
		switch ( p ) {
M
Mr.doob 已提交
1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491

			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;

1492
		}
M
Mr.doob 已提交
1493

1494
		return 0;
M
Mr.doob 已提交
1495

1496 1497 1498 1499 1500 1501
	};

	function materialNeedsSmoothNormals( material ) {

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

1502
	};
M
Mr.doob 已提交
1503

M
Mr.doob 已提交
1504
	function bufferNeedsSmoothNormals( geometryChunk, object ) {
M
Mr.doob 已提交
1505

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

1508 1509 1510 1511 1512 1513
		for ( m = 0, ml = object.material.length; m < ml; m++ ) {

			meshMaterial = object.material[ m ];

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

M
Mr.doob 已提交
1514
				for ( i = 0, l = geometryChunk.material.length; i < l; i++ ) {
1515

M
Mr.doob 已提交
1516
					if ( materialNeedsSmoothNormals( geometryChunk.material[ i ] ) ) {
1517

1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538
						needsSmoothNormals = true;
						break;

					}

				}

			} else {

				if ( materialNeedsSmoothNormals( meshMaterial ) ) {

					needsSmoothNormals = true;
					break;

				}

			}

			if ( needsSmoothNormals ) break;

		}
M
Mr.doob 已提交
1539

1540
		return needsSmoothNormals;
M
Mr.doob 已提交
1541

1542
	};
M
Mr.doob 已提交
1543

1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577
	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 已提交
1578

A
alteredq 已提交
1579
	/* DEBUG
1580
	function getGLParams() {
M
Mr.doob 已提交
1581

1582
		var params  = {
M
Mr.doob 已提交
1583

1584 1585
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
1586

1587 1588 1589
			'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 已提交
1590

1591 1592 1593
			'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 已提交
1594

1595 1596
		return params;
	};
M
Mr.doob 已提交
1597

1598
	function dumpObject( obj ) {
M
Mr.doob 已提交
1599

1600 1601
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
1602

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

1605
		}
M
Mr.doob 已提交
1606

1607 1608
		return str;
	}
A
alteredq 已提交
1609
	*/
M
Mr.doob 已提交
1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 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 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678
	
	var ShaderLib = {
		
		'depth': {

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

			fragment_shader: [
				
				"uniform float mNear;",
				"uniform float mFar;",

				"void main() {",
						
					"float depth = gl_FragCoord.z / gl_FragCoord.w;",
					"float color = 1.0 - smoothstep( mNear, mFar, depth );",
					"gl_FragColor = vec4( vec3( color ), 1.0 );",
					
				"}"

			].join("\n"),
						
			vertex_shader: [

				"void main() {",

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

				"}"

			].join("\n")

		},
		
		'normal': {
			
			uniforms: { },
			
			fragment_shader: [
				
				"varying vec3 vNormal;",
			
				"void main() {",
						
					"gl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, 1.0 );",
					
				"}"

			].join("\n"),
			
			vertex_shader: [
			
				"varying vec3 vNormal;",

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

					"gl_Position = projectionMatrix * mvPosition;",

				"}"

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

N
Nicolas Garcia Belmonte 已提交
1680
};