WebGLRenderer.js 41.3 KB
Newer Older
N
Nicolas Garcia Belmonte 已提交
1 2 3
/**
 * @author supereggbert / http://www.paulbrunt.co.uk/
 * @author mrdoob / http://mrdoob.com/
4
 * @author alteredq / http://alteredqualia.com/
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 34

	BASIC = 0, LAMBERT = 1, PHONG = 2, DEPTH = 3, NORMAL = 4, CUBE = 5,
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

	};

362
	this.renderBuffer = function ( camera, lights, material, geometryChunk ) {
363

364 365
		var mColor, mOpacity, mReflectivity,
			mWireframe, mLineWidth, mBlending,
A
alteredq 已提交
366
			mAmbient, mSpecular, mShininess,
367
			mMap, envMap, mixEnvMap,
M
Mr.doob 已提交
368
			mRefractionRatio, useRefract,
369
			program, u, identifiers, attributes;
M
Mr.doob 已提交
370

M
Mr.doob 已提交
371

M
Mr.doob 已提交
372
		if ( material instanceof THREE.MeshShaderMaterial ) {
M
Mr.doob 已提交
373

M
Mr.doob 已提交
374
			if ( !material.program ) {
M
Mr.doob 已提交
375

M
Mr.doob 已提交
376
				material.program = buildProgram( material.fragment_shader, material.vertex_shader );
M
Mr.doob 已提交
377

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

381
					identifiers.push(u);
M
Mr.doob 已提交
382

383
				}
M
Mr.doob 已提交
384
				cacheUniformLocations( material.program, identifiers );
385
				cacheAttributeLocations( material.program, [ "position", "normal", "uv", "tangent" ] );
M
Mr.doob 已提交
386

M
Mr.doob 已提交
387
			}
M
Mr.doob 已提交
388

M
Mr.doob 已提交
389
			program = material.program;
M
Mr.doob 已提交
390

M
Mr.doob 已提交
391
		} else {
M
Mr.doob 已提交
392

393
			program = _uberProgram;
M
Mr.doob 已提交
394

M
Mr.doob 已提交
395
		}
M
Mr.doob 已提交
396

M
Mr.doob 已提交
397
		if( program != _oldProgram ) {
M
Mr.doob 已提交
398

M
Mr.doob 已提交
399 400
			_gl.useProgram( program );
			_oldProgram = program;
M
Mr.doob 已提交
401

M
Mr.doob 已提交
402
		}
M
Mr.doob 已提交
403

404 405 406
		if ( program == _uberProgram ) {

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

408
		}
M
Mr.doob 已提交
409

410 411
		this.loadCamera( program, camera );
		this.loadMatrices( program );
M
Mr.doob 已提交
412

M
Mr.doob 已提交
413
		if ( material instanceof THREE.MeshShaderMaterial ) {
M
Mr.doob 已提交
414

M
Mr.doob 已提交
415 416
			mWireframe = material.wireframe;
			mLineWidth = material.wireframe_linewidth;
417

418
			mBlending = material.blending;
419

M
Mr.doob 已提交
420
			setUniforms( program, material.uniforms );
M
Mr.doob 已提交
421 422 423

		}

424
		if ( material instanceof THREE.MeshPhongMaterial ||
A
alteredq 已提交
425 426
			 material instanceof THREE.MeshLambertMaterial ||
			 material instanceof THREE.MeshBasicMaterial ) {
M
Mr.doob 已提交
427

A
alteredq 已提交
428 429
			mColor = material.color;
			mOpacity = material.opacity;
M
Mr.doob 已提交
430

A
alteredq 已提交
431 432
			mWireframe = material.wireframe;
			mLineWidth = material.wireframe_linewidth;
M
Mr.doob 已提交
433

A
alteredq 已提交
434
			mBlending = material.blending;
M
Mr.doob 已提交
435

A
alteredq 已提交
436
			mMap = material.map;
437
			envMap = material.env_map;
438

439
			mixEnvMap = material.combine == THREE.MixOperation;
440
			mReflectivity = material.reflectivity;
M
Mr.doob 已提交
441

442
			useRefract = material.env_map && material.env_map.mapping instanceof THREE.CubeRefractionMapping;
443
			mRefractionRatio = material.refraction_ratio;
M
Mr.doob 已提交
444

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

M
Mr.doob 已提交
447 448
			_gl.uniform1i( program.uniforms.mixEnvMap, mixEnvMap );
			_gl.uniform1f( program.uniforms.mReflectivity, mReflectivity );
M
Mr.doob 已提交
449

M
Mr.doob 已提交
450 451
			_gl.uniform1i( program.uniforms.useRefract, useRefract );
			_gl.uniform1f( program.uniforms.mRefractionRatio, mRefractionRatio );
M
Mr.doob 已提交
452

A
alteredq 已提交
453
		}
M
Mr.doob 已提交
454

455
		if ( material instanceof THREE.MeshNormalMaterial ) {
M
Mr.doob 已提交
456

457 458
			mOpacity = material.opacity;
			mBlending = material.blending;
M
Mr.doob 已提交
459

M
Mr.doob 已提交
460
			_gl.uniform1f( program.uniforms.mOpacity, mOpacity );
M
Mr.doob 已提交
461

M
Mr.doob 已提交
462
			_gl.uniform1i( program.uniforms.material, NORMAL );
M
Mr.doob 已提交
463

464
		} else if ( material instanceof THREE.MeshDepthMaterial ) {
M
Mr.doob 已提交
465

466
			mOpacity = material.opacity;
M
Mr.doob 已提交
467

468 469
			mWireframe = material.wireframe;
			mLineWidth = material.wireframe_linewidth;
M
Mr.doob 已提交
470

M
Mr.doob 已提交
471
			_gl.uniform1f( program.uniforms.mOpacity, mOpacity );
M
Mr.doob 已提交
472

M
Mr.doob 已提交
473 474 475
			_gl.uniform1f( program.uniforms.m2Near, material.__2near );
			_gl.uniform1f( program.uniforms.mFarPlusNear, material.__farPlusNear );
			_gl.uniform1f( program.uniforms.mFarMinusNear, material.__farMinusNear );
M
Mr.doob 已提交
476

M
Mr.doob 已提交
477
			_gl.uniform1i( program.uniforms.material, DEPTH );
M
Mr.doob 已提交
478

479
		} else if ( material instanceof THREE.MeshPhongMaterial ) {
480 481 482

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

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

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

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

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

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

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

M
Mr.doob 已提交
499 500
		} else if ( material instanceof THREE.MeshCubeMaterial ) {

M
Mr.doob 已提交
501
			_gl.uniform1i( program.uniforms.material, CUBE );
M
Mr.doob 已提交
502

M
Mr.doob 已提交
503 504
			envMap = material.env_map;

M
Mr.doob 已提交
505
		}
M
Mr.doob 已提交
506

A
alteredq 已提交
507
		if ( mMap ) {
508

509
			setTexture( mMap, 0 );
M
Mr.doob 已提交
510

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

A
alteredq 已提交
514
		} else {
M
Mr.doob 已提交
515

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

518
		}
M
Mr.doob 已提交
519

520
		if ( envMap ) {
M
Mr.doob 已提交
521

522
			setCubeTexture( envMap, 1 );
M
Mr.doob 已提交
523

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

527
		} else {
M
Mr.doob 已提交
528

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

531
		}
M
Mr.doob 已提交
532

533
		attributes = program.attributes;
M
Mr.doob 已提交
534

535
		// vertices
M
Mr.doob 已提交
536

M
Mr.doob 已提交
537
		_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLVertexBuffer );
538
		_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
539 540

		// normals
M
Mr.doob 已提交
541

542
		if ( attributes.normal >= 0 ) {
543

544 545
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLNormalBuffer );
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
546

547
		}
548

549 550 551
		// tangents

		if ( attributes.tangent >= 0 ) {
552

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

556
		}
557

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

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

562
			if ( geometryChunk.__webGLUVBuffer ) {
563

564
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLUVBuffer );
565

566 567
				_gl.enableVertexAttribArray( attributes.uv );
				_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
568

569
			} else {
570

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

573
			}
574 575 576 577

		}

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

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

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

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

A
alteredq 已提交
586
		} else {
587

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

		}

	};

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

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

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

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

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

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

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

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

614 615
					}

M
Mr.doob 已提交
616
				}
617

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

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

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

626 627 628
				}

			}
629 630

		}
M
Mr.doob 已提交
631

632
	};
M
Mr.doob 已提交
633

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

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

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

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

			this.clear();

		}

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

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

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

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

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

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

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

666
			}
M
Mr.doob 已提交
667

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

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

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

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

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

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

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

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

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

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

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

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

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

697
			}
M
Mr.doob 已提交
698

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

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

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

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

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

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

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

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

			object = scene.objects[ o ];

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

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

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

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

726 727
			if ( object instanceof THREE.Mesh ) {

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

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

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

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

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

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

					}
M
Mr.doob 已提交
741

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

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

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

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

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

M
Mr.doob 已提交
753
				}
754

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

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

			}*/

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

	};

	this.removeObject = function ( scene, object ) {

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

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

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

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

				scene.__webGLObjects.splice( o, 1 );

			}
M
Mr.doob 已提交
778

779
		}
M
Mr.doob 已提交
780

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

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

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

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

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

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

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

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

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

M
Mr.doob 已提交
805
	};
806

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

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

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

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

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

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

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

M
Mr.doob 已提交
822
				break;
823

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

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

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

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

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

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

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

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

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

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

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

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

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

853
			}
M
Mr.doob 已提交
854

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

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

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

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

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

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

867
			}
M
Mr.doob 已提交
868

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

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

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

875 876 877
		}

	};
N
Nicolas Garcia Belmonte 已提交
878

879
	this.supportsVertexTextures = function() {
880

881
		return maxVertexTextures() > 0;
882

883
	};
884

885
	function maxVertexTextures() {
886

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

	};
890 891


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

		try {

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

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

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

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

921
	};
N
Nicolas Garcia Belmonte 已提交
922

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

925
		var chunks = [
926

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

M
Mr.doob 已提交
930
			"uniform int material;", // 0 - Basic, 1 - Lambert, 2 - Phong, 3 - Depth, 4 - Normal, 5 - Cube
931

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

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

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

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

947 948 949
			"uniform float m2Near;",
			"uniform float mFarPlusNear;",
			"uniform float mFarMinusNear;",
M
Mr.doob 已提交
950

951 952
			"uniform int pointLightNumber;",
			"uniform int directionalLightNumber;",
M
Mr.doob 已提交
953

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

956
			"varying vec3 vNormal;",
957
			"varying vec2 vUv;",
M
Mr.doob 已提交
958

959 960
			"varying vec3 vLightWeighting;",

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

963
			"varying vec3 vViewPosition;",
M
Mr.doob 已提交
964

965
			"varying vec3 vReflect;",
M
Mr.doob 已提交
966

M
Mr.doob 已提交
967
			"uniform vec3 cameraPosition;",
M
Mr.doob 已提交
968

969
			"void main() {",
970

A
alteredq 已提交
971
				"vec4 mapColor = vec4( 1.0, 1.0, 1.0, 1.0 );",
972
				"vec4 cubeColor = vec4( 1.0, 1.0, 1.0, 1.0 );",
973

974
				// diffuse map
M
Mr.doob 已提交
975

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

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

A
alteredq 已提交
980
				"}",
981

982
				// cube map
M
Mr.doob 已提交
983

984
				"if ( enableCubeMap ) {",
M
Mr.doob 已提交
985

986 987 988 989
					"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 已提交
990

991 992
				"}",

M
Mr.doob 已提交
993
				// Cube
M
Mr.doob 已提交
994

M
Mr.doob 已提交
995 996 997 998 999
				"if ( material == 5 ) { ",

					"vec3 wPos = cameraPosition - vViewPosition;",
					"gl_FragColor = textureCube( tCube, vec3( -wPos.x, wPos.yz ) );",

1000
				// Normals
M
Mr.doob 已提交
1001

M
Mr.doob 已提交
1002
				"} else if ( material == 4 ) { ",
M
Mr.doob 已提交
1003

1004
					"gl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, mOpacity );",
M
Mr.doob 已提交
1005

1006
				// Depth
M
Mr.doob 已提交
1007

1008
				"} else if ( material == 3 ) { ",
M
Mr.doob 已提交
1009 1010

					// this breaks shader validation in Chrome 9.0.576.0 dev
1011 1012 1013 1014
					// and also latest continuous build Chromium 9.0.583.0 (66089)
					// (curiously it works in Chrome 9.0.576.0 canary build and Firefox 4b7)
					//"float w = 1.0 - ( m2Near / ( mFarPlusNear - gl_FragCoord.z * mFarMinusNear ) );",
					"float w = 0.5;",
M
Mr.doob 已提交
1015

1016
					"gl_FragColor = vec4( w, w, w, mOpacity );",
M
Mr.doob 已提交
1017

1018 1019
				// Blinn-Phong
				// based on o3d example
M
Mr.doob 已提交
1020 1021

				"} else if ( material == 2 ) { ",
1022 1023 1024 1025

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

1026
					// point lights
M
Mr.doob 已提交
1027

1028 1029 1030
					maxPointLights ? "vec4 pointDiffuse  = vec4( 0.0, 0.0, 0.0, 0.0 );" : "",
					maxPointLights ? "vec4 pointSpecular = vec4( 0.0, 0.0, 0.0, 0.0 );" : "",

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

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

1036 1037 1038 1039 1040 1041
					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 已提交
1042

1043 1044
					//"float specularCompPoint = dot( normal, pointVector ) < 0.0 || pointDotNormalHalf < 0.0 ? 0.0 : pow( pointDotNormalHalf, mShininess );",
					//"float specularCompPoint = pow( pointDotNormalHalf, mShininess );",
1045
					//"float pointSpecularWeight = pointDotNormalHalf < 0.0 ? 0.0 : pow( pointDotNormalHalf, mShininess );",
1046

1047 1048
					// Ternary conditional inside for loop breaks Chrome shader linking.
					// Must do it with if.
1049

1050 1051 1052
					maxPointLights ? 	"float pointSpecularWeight = 0.0;" : "",
					maxPointLights ? 	"if ( pointDotNormalHalf >= 0.0 )" : "",
					maxPointLights ? 		"pointSpecularWeight = pow( pointDotNormalHalf, mShininess );" : "",
M
Mr.doob 已提交
1053

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

1057
					maxPointLights ? "}" : "",
1058

1059 1060 1061 1062
					// 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 已提交
1063

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

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

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

1071
					maxDirLights ? 		"float dirDotNormalHalf = dot( normal, dirHalfVector );" : "",
1072

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

1075 1076 1077
					maxDirLights ? 		"float dirSpecularWeight = 0.0;" : "",
					maxDirLights ? 		"if ( dirDotNormalHalf >= 0.0 )" : "",
					maxDirLights ? 			"dirSpecularWeight = pow( dirDotNormalHalf, mShininess );" : "",
1078

A
alteredq 已提交
1079
					maxDirLights ? 		"dirDiffuse  += mColor * dirDiffuseWeight;" : "",
1080 1081 1082 1083 1084
					maxDirLights ? 		"dirSpecular += mSpecular * dirSpecularWeight;" : "",

					maxDirLights ? "}" : "",

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

1086 1087 1088 1089 1090
					"vec4 totalLight = mAmbient;",
					maxDirLights   ? "totalLight += dirDiffuse + dirSpecular;" : "",
					maxPointLights ? "totalLight += pointDiffuse + pointSpecular;" : "",

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

1092
					"if ( mixEnvMap ) {",
M
Mr.doob 已提交
1093

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

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

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

1100
					"}",
M
Mr.doob 已提交
1101

A
alteredq 已提交
1102
				// Lambert: diffuse lighting
M
Mr.doob 已提交
1103 1104

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

M
Mr.doob 已提交
1106
					"if ( mixEnvMap ) {",
M
Mr.doob 已提交
1107

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

1110
					"} else {",
M
Mr.doob 已提交
1111

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

1114
					"}",
M
Mr.doob 已提交
1115

A
alteredq 已提交
1116
				// Basic: unlit color / texture
M
Mr.doob 已提交
1117 1118

				"} else {",
1119

1120 1121 1122
					"if ( mixEnvMap ) {",

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

1124 1125 1126
					"} else {",

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

1128
					"}",
M
Mr.doob 已提交
1129

1130 1131
				"}",

1132
			"}" ];
M
Mr.doob 已提交
1133

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

1136
	};
M
Mr.doob 已提交
1137

1138
	function generateVertexShader( maxDirLights, maxPointLights ) {
M
Mr.doob 已提交
1139

1140
		var chunks = [
M
Mr.doob 已提交
1141

1142 1143
			maxDirLights   ? "#define MAX_DIR_LIGHTS " + maxDirLights     : "",
			maxPointLights ? "#define MAX_POINT_LIGHTS " + maxPointLights : "",
M
Mr.doob 已提交
1144

1145
			"uniform bool enableLighting;",
1146
			"uniform bool useRefract;",
M
Mr.doob 已提交
1147

1148 1149
			"uniform int pointLightNumber;",
			"uniform int directionalLightNumber;",
M
Mr.doob 已提交
1150

1151
			"uniform vec3 ambientLightColor;",
M
Mr.doob 已提交
1152

1153 1154
			maxDirLights ? "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];"     : "",
			maxDirLights ? "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];" : "",
1155

1156 1157
			maxPointLights ? "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];"    : "",
			maxPointLights ? "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];" : "",
1158

1159
			"varying vec3 vNormal;",
1160
			"varying vec2 vUv;",
M
Mr.doob 已提交
1161

1162
			"varying vec3 vLightWeighting;",
1163

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

1166
			"varying vec3 vViewPosition;",
M
Mr.doob 已提交
1167

1168
			"varying vec3 vReflect;",
1169
			"uniform float mRefractionRatio;",
1170

1171
			"void main(void) {",
1172

1173
				// world space
M
Mr.doob 已提交
1174

M
Mr.doob 已提交
1175
				"vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
1176
				"vViewPosition = cameraPosition - mPosition.xyz;",
M
Mr.doob 已提交
1177

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

1182
				// eye space
M
Mr.doob 已提交
1183

1184
				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
1185
				"vec3 transformedNormal = normalize( normalMatrix * normal );",
1186

1187
				"if ( !enableLighting ) {",
1188

1189
					"vLightWeighting = vec3( 1.0, 1.0, 1.0 );",
1190 1191 1192

				"} else {",

1193
					"vLightWeighting = ambientLightColor;",
M
Mr.doob 已提交
1194

1195
					// directional lights
M
Mr.doob 已提交
1196

1197
					maxDirLights ? "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {" : "",
1198
					maxDirLights ?		"vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );" : "",
1199
					maxDirLights ?		"float directionalLightWeighting = max( dot( transformedNormal, normalize( lDirection.xyz ) ), 0.0 );" : "",
1200 1201
					maxDirLights ?		"vLightWeighting += directionalLightColor[ i ] * directionalLightWeighting;" : "",
					maxDirLights ? "}" : "",
M
Mr.doob 已提交
1202

1203
					// point lights
M
Mr.doob 已提交
1204

1205
					maxPointLights ? "for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {" : "",
1206 1207 1208 1209 1210
					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 已提交
1211

1212
				"}",
1213

1214
				"vNormal = transformedNormal;",
1215
				"vUv = uv;",
1216

1217
				"if ( useRefract ) {",
M
Mr.doob 已提交
1218

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

1221
				"} else {",
M
Mr.doob 已提交
1222

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

1225
				"}",
M
Mr.doob 已提交
1226

1227
				"gl_Position = projectionMatrix * mvPosition;",
1228

1229
			"}" ];
M
Mr.doob 已提交
1230

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

1233
	};
M
Mr.doob 已提交
1234

M
Mr.doob 已提交
1235
	function buildProgram( fragment_shader, vertex_shader ) {
M
Mr.doob 已提交
1236

M
Mr.doob 已提交
1237
		var program = _gl.createProgram(),
M
Mr.doob 已提交
1238

M
Mr.doob 已提交
1239 1240 1241 1242
		prefix_fragment = [
			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",
1243
			"uniform mat4 viewMatrix;",
M
Mr.doob 已提交
1244 1245 1246 1247
			""
		].join("\n"),

		prefix_vertex = [
1248
			maxVertexTextures() > 0 ? "#define VERTEX_TEXTURES" : "",
1249

M
Mr.doob 已提交
1250 1251 1252
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
1253 1254
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
1255
			"uniform vec3 cameraPosition;",
M
Mr.doob 已提交
1256 1257 1258
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
M
Mr.doob 已提交
1259 1260
			""
		].join("\n");
M
Mr.doob 已提交
1261

M
Mr.doob 已提交
1262 1263
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragment_shader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertex_shader ) );
M
Mr.doob 已提交
1264

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

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

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

N
Nicolas Garcia Belmonte 已提交
1272
		}
M
Mr.doob 已提交
1273

M
Mr.doob 已提交
1274
		program.uniforms = {};
1275
		program.attributes = {};
M
Mr.doob 已提交
1276

M
Mr.doob 已提交
1277
		return program;
M
Mr.doob 已提交
1278

M
Mr.doob 已提交
1279
	};
M
Mr.doob 已提交
1280

M
Mr.doob 已提交
1281
	function setUniforms( program, uniforms ) {
M
Mr.doob 已提交
1282

M
Mr.doob 已提交
1283
		var u, value, type, location, texture;
M
Mr.doob 已提交
1284

M
Mr.doob 已提交
1285
		for( u in uniforms ) {
M
Mr.doob 已提交
1286

M
Mr.doob 已提交
1287 1288 1289
			type = uniforms[u].type;
			value = uniforms[u].value;
			location = program.uniforms[u];
M
Mr.doob 已提交
1290

M
Mr.doob 已提交
1291
			if( type == "i" ) {
M
Mr.doob 已提交
1292

M
Mr.doob 已提交
1293
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
1294

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

M
Mr.doob 已提交
1297
				_gl.uniform1f( location, value );
1298

1299 1300 1301
			} else if( type == "v3" ) {

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

1303 1304 1305
			} else if( type == "c" ) {

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

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

M
Mr.doob 已提交
1309
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
1310

M
Mr.doob 已提交
1311
				texture = uniforms[u].texture;
M
Mr.doob 已提交
1312

1313
				if ( !texture ) continue;
M
Mr.doob 已提交
1314

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

1317
					setCubeTexture( texture, value );
M
Mr.doob 已提交
1318

1319
				} else {
M
Mr.doob 已提交
1320

1321
					setTexture( texture, value );
M
Mr.doob 已提交
1322

1323
				}
M
Mr.doob 已提交
1324

1325
			}
M
Mr.doob 已提交
1326

1327
		}
M
Mr.doob 已提交
1328

1329
	};
M
Mr.doob 已提交
1330

1331
	function setCubeTexture( texture, slot ) {
M
Mr.doob 已提交
1332

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

1335 1336
			if ( !texture.image.__webGLTextureCube &&
				 !texture.image.__cubeMapInitialized && texture.image.loadCount == 6 ) {
M
Mr.doob 已提交
1337

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

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

1342 1343
				_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 已提交
1344

1345 1346
				_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 已提交
1347

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

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

1352
				}
M
Mr.doob 已提交
1353

1354
				_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
1355

1356
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
M
Mr.doob 已提交
1357

1358
				texture.image.__cubeMapInitialized = true;
M
Mr.doob 已提交
1359

M
Mr.doob 已提交
1360
			}
1361 1362 1363

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

1365
		}
M
Mr.doob 已提交
1366

M
Mr.doob 已提交
1367
	};
M
Mr.doob 已提交
1368

1369
	function setTexture( texture, slot ) {
M
Mr.doob 已提交
1370

1371 1372 1373 1374 1375
		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 已提交
1376

1377 1378
			_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 已提交
1379 1380 1381

			_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 ) );
1382 1383 1384 1385 1386 1387 1388
			_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 已提交
1389

1390
	};
M
Mr.doob 已提交
1391

M
Mr.doob 已提交
1392
	function cacheUniformLocations( program, identifiers ) {
M
Mr.doob 已提交
1393

M
Mr.doob 已提交
1394
		var i, l, id;
M
Mr.doob 已提交
1395

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

1398 1399
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
1400

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

M
Mr.doob 已提交
1403
	};
M
Mr.doob 已提交
1404

1405
	function cacheAttributeLocations( program, identifiers ) {
1406

1407
		var i, l, id;
M
Mr.doob 已提交
1408

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

1411 1412
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
1413

1414
			if ( program.attributes[ id ] >= 0 ) {
M
Mr.doob 已提交
1415

1416
				_gl.enableVertexAttribArray( program.attributes[ id ] );
M
Mr.doob 已提交
1417

1418
			}
M
Mr.doob 已提交
1419

1420
		}
M
Mr.doob 已提交
1421

M
Mr.doob 已提交
1422
	};
M
Mr.doob 已提交
1423

M
Mr.doob 已提交
1424
	function initUbershader( maxDirLights, maxPointLights ) {
M
Mr.doob 已提交
1425

M
Mr.doob 已提交
1426
		var vertex_shader = generateVertexShader( maxDirLights, maxPointLights ),
1427 1428
			fragment_shader = generateFragmentShader( maxDirLights, maxPointLights ),
			program;
1429

M
Mr.doob 已提交
1430 1431
		//log ( vertex_shader );
		//log ( fragment_shader );
M
Mr.doob 已提交
1432

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

1435
		_gl.useProgram( program );
M
Mr.doob 已提交
1436

M
Mr.doob 已提交
1437 1438 1439 1440
		// matrices
		// lights
		// material properties (Basic / Lambert / Blinn-Phong shader)
		// material properties (Depth)
M
Mr.doob 已提交
1441

1442
		cacheUniformLocations( program, [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
M
Mr.doob 已提交
1443 1444 1445 1446 1447 1448
										   'enableLighting', 'ambientLightColor',
										   'material', 'mColor', 'mAmbient', 'mSpecular', 'mShininess', 'mOpacity',
										   'enableMap', 'tMap',
										   'enableCubeMap', 'tCube', 'mixEnvMap', 'mReflectivity',
										   'mRefractionRatio', 'useRefract',
										   'm2Near', 'mFarPlusNear', 'mFarMinusNear'
M
Mr.doob 已提交
1449
		] );
1450

M
Mr.doob 已提交
1451

M
Mr.doob 已提交
1452
		if ( maxDirLights ) {
M
Mr.doob 已提交
1453 1454

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

M
Mr.doob 已提交
1456
		}
1457

M
Mr.doob 已提交
1458
		if ( maxPointLights ) {
M
Mr.doob 已提交
1459

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

M
Mr.doob 已提交
1462
		}
M
Mr.doob 已提交
1463

M
Mr.doob 已提交
1464
		// texture (diffuse map)
M
Mr.doob 已提交
1465

1466 1467
		_gl.uniform1i( program.uniforms.enableMap, 0 );
		_gl.uniform1i( program.uniforms.tMap, 0 );
M
Mr.doob 已提交
1468

M
Mr.doob 已提交
1469
		// cube texture
M
Mr.doob 已提交
1470

1471 1472 1473
		_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 已提交
1474

M
Mr.doob 已提交
1475
		// refraction
M
Mr.doob 已提交
1476

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

1479
		// attribute arrays
M
Mr.doob 已提交
1480

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

1483
		return program;
N
Nicolas Garcia Belmonte 已提交
1484

1485
	};
N
Nicolas Garcia Belmonte 已提交
1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511

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

1513
	};
N
Nicolas Garcia Belmonte 已提交
1514

1515
	function paramThreeToGL( p ) {
M
Mr.doob 已提交
1516

1517
		switch ( p ) {
M
Mr.doob 已提交
1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530

			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;

1531
		}
M
Mr.doob 已提交
1532

1533
		return 0;
M
Mr.doob 已提交
1534

1535 1536 1537 1538 1539 1540
	};

	function materialNeedsSmoothNormals( material ) {

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

1541
	};
M
Mr.doob 已提交
1542

M
Mr.doob 已提交
1543
	function bufferNeedsSmoothNormals( geometryChunk, object ) {
M
Mr.doob 已提交
1544

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

1547 1548 1549 1550 1551 1552
		for ( m = 0, ml = object.material.length; m < ml; m++ ) {

			meshMaterial = object.material[ m ];

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

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

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

1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577
						needsSmoothNormals = true;
						break;

					}

				}

			} else {

				if ( materialNeedsSmoothNormals( meshMaterial ) ) {

					needsSmoothNormals = true;
					break;

				}

			}

			if ( needsSmoothNormals ) break;

		}
M
Mr.doob 已提交
1578

1579
		return needsSmoothNormals;
M
Mr.doob 已提交
1580

1581
	};
M
Mr.doob 已提交
1582

1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616
	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 已提交
1617

A
alteredq 已提交
1618
	/* DEBUG
1619
	function getGLParams() {
M
Mr.doob 已提交
1620

1621
		var params  = {
M
Mr.doob 已提交
1622

1623 1624
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
1625

1626 1627 1628
			'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 已提交
1629

1630 1631 1632
			'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 已提交
1633

1634 1635
		return params;
	};
M
Mr.doob 已提交
1636

1637
	function dumpObject( obj ) {
M
Mr.doob 已提交
1638

1639 1640
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
1641

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

1644
		}
M
Mr.doob 已提交
1645

1646 1647
		return str;
	}
A
alteredq 已提交
1648 1649
	*/

N
Nicolas Garcia Belmonte 已提交
1650
};