WebGLRenderer.js 113.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/
5
 * @author szimek / https://github.com/szimek/
N
Nicolas Garcia Belmonte 已提交
6 7
 */

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

M
Mr.doob 已提交
10 11
	// Currently you can use just up to 4 directional / point lights total.
	// Chrome barfs on shader linking when there are more than 4 lights :(
M
Mr.doob 已提交
12

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

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

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

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

23 24 25 26
	var _gl,
	_canvas = document.createElement( 'canvas' ),
	_currentProgram = null,
	_currentFramebuffer = null,
27
	_currentDepthMask = true,
M
Mr.doob 已提交
28

A
alteredq 已提交
29
	_this = this,
30

A
alteredq 已提交
31
	// gl state cache
32

33 34
	_oldDoubleSided = null,
	_oldFlipSided = null,
A
alteredq 已提交
35
	_oldBlending = null,
A
alteredq 已提交
36
	_oldDepth = null,
M
Mikael Emtinger 已提交
37
	_cullEnabled = true,
38

39 40 41 42 43
	_viewportX = 0,
	_viewportY = 0,
	_viewportWidth = 0,
	_viewportHeight = 0,

44
	// camera matrices caches
45 46

	_frustum = [
47 48 49 50 51 52 53 54
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4()
	 ],

55
	_projScreenMatrix = new THREE.Matrix4(),
56
	_projectionMatrixArray = new Float32Array( 16 ),
57
	_viewMatrixArray = new Float32Array( 16 ),
58

59
	_vector3 = new THREE.Vector4(),
60

A
alteredq 已提交
61
	// light arrays cache
62

A
alteredq 已提交
63 64
	_lights = {

65
		ambient: [ 0, 0, 0 ],
A
alteredq 已提交
66
		directional: { length: 0, colors: new Array(), positions: new Array() },
67
		point: { length: 0, colors: new Array(), positions: new Array(), distances: new Array() }
A
alteredq 已提交
68 69 70

	},

71
	// parameters defaults
M
Mr.doob 已提交
72

M
Mikael Emtinger 已提交
73
	stencil = true,
74 75 76
	antialias = true,
	clearColor = new THREE.Color( 0x000000 ),
	clearAlpha = 0;
77

78
	if ( parameters ) {
M
Mr.doob 已提交
79

M
Mikael Emtinger 已提交
80
		if ( parameters.stencil != undefined ) stencil = parameters.stencil;
81 82 83
		if ( parameters.antialias !== undefined ) antialias = parameters.antialias;
		if ( parameters.clearColor !== undefined ) clearColor.setHex( parameters.clearColor );
		if ( parameters.clearAlpha !== undefined ) clearAlpha = parameters.clearAlpha;
M
Mr.doob 已提交
84

85
	}
M
Mr.doob 已提交
86

87
	this.maxMorphTargets = 8;
N
Nicolas Garcia Belmonte 已提交
88 89
	this.domElement = _canvas;
	this.autoClear = true;
90
	this.sortObjects = true;
N
Nicolas Garcia Belmonte 已提交
91

M
Mikael Emtinger 已提交
92
	initGL( antialias, clearColor, clearAlpha, stencil );
M
Mr.doob 已提交
93

94 95
	this.context = _gl;

M
Mikael Emtinger 已提交
96

M
Mikael Emtinger 已提交
97
	// prepare stencil shadow polygon
M
Mikael Emtinger 已提交
98

M
Mr.doob 已提交
99 100
	if ( stencil ) {

M
Mikael Emtinger 已提交
101
		var _stencilShadow      = {};
M
Mr.doob 已提交
102

M
Mikael Emtinger 已提交
103 104 105
		_stencilShadow.vertices = new Float32Array( 12 );
		_stencilShadow.faces    = new Uint16Array( 6 );
		_stencilShadow.darkness = 0.5;
M
Mr.doob 已提交
106

M
Mikael Emtinger 已提交
107 108 109 110
		_stencilShadow.vertices[ 0 * 3 + 0 ] = -2; _stencilShadow.vertices[ 0 * 3 + 1 ] = -1; _stencilShadow.vertices[ 0 * 3 + 2 ] = -1;
		_stencilShadow.vertices[ 1 * 3 + 0 ] =  2; _stencilShadow.vertices[ 1 * 3 + 1 ] = -1; _stencilShadow.vertices[ 1 * 3 + 2 ] = -1;
		_stencilShadow.vertices[ 2 * 3 + 0 ] =  2; _stencilShadow.vertices[ 2 * 3 + 1 ] =  1; _stencilShadow.vertices[ 2 * 3 + 2 ] = -1;
		_stencilShadow.vertices[ 3 * 3 + 0 ] = -2; _stencilShadow.vertices[ 3 * 3 + 1 ] =  1; _stencilShadow.vertices[ 3 * 3 + 2 ] = -1;
M
Mr.doob 已提交
111

M
Mikael Emtinger 已提交
112 113
		_stencilShadow.faces[ 0 ] = 0; _stencilShadow.faces[ 1 ] = 1; _stencilShadow.faces[ 2 ] = 2;
		_stencilShadow.faces[ 3 ] = 0; _stencilShadow.faces[ 4 ] = 2; _stencilShadow.faces[ 5 ] = 3;
M
Mr.doob 已提交
114

M
Mikael Emtinger 已提交
115 116
		_stencilShadow.vertexBuffer  = _gl.createBuffer();
		_stencilShadow.elementBuffer = _gl.createBuffer();
M
Mr.doob 已提交
117

M
Mikael Emtinger 已提交
118 119
		_gl.bindBuffer( _gl.ARRAY_BUFFER, _stencilShadow.vertexBuffer );
		_gl.bufferData( _gl.ARRAY_BUFFER,  _stencilShadow.vertices, _gl.STATIC_DRAW );
M
Mr.doob 已提交
120

M
Mikael Emtinger 已提交
121 122
		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _stencilShadow.elementBuffer );
		_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _stencilShadow.faces, _gl.STATIC_DRAW );
M
Mr.doob 已提交
123

M
Mikael Emtinger 已提交
124
		_stencilShadow.program = _gl.createProgram();
M
Mr.doob 已提交
125

M
Mikael Emtinger 已提交
126 127
		_gl.attachShader( _stencilShadow.program, getShader( "fragment", THREE.ShaderLib.shadowPost.fragmentShader ));
		_gl.attachShader( _stencilShadow.program, getShader( "vertex",   THREE.ShaderLib.shadowPost.vertexShader   ));
M
Mr.doob 已提交
128

M
Mikael Emtinger 已提交
129
		_gl.linkProgram( _stencilShadow.program );
M
Mr.doob 已提交
130

M
Mikael Emtinger 已提交
131 132 133 134
		_stencilShadow.vertexLocation     = _gl.getAttribLocation ( _stencilShadow.program, "position"         );
		_stencilShadow.projectionLocation = _gl.getUniformLocation( _stencilShadow.program, "projectionMatrix" );
		_stencilShadow.darknessLocation   = _gl.getUniformLocation( _stencilShadow.program, "darkness"         );
	}
M
Mr.doob 已提交
135 136


M
Mikael Emtinger 已提交
137
	// prepare lens flare
M
Mr.doob 已提交
138

M
Mikael Emtinger 已提交
139 140
	var _lensFlare = {};
	var i;
M
Mr.doob 已提交
141

M
Mikael Emtinger 已提交
142 143 144
	_lensFlare.vertices     = new Float32Array( 8 + 8 );
	_lensFlare.faces        = new Uint16Array( 6 );
	_lensFlare.transparency = 0.5;
M
Mr.doob 已提交
145

M
Mikael Emtinger 已提交
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
	i = 0;
	_lensFlare.vertices[ i++ ] = -1; _lensFlare.vertices[ i++ ] = -1;	// vertex
	_lensFlare.vertices[ i++ ] = 0;  _lensFlare.vertices[ i++ ] = 0;	// uv... etc.
	_lensFlare.vertices[ i++ ] = 1;  _lensFlare.vertices[ i++ ] = -1;
	_lensFlare.vertices[ i++ ] = 1;  _lensFlare.vertices[ i++ ] = 0;
	_lensFlare.vertices[ i++ ] = 1;  _lensFlare.vertices[ i++ ] = 1;
	_lensFlare.vertices[ i++ ] = 1;  _lensFlare.vertices[ i++ ] = 1;
	_lensFlare.vertices[ i++ ] = -1; _lensFlare.vertices[ i++ ] = 1;
	_lensFlare.vertices[ i++ ] = 0;  _lensFlare.vertices[ i++ ] = 1;

	i = 0;
	_lensFlare.faces[ i++ ] = 0; _lensFlare.faces[ i++ ] = 1; _lensFlare.faces[ i++ ] = 2;
	_lensFlare.faces[ i++ ] = 0; _lensFlare.faces[ i++ ] = 2; _lensFlare.faces[ i++ ] = 3;

	_lensFlare.vertexBuffer  = _gl.createBuffer();
	_lensFlare.elementBuffer = _gl.createBuffer();
	_lensFlare.tempTexture   = _gl.createTexture();
163
	_lensFlare.readBackPixels = new Uint8Array( 16*16*4 );
M
Mr.doob 已提交
164

M
Mikael Emtinger 已提交
165 166
	_gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer );
	_gl.bufferData( _gl.ARRAY_BUFFER,  _lensFlare.vertices, _gl.STATIC_DRAW );
M
Mikael Emtinger 已提交
167

M
Mikael Emtinger 已提交
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
	_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.elementBuffer );
	_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.faces, _gl.STATIC_DRAW );

	_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
	_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGB, 16, 16, 0, _gl.RGB, _gl.UNSIGNED_BYTE, null );
	_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
	_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
	_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, _gl.NEAREST );
	_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.NEAREST );

	_lensFlare.program = _gl.createProgram();

	_gl.attachShader( _lensFlare.program, getShader( "fragment", THREE.ShaderLib.lensFlare.fragmentShader ));
	_gl.attachShader( _lensFlare.program, getShader( "vertex",   THREE.ShaderLib.lensFlare.vertexShader   ));

	_gl.linkProgram( _lensFlare.program );

	_lensFlare.attributes = {};
	_lensFlare.uniforms = {};
	_lensFlare.attributes.vertex       = _gl.getAttribLocation ( _lensFlare.program, "position" );
	_lensFlare.attributes.uv           = _gl.getAttribLocation ( _lensFlare.program, "UV" );
	_lensFlare.uniforms.map            = _gl.getUniformLocation( _lensFlare.program, "map" );
	_lensFlare.uniforms.opacity        = _gl.getUniformLocation( _lensFlare.program, "opacity" );
	_lensFlare.uniforms.scale          = _gl.getUniformLocation( _lensFlare.program, "scale" );
	_lensFlare.uniforms.rotation       = _gl.getUniformLocation( _lensFlare.program, "rotation" );
	_lensFlare.uniforms.screenPosition = _gl.getUniformLocation( _lensFlare.program, "screenPosition" );
	_lensFlare.uniforms.renderPink     = _gl.getUniformLocation( _lensFlare.program, "renderPink" );

M
Mikael Emtinger 已提交
196

N
Nicolas Garcia Belmonte 已提交
197 198 199 200
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
201

202 203 204
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
205

206
	this.setViewport = function ( x, y, width, height ) {
207

208 209
		_viewportX = x;
		_viewportY = y;
210

211 212
		_viewportWidth = width;
		_viewportHeight = height;
213

214
		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
215

N
Nicolas Garcia Belmonte 已提交
216
	};
217

218
	this.setScissor = function ( x, y, width, height ) {
N
Nicolas Garcia Belmonte 已提交
219

220
		_gl.scissor( x, y, width, height );
221

222
	};
223

224
	this.enableScissorTest = function ( enable ) {
225

226 227 228 229
		if ( enable )
			_gl.enable( _gl.SCISSOR_TEST );
		else
			_gl.disable( _gl.SCISSOR_TEST );
230

231
	};
232

233
	this.enableDepthBufferWrite = function ( enable ) {
234

235
		_currentDepthMask = enable;
236 237 238
		_gl.depthMask( enable );

	};
239

240
	this.setClearColorHex = function ( hex, alpha ) {
241

242 243
		var color = new THREE.Color( hex );
		_gl.clearColor( color.r, color.g, color.b, alpha );
244

245
	};
A
alteredq 已提交
246

247
	this.setClearColor = function ( color, alpha ) {
A
alteredq 已提交
248 249 250 251

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

	};
252

N
Nicolas Garcia Belmonte 已提交
253 254
	this.clear = function () {

M
Mikael Emtinger 已提交
255
		_gl.clear( _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT | _gl.STENCIL_BUFFER_BIT );
N
Nicolas Garcia Belmonte 已提交
256 257 258

	};

M
Mikael Emtinger 已提交
259 260 261 262 263
	this.setStencilShadowDarkness = function( value ) {
		
		_stencilShadow.darkness = value;
	};

M
Mr.doob 已提交
264

A
alteredq 已提交
265
	function setupLights ( program, lights ) {
266

267
		var l, ll, light, r = 0, g = 0, b = 0,
268
		color, position, intensity, distance,
M
Mr.doob 已提交
269

270
		zlights = _lights,
M
Mr.doob 已提交
271

272
		dcolors = zlights.directional.colors,
273
		dpositions = zlights.directional.positions,
274

275
		pcolors = zlights.point.colors,
276
		ppositions = zlights.point.positions,
277
		pdistances = zlights.point.distances,
278

279 280
		dlength = 0,
		plength = 0,
281

282 283
		doffset = 0,
		poffset = 0;
M
Mr.doob 已提交
284

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

287
			light = lights[ l ];
288
			color = light.color;
289

290 291
			position = light.position;
			intensity = light.intensity;
292
			distance = light.distance;
293 294 295

			if ( light instanceof THREE.AmbientLight ) {

296 297 298
				r += color.r;
				g += color.g;
				b += color.b;
M
Mr.doob 已提交
299

300
			} else if ( light instanceof THREE.DirectionalLight ) {
301

302
				doffset = dlength * 3;
303

304
				dcolors[ doffset ] = color.r * intensity;
305 306
				dcolors[ doffset + 1 ] = color.g * intensity;
				dcolors[ doffset + 2 ] = color.b * intensity;
307

308
				dpositions[ doffset ] = position.x;
309 310
				dpositions[ doffset + 1 ] = position.y;
				dpositions[ doffset + 2 ] = position.z;
311

312
				dlength += 1;
M
Mr.doob 已提交
313

314 315
			} else if( light instanceof THREE.PointLight ) {

316
				poffset = plength * 3;
317

318
				pcolors[ poffset ] = color.r * intensity;
319 320
				pcolors[ poffset + 1 ] = color.g * intensity;
				pcolors[ poffset + 2 ] = color.b * intensity;
321

322
				ppositions[ poffset ] = position.x;
323 324
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
M
Mr.doob 已提交
325

326 327
				pdistances[ plength ] = distance;

328
				plength += 1;
M
Mr.doob 已提交
329

330 331 332
			}

		}
333

334 335
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
336

337 338
		for( l = dlength * 3; l < dcolors.length; l++ ) dcolors[ l ] = 0.0;
		for( l = plength * 3; l < pcolors.length; l++ ) pcolors[ l ] = 0.0;
M
Mr.doob 已提交
339

340 341
		zlights.point.length = plength;
		zlights.directional.length = dlength;
M
Mr.doob 已提交
342

343 344 345
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
M
Mr.doob 已提交
346

347
	};
M
Mr.doob 已提交
348

349
	function createParticleBuffers ( geometry ) {
M
Mr.doob 已提交
350

351 352
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
353

354
	};
M
Mr.doob 已提交
355

356
	function createLineBuffers( geometry ) {
M
Mr.doob 已提交
357

358 359
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
360

361
	};
362

363
	function createRibbonBuffers( geometry ) {
A
alteredq 已提交
364

365 366
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
A
alteredq 已提交
367 368 369

	};

370
	function createMeshBuffers( geometryGroup ) {
M
Mr.doob 已提交
371

372 373 374 375 376 377
		geometryGroup.__webglVertexBuffer = _gl.createBuffer();
		geometryGroup.__webglNormalBuffer = _gl.createBuffer();
		geometryGroup.__webglTangentBuffer = _gl.createBuffer();
		geometryGroup.__webglColorBuffer = _gl.createBuffer();
		geometryGroup.__webglUVBuffer = _gl.createBuffer();
		geometryGroup.__webglUV2Buffer = _gl.createBuffer();
378

379 380 381 382 383 384 385 386 387
		geometryGroup.__webglSkinVertexABuffer = _gl.createBuffer();
		geometryGroup.__webglSkinVertexBBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinIndicesBuffer = _gl.createBuffer();
		geometryGroup.__webglSkinWeightsBuffer = _gl.createBuffer();

		geometryGroup.__webglFaceBuffer = _gl.createBuffer();
		geometryGroup.__webglLineBuffer = _gl.createBuffer();

		if ( geometryGroup.numMorphTargets ) {
388

389
			var m, ml;
390 391 392 393 394 395
			geometryGroup.__webglMorphTargetsBuffers = []; 

			for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m++ ) {

				geometryGroup.__webglMorphTargetsBuffers.push( _gl.createBuffer() );

396 397 398
			}

		}
M
Mr.doob 已提交
399

400
	};
401

402
	function initLineBuffers ( geometry ) {
M
Mr.doob 已提交
403

404 405 406
		var nvertices = geometry.vertices.length;

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

409
		geometry.__webglLineCount = nvertices;
M
Mr.doob 已提交
410

411
	};
M
Mr.doob 已提交
412

413
	function initRibbonBuffers ( geometry ) {
A
alteredq 已提交
414 415 416 417 418 419

		var nvertices = geometry.vertices.length;

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

420
		geometry.__webglVertexCount = nvertices;
A
alteredq 已提交
421 422

	};
423

424
	function initParticleBuffers ( geometry ) {
425 426 427 428

		var nvertices = geometry.vertices.length;

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

431
		geometry.__sortArray = [];
432

433
		geometry.__webglParticleCount = nvertices;
434 435 436

	};

437
	function initMeshBuffers ( geometryGroup, object ) {
M
Mr.doob 已提交
438

M
Mikael Emtinger 已提交
439
		var f, fl, fi, face,
440
		m, ml, size,
441 442 443 444 445 446
		nvertices = 0, ntris = 0, nlines = 0,

		uvType,
		vertexColorType,
		normalType,
		materials,
447
		attribute,
448 449 450 451

		geometry = object.geometry,
		obj_faces = geometry.faces,
		chunk_faces = geometryGroup.faces;
M
Mr.doob 已提交
452

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

455 456
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
M
Mr.doob 已提交
457

458
			if ( face instanceof THREE.Face3 ) {
M
Mr.doob 已提交
459

460 461 462
				nvertices += 3;
				ntris += 1;
				nlines += 3;
M
Mr.doob 已提交
463

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

466 467
				nvertices += 4;
				ntris += 2;
468
				nlines += 4;
M
Mr.doob 已提交
469

470
			}
M
Mr.doob 已提交
471

472
		}
473 474 475

		materials = unrollGroupMaterials( geometryGroup, object );

476 477
		uvType = bufferGuessUVType( materials, geometryGroup, object );
		normalType = bufferGuessNormalType( materials, geometryGroup, object );
A
alteredq 已提交
478 479
		vertexColorType = bufferGuessVertexColorType( materials, geometryGroup, object );

480
		//console.log("uvType",uvType, "normalType",normalType, "vertexColorType",vertexColorType, object, geometryGroup, materials );
M
Mr.doob 已提交
481

482
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
483

484
		if ( normalType ) {
M
Mr.doob 已提交
485

486
			geometryGroup.__normalArray = new Float32Array( nvertices * 3 );
M
Mr.doob 已提交
487

488
		}
489

490
		if ( geometry.hasTangents ) {
491

492
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
493

494
		}
495

496
		if ( vertexColorType ) {
497

498
			geometryGroup.__colorArray = new Float32Array( nvertices * 3 );
M
Mr.doob 已提交
499

500
		}
M
Mr.doob 已提交
501

502
		if ( uvType ) {
503

504
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
505

506 507 508 509 510
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

			if ( geometry.faceUvs.length > 1 || geometry.faceVertexUvs.length > 1 ) {
511

512 513 514 515 516 517 518 519 520 521 522 523 524 525 526
				geometryGroup.__uv2Array = new Float32Array( nvertices * 2 );

			}

		}

		if ( object.geometry.skinWeights.length && object.geometry.skinIndices.length ) {

			geometryGroup.__skinVertexAArray = new Float32Array( nvertices * 4 );
			geometryGroup.__skinVertexBArray = new Float32Array( nvertices * 4 );
			geometryGroup.__skinIndexArray = new Float32Array( nvertices * 4 );
			geometryGroup.__skinWeightArray = new Float32Array( nvertices * 4 );

		}

M
Mikael Emtinger 已提交
527
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 + ( object.geometry.edgeFaces ? object.geometry.edgeFaces.length * 2 * 3 : 0 ));
528
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
529

530 531
		if ( geometryGroup.numMorphTargets ) {

532
			geometryGroup.__morphTargetsArrays = []; 
533 534 535

			for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m++ ) {

536 537
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );

538 539 540
			}

		}
541

542
		geometryGroup.__needsSmoothNormals = ( normalType == THREE.SmoothShading );
543

544 545 546 547
		geometryGroup.__uvType = uvType;
		geometryGroup.__vertexColorType = vertexColorType;
		geometryGroup.__normalType = normalType;

548 549
		geometryGroup.__webglFaceCount = ntris * 3 + ( object.geometry.edgeFaces ? object.geometry.edgeFaces.length * 2 * 3 : 0 );
		geometryGroup.__webglLineCount = nlines * 2;
550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582
		
		
		// custom attributes
		
		for( m = 0, ml = materials.length; m < ml; m++ ) {
			
			if( materials[ m ].attributes ) {
				
				geometryGroup.__webglCustomAttributes = {};

				for( a in materials[ m ].attributes ) {
					
					attribute = materials[ m ].attributes[ a ];
					
					size = 1;		// "f" and "i"
					
					     if( attribute.type === "v2" ) size = 2;
					else if( attribute.type === "v3" ) size = 3;
					else if( attribute.type === "v4" ) size = 4;
					else if( attribute.type === "c"  ) size = 3;
					
					attribute.size = size;
					attribute.dirty = true;
					attribute.array = new Float32Array( nvertices * size );
					attribute.buffer = _gl.createBuffer();

					geometryGroup.__webglCustomAttributes[ a ] = attribute;

				}

			}
		
		}
583

584
	};
M
Mr.doob 已提交
585

586

587
	function setMeshBuffers ( geometryGroup, object, hint ) {
588

589
		var f, fl, fi, face, 
590 591 592 593 594 595 596 597 598 599 600 601 602
		vertexNormals, faceNormal, normal,
		vertexColors, faceColor,
		vertexTangents,
		uvType, vertexColorType, normalType,
		uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4,
		c1, c2, c3, c4,
		sw1, sw2, sw3, sw4,
		si1, si2, si3, si4,
		sa1, sa2, sa3, sa4,
		sb1, sb2, sb3, sb4,
		m, ml, i,
		vn, uvi, uv2i,
		vk, vkl, vka,
603
		a,
M
Mr.doob 已提交
604

605
		vertexIndex = 0,
606

607 608
		offset = 0,
		offset_uv = 0,
609
		offset_uv2 = 0,
610 611 612 613
		offset_face = 0,
		offset_normal = 0,
		offset_tangent = 0,
		offset_line = 0,
614
		offset_color = 0,
A
alteredq 已提交
615
		offset_skin = 0,
616
		offset_morphTarget = 0,
617
		offset_custom = 0,
M
Mr.doob 已提交
618

619 620 621 622 623 624
		vertexArray = geometryGroup.__vertexArray,
		uvArray = geometryGroup.__uvArray,
		uv2Array = geometryGroup.__uv2Array,
		normalArray = geometryGroup.__normalArray,
		tangentArray = geometryGroup.__tangentArray,
		colorArray = geometryGroup.__colorArray,
625

626 627 628 629
		skinVertexAArray = geometryGroup.__skinVertexAArray,
		skinVertexBArray = geometryGroup.__skinVertexBArray,
		skinIndexArray = geometryGroup.__skinIndexArray,
		skinWeightArray = geometryGroup.__skinWeightArray,
M
Mr.doob 已提交
630

631
		morphTargetsArrays = geometryGroup.__morphTargetsArrays,
632 633 634
		
		customAttributes = geometryGroup.__webglCustomAttributes,
		customAttribute,
635

636 637
		faceArray = geometryGroup.__faceArray,
		lineArray = geometryGroup.__lineArray,
M
Mr.doob 已提交
638

639
		needsSmoothNormals = geometryGroup.__needsSmoothNormals,
640

641
		vertexColorType = geometryGroup.__vertexColorType,
A
alteredq 已提交
642 643
		uvType = geometryGroup.__uvType,
		normalType = geometryGroup.__normalType,
644

645
		geometry = object.geometry, // this is shared for all chunks
646

647
		dirtyVertices = geometry.__dirtyVertices,
648 649 650
		dirtyElements = geometry.__dirtyElements,
		dirtyUvs = geometry.__dirtyUvs,
		dirtyNormals = geometry.__dirtyNormals,
651
		dirtyTangents = geometry.__dirtyTangents,
652
		dirtyColors = geometry.__dirtyColors,
653
		dirtyMorphTargets = geometry.__dirtyMorphTargets,
M
Mr.doob 已提交
654

655
		vertices = geometry.vertices,
656
		chunk_faces = geometryGroup.faces,
657
		obj_faces = geometry.faces,
658

659 660
		obj_uvs  = geometry.faceVertexUvs[ 0 ],
		obj_uvs2 = geometry.faceVertexUvs[ 1 ],
661

A
alteredq 已提交
662
		obj_colors = geometry.colors,
663

A
alteredq 已提交
664 665 666
		obj_skinVerticesA = geometry.skinVerticesA,
		obj_skinVerticesB = geometry.skinVerticesB,
		obj_skinIndices = geometry.skinIndices,
667
		obj_skinWeights = geometry.skinWeights,
M
Mikael Emtinger 已提交
668
		obj_edgeFaces = geometry.edgeFaces,
669 670

		morphTargets = geometry.morphTargets;
671

672 673 674 675 676 677 678 679 680 681 682 683
		if ( customAttributes ) {
			
			for ( a in customAttributes ) {
				
				customAttributes[ a ].offset = 0;
				
			}
			
		}



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

686 687
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
688 689

			if ( obj_uvs ) {
A
alteredq 已提交
690 691 692 693

				uv = obj_uvs[ fi ];

			}
694 695 696

			if ( obj_uvs2 ) {

A
alteredq 已提交
697 698 699
				uv2 = obj_uvs2[ fi ];

			}
M
Mr.doob 已提交
700

701
			vertexNormals = face.vertexNormals;
702
			faceNormal = face.normal;
703

704 705
			vertexColors = face.vertexColors;
			faceColor = face.color;
706

707
			vertexTangents = face.vertexTangents;
708 709 710

			if ( face instanceof THREE.Face3 ) {

711
				if ( dirtyVertices ) {
M
Mr.doob 已提交
712

713 714 715
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
M
Mr.doob 已提交
716

717 718 719
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
720

721 722 723
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
724

725 726 727
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
M
Mr.doob 已提交
728

729
					offset += 9;
M
Mr.doob 已提交
730

731
				}
732

733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809
				if ( customAttributes ) {
					
					for ( a in customAttributes ) {
						
						customAttribute = customAttributes[ a ];

						if ( customAttribute.dirty ) {
							
							offset_custom = customAttribute.offset;
							
							if( customAttribute.size === 1 ) {
								
								customAttribute.array[ offset_custom + 0 ] = customAttribute.value[ face.a ];								
								customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];								
								customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];								
								
								customAttribute.offset += 3;
								
							} else {
								
								v1 = customAttribute.value[ face.a ];
								v2 = customAttribute.value[ face.b ];
								v3 = customAttribute.value[ face.c ];
								
								if( customAttribute.size === 2 ) {
									
									customAttribute.array[ offset_custom + 0 ] = v1.x;								
									customAttribute.array[ offset_custom + 1 ] = v1.y;								
									customAttribute.array[ offset_custom + 2 ] = v2.x;								
									customAttribute.array[ offset_custom + 3 ] = v2.y;								
									customAttribute.array[ offset_custom + 4 ] = v3.x;								
									customAttribute.array[ offset_custom + 5 ] = v3.y;
									
									customAttribute.offset += 6;
									
								} else if( customAttribute.size === 3 ) {
									
									customAttribute.array[ offset_custom + 0 ] = v1.x;								
									customAttribute.array[ offset_custom + 1 ] = v1.y;								
									customAttribute.array[ offset_custom + 2 ] = v1.z;								
									customAttribute.array[ offset_custom + 3 ] = v2.x;								
									customAttribute.array[ offset_custom + 4 ] = v2.y;								
									customAttribute.array[ offset_custom + 5 ] = v2.z;								
									customAttribute.array[ offset_custom + 6 ] = v3.x;								
									customAttribute.array[ offset_custom + 7 ] = v3.y;
									customAttribute.array[ offset_custom + 8 ] = v3.z;
									
									customAttribute.offset += 9;
									
								} else {
									
									customAttribute.array[ offset_custom + 0  ] = v1.x;								
									customAttribute.array[ offset_custom + 1  ] = v1.y;								
									customAttribute.array[ offset_custom + 2  ] = v1.z;								
									customAttribute.array[ offset_custom + 3  ] = v1.w;								
									customAttribute.array[ offset_custom + 4  ] = v2.x;								
									customAttribute.array[ offset_custom + 5  ] = v2.y;								
									customAttribute.array[ offset_custom + 6  ] = v2.z;								
									customAttribute.array[ offset_custom + 7  ] = v2.w;								
									customAttribute.array[ offset_custom + 8  ] = v3.x;								
									customAttribute.array[ offset_custom + 9  ] = v3.y;
									customAttribute.array[ offset_custom + 10 ] = v3.z;
									customAttribute.array[ offset_custom + 11 ] = v3.w;
									
									customAttribute.offset += 12;
									
								}
								
							}
							
						}
						
					}
					
				}


810
				if ( dirtyMorphTargets ) {
811 812 813

					for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {

814 815 816
						v1 = morphTargets[ vk ].vertices[ face.a ].position;
						v2 = morphTargets[ vk ].vertices[ face.b ].position;
						v3 = morphTargets[ vk ].vertices[ face.c ].position;
817

818
						vka = morphTargetsArrays[ vk ];
819

820 821 822
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
823

824 825 826
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
827

828 829 830
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
831 832
					}

833
					offset_morphTarget += 9;
834

835 836
				}

A
alteredq 已提交
837 838 839
				if ( obj_skinWeights.length ) {

					// weights
840

A
alteredq 已提交
841 842 843
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
844

A
alteredq 已提交
845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860
					skinWeightArray[ offset_skin ]     = sw1.x;
					skinWeightArray[ offset_skin + 1 ] = sw1.y;
					skinWeightArray[ offset_skin + 2 ] = sw1.z;
					skinWeightArray[ offset_skin + 3 ] = sw1.w;

					skinWeightArray[ offset_skin + 4 ] = sw2.x;
					skinWeightArray[ offset_skin + 5 ] = sw2.y;
					skinWeightArray[ offset_skin + 6 ] = sw2.z;
					skinWeightArray[ offset_skin + 7 ] = sw2.w;

					skinWeightArray[ offset_skin + 8 ]  = sw3.x;
					skinWeightArray[ offset_skin + 9 ]  = sw3.y;
					skinWeightArray[ offset_skin + 10 ] = sw3.z;
					skinWeightArray[ offset_skin + 11 ] = sw3.w;

					// indices
861

A
alteredq 已提交
862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881
					si1 = obj_skinIndices[ face.a ];
					si2 = obj_skinIndices[ face.b ];
					si3 = obj_skinIndices[ face.c ];

					skinIndexArray[ offset_skin ]     = si1.x;
					skinIndexArray[ offset_skin + 1 ] = si1.y;
					skinIndexArray[ offset_skin + 2 ] = si1.z;
					skinIndexArray[ offset_skin + 3 ] = si1.w;

					skinIndexArray[ offset_skin + 4 ] = si2.x;
					skinIndexArray[ offset_skin + 5 ] = si2.y;
					skinIndexArray[ offset_skin + 6 ] = si2.z;
					skinIndexArray[ offset_skin + 7 ] = si2.w;

					skinIndexArray[ offset_skin + 8 ]  = si3.x;
					skinIndexArray[ offset_skin + 9 ]  = si3.y;
					skinIndexArray[ offset_skin + 10 ] = si3.z;
					skinIndexArray[ offset_skin + 11 ] = si3.w;

					// vertices A
882

A
alteredq 已提交
883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902
					sa1 = obj_skinVerticesA[ face.a ];
					sa2 = obj_skinVerticesA[ face.b ];
					sa3 = obj_skinVerticesA[ face.c ];

					skinVertexAArray[ offset_skin ]     = sa1.x;
					skinVertexAArray[ offset_skin + 1 ] = sa1.y;
					skinVertexAArray[ offset_skin + 2 ] = sa1.z;
					skinVertexAArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader

					skinVertexAArray[ offset_skin + 4 ] = sa2.x;
					skinVertexAArray[ offset_skin + 5 ] = sa2.y;
					skinVertexAArray[ offset_skin + 6 ] = sa2.z;
					skinVertexAArray[ offset_skin + 7 ] = 1;

					skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
					skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
					skinVertexAArray[ offset_skin + 10 ] = sa3.z;
					skinVertexAArray[ offset_skin + 11 ] = 1;

					// vertices B
903

A
alteredq 已提交
904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923
					sb1 = obj_skinVerticesB[ face.a ];
					sb2 = obj_skinVerticesB[ face.b ];
					sb3 = obj_skinVerticesB[ face.c ];

					skinVertexBArray[ offset_skin ]     = sb1.x;
					skinVertexBArray[ offset_skin + 1 ] = sb1.y;
					skinVertexBArray[ offset_skin + 2 ] = sb1.z;
					skinVertexBArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader

					skinVertexBArray[ offset_skin + 4 ] = sb2.x;
					skinVertexBArray[ offset_skin + 5 ] = sb2.y;
					skinVertexBArray[ offset_skin + 6 ] = sb2.z;
					skinVertexBArray[ offset_skin + 7 ] = 1;

					skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
					skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
					skinVertexBArray[ offset_skin + 10 ] = sb3.z;
					skinVertexBArray[ offset_skin + 11 ] = 1;

					offset_skin += 12;
924

A
alteredq 已提交
925
				}
926

927 928 929
				if ( dirtyColors && vertexColorType ) {

					if ( vertexColors.length == 3 && vertexColorType == THREE.VertexColors ) {
930

931 932 933 934 935
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];

					} else {
936

937 938 939 940 941
						c1 = faceColor;
						c2 = faceColor;
						c3 = faceColor;

					}
942 943 944 945 946 947 948 949 950 951 952 953

					colorArray[ offset_color ]     = c1.r;
					colorArray[ offset_color + 1 ] = c1.g;
					colorArray[ offset_color + 2 ] = c1.b;

					colorArray[ offset_color + 3 ] = c2.r;
					colorArray[ offset_color + 4 ] = c2.g;
					colorArray[ offset_color + 5 ] = c2.b;

					colorArray[ offset_color + 6 ] = c3.r;
					colorArray[ offset_color + 7 ] = c3.g;
					colorArray[ offset_color + 8 ] = c3.b;
954

955 956 957 958
					offset_color += 9;

				}

959
				if ( dirtyTangents && geometry.hasTangents ) {
960

961 962 963
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
964

965 966 967 968
					tangentArray[ offset_tangent ]     = t1.x;
					tangentArray[ offset_tangent + 1 ] = t1.y;
					tangentArray[ offset_tangent + 2 ] = t1.z;
					tangentArray[ offset_tangent + 3 ] = t1.w;
M
Mr.doob 已提交
969

970 971 972 973
					tangentArray[ offset_tangent + 4 ] = t2.x;
					tangentArray[ offset_tangent + 5 ] = t2.y;
					tangentArray[ offset_tangent + 6 ] = t2.z;
					tangentArray[ offset_tangent + 7 ] = t2.w;
M
Mr.doob 已提交
974

975 976 977 978
					tangentArray[ offset_tangent + 8 ]  = t3.x;
					tangentArray[ offset_tangent + 9 ]  = t3.y;
					tangentArray[ offset_tangent + 10 ] = t3.z;
					tangentArray[ offset_tangent + 11 ] = t3.w;
M
Mr.doob 已提交
979

980
					offset_tangent += 12;
M
Mr.doob 已提交
981

982 983
				}

A
alteredq 已提交
984
				if ( dirtyNormals && normalType ) {
M
Mr.doob 已提交
985

986 987 988
					if ( vertexNormals.length == 3 && needsSmoothNormals ) {

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

990
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
991

992 993 994
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
995

996
							offset_normal += 3;
M
Mr.doob 已提交
997

998
						}
M
Mr.doob 已提交
999

1000
					} else {
1001

1002
						for ( i = 0; i < 3; i ++ ) {
1003

1004 1005 1006
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1007

1008
							offset_normal += 3;
M
Mr.doob 已提交
1009

1010
						}
M
Mr.doob 已提交
1011 1012

					}
M
Mr.doob 已提交
1013

1014 1015
				}

A
alteredq 已提交
1016
				if ( dirtyUvs && uv !== undefined && uvType ) {
1017

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

1020
						uvi = uv[ i ];
M
Mr.doob 已提交
1021

1022 1023
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1024

1025
						offset_uv += 2;
M
Mr.doob 已提交
1026

M
Mr.doob 已提交
1027
					}
1028 1029 1030

				}

A
alteredq 已提交
1031
				if ( dirtyUvs && uv2 !== undefined && uvType ) {
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045

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

						uv2i = uv2[ i ];

						uv2Array[ offset_uv2 ]     = uv2i.u;
						uv2Array[ offset_uv2 + 1 ] = uv2i.v;

						offset_uv2 += 2;

					}

				}

1046
				if ( dirtyElements ) {
M
Mr.doob 已提交
1047

1048 1049 1050
					faceArray[ offset_face ] = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
M
Mr.doob 已提交
1051

1052
					offset_face += 3;
M
Mr.doob 已提交
1053

1054 1055
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
1056

1057 1058
					lineArray[ offset_line + 2 ] = vertexIndex;
					lineArray[ offset_line + 3 ] = vertexIndex + 2;
M
Mr.doob 已提交
1059

1060 1061
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
1062

1063
					offset_line += 6;
1064

1065
					vertexIndex += 3;
M
Mr.doob 已提交
1066

1067
				}
M
Mr.doob 已提交
1068

1069 1070 1071

			} else if ( face instanceof THREE.Face4 ) {

1072
				if ( dirtyVertices ) {
M
Mr.doob 已提交
1073

1074 1075 1076 1077
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
					v4 = vertices[ face.d ].position;
M
Mr.doob 已提交
1078

1079 1080 1081
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
1082

1083 1084 1085
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
1086

1087 1088 1089
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
1090

1091 1092 1093
					vertexArray[ offset + 9 ] = v4.x;
					vertexArray[ offset + 10 ] = v4.y;
					vertexArray[ offset + 11 ] = v4.z;
M
Mr.doob 已提交
1094

1095
					offset += 12;
M
Mr.doob 已提交
1096

1097
				}
1098

1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186
				if ( customAttributes ) {
					
					for ( a in customAttributes ) {
						
						customAttribute = customAttributes[ a ];

						if ( customAttribute.dirty ) {

							offset_custom = customAttribute.offset;
							
							if( customAttribute.size === 1 ) {
								
								customAttribute.array[ offset_custom + 0 ] = customAttribute.value[ face.a ];								
								customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];								
								customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];								
								customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.d ];								
								
								customAttribute.offset += 4;
								
							} else {
								
								v1 = customAttribute.value[ face.a ];
								v2 = customAttribute.value[ face.b ];
								v3 = customAttribute.value[ face.c ];
								v4 = customAttribute.value[ face.d ];
								
								if( customAttribute.size === 2 ) {
									
									customAttribute.array[ offset_custom + 0 ] = v1.x;								
									customAttribute.array[ offset_custom + 1 ] = v1.y;								
									customAttribute.array[ offset_custom + 2 ] = v2.x;								
									customAttribute.array[ offset_custom + 3 ] = v2.y;								
									customAttribute.array[ offset_custom + 4 ] = v3.x;								
									customAttribute.array[ offset_custom + 5 ] = v3.y;
									customAttribute.array[ offset_custom + 6 ] = v4.x;								
									customAttribute.array[ offset_custom + 7 ] = v4.y;
									
									customAttribute.offset += 8;
									
								} else if( customAttribute.size === 3 ) {
									
									customAttribute.array[ offset_custom + 0  ] = v1.x;								
									customAttribute.array[ offset_custom + 1  ] = v1.y;								
									customAttribute.array[ offset_custom + 2  ] = v1.z;								
									customAttribute.array[ offset_custom + 3  ] = v2.x;								
									customAttribute.array[ offset_custom + 4  ] = v2.y;								
									customAttribute.array[ offset_custom + 5  ] = v2.z;								
									customAttribute.array[ offset_custom + 6  ] = v3.x;								
									customAttribute.array[ offset_custom + 7  ] = v3.y;
									customAttribute.array[ offset_custom + 8  ] = v3.z;
									customAttribute.array[ offset_custom + 9  ] = v4.x;								
									customAttribute.array[ offset_custom + 10 ] = v4.y;
									customAttribute.array[ offset_custom + 11 ] = v4.z;
									
									customAttribute.offset += 12;
									
								} else {
									
									customAttribute.array[ offset_custom + 0  ] = v1.x;								
									customAttribute.array[ offset_custom + 1  ] = v1.y;								
									customAttribute.array[ offset_custom + 2  ] = v1.z;								
									customAttribute.array[ offset_custom + 3  ] = v1.w;								
									customAttribute.array[ offset_custom + 4  ] = v2.x;								
									customAttribute.array[ offset_custom + 5  ] = v2.y;								
									customAttribute.array[ offset_custom + 6  ] = v2.z;								
									customAttribute.array[ offset_custom + 7  ] = v2.w;								
									customAttribute.array[ offset_custom + 8  ] = v3.x;								
									customAttribute.array[ offset_custom + 9  ] = v3.y;
									customAttribute.array[ offset_custom + 10 ] = v3.z;
									customAttribute.array[ offset_custom + 11 ] = v3.w;
									customAttribute.array[ offset_custom + 12 ] = v4.x;								
									customAttribute.array[ offset_custom + 13 ] = v4.y;
									customAttribute.array[ offset_custom + 14 ] = v4.z;
									customAttribute.array[ offset_custom + 15 ] = v4.w;
									
									customAttribute.offset += 16;
									
								}
								
							}
							
						}
						
					}
					
				}


1187
				if ( dirtyMorphTargets ) {
1188 1189 1190

					for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk++ ) {

1191 1192 1193 1194
						v1 = morphTargets[ vk ].vertices[ face.a ].position;
						v2 = morphTargets[ vk ].vertices[ face.b ].position;
						v3 = morphTargets[ vk ].vertices[ face.c ].position;
						v4 = morphTargets[ vk ].vertices[ face.d ].position;
1195

1196
						vka = morphTargetsArrays[ vk ];
1197

1198 1199 1200
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
1201

1202 1203 1204
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
1205

1206 1207 1208
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
1209

1210 1211 1212
						vka[ offset_morphTarget + 9 ] = v4.x;
						vka[ offset_morphTarget + 10 ] = v4.y;
						vka[ offset_morphTarget + 11 ] = v4.z;
1213 1214
					}

1215
					offset_morphTarget += 12;
1216

1217 1218
				}

A
alteredq 已提交
1219 1220 1221
				if ( obj_skinWeights.length ) {

					// weights
1222

A
alteredq 已提交
1223 1224 1225 1226
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
					sw4 = obj_skinWeights[ face.d ];
1227

A
alteredq 已提交
1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248
					skinWeightArray[ offset_skin ]     = sw1.x;
					skinWeightArray[ offset_skin + 1 ] = sw1.y;
					skinWeightArray[ offset_skin + 2 ] = sw1.z;
					skinWeightArray[ offset_skin + 3 ] = sw1.w;

					skinWeightArray[ offset_skin + 4 ] = sw2.x;
					skinWeightArray[ offset_skin + 5 ] = sw2.y;
					skinWeightArray[ offset_skin + 6 ] = sw2.z;
					skinWeightArray[ offset_skin + 7 ] = sw2.w;

					skinWeightArray[ offset_skin + 8 ]  = sw3.x;
					skinWeightArray[ offset_skin + 9 ]  = sw3.y;
					skinWeightArray[ offset_skin + 10 ] = sw3.z;
					skinWeightArray[ offset_skin + 11 ] = sw3.w;

					skinWeightArray[ offset_skin + 12 ] = sw4.x;
					skinWeightArray[ offset_skin + 13 ] = sw4.y;
					skinWeightArray[ offset_skin + 14 ] = sw4.z;
					skinWeightArray[ offset_skin + 15 ] = sw4.w;

					// indices
1249

A
alteredq 已提交
1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275
					si1 = obj_skinIndices[ face.a ];
					si2 = obj_skinIndices[ face.b ];
					si3 = obj_skinIndices[ face.c ];
					si4 = obj_skinIndices[ face.d ];

					skinIndexArray[ offset_skin ]     = si1.x;
					skinIndexArray[ offset_skin + 1 ] = si1.y;
					skinIndexArray[ offset_skin + 2 ] = si1.z;
					skinIndexArray[ offset_skin + 3 ] = si1.w;

					skinIndexArray[ offset_skin + 4 ] = si2.x;
					skinIndexArray[ offset_skin + 5 ] = si2.y;
					skinIndexArray[ offset_skin + 6 ] = si2.z;
					skinIndexArray[ offset_skin + 7 ] = si2.w;

					skinIndexArray[ offset_skin + 8 ]  = si3.x;
					skinIndexArray[ offset_skin + 9 ]  = si3.y;
					skinIndexArray[ offset_skin + 10 ] = si3.z;
					skinIndexArray[ offset_skin + 11 ] = si3.w;

					skinIndexArray[ offset_skin + 12 ] = si4.x;
					skinIndexArray[ offset_skin + 13 ] = si4.y;
					skinIndexArray[ offset_skin + 14 ] = si4.z;
					skinIndexArray[ offset_skin + 15 ] = si4.w;

					// vertices A
1276

A
alteredq 已提交
1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302
					sa1 = obj_skinVerticesA[ face.a ];
					sa2 = obj_skinVerticesA[ face.b ];
					sa3 = obj_skinVerticesA[ face.c ];
					sa4 = obj_skinVerticesA[ face.d ];

					skinVertexAArray[ offset_skin ]     = sa1.x;
					skinVertexAArray[ offset_skin + 1 ] = sa1.y;
					skinVertexAArray[ offset_skin + 2 ] = sa1.z;
					skinVertexAArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader

					skinVertexAArray[ offset_skin + 4 ] = sa2.x;
					skinVertexAArray[ offset_skin + 5 ] = sa2.y;
					skinVertexAArray[ offset_skin + 6 ] = sa2.z;
					skinVertexAArray[ offset_skin + 7 ] = 1;

					skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
					skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
					skinVertexAArray[ offset_skin + 10 ] = sa3.z;
					skinVertexAArray[ offset_skin + 11 ] = 1;

					skinVertexAArray[ offset_skin + 12 ] = sa4.x;
					skinVertexAArray[ offset_skin + 13 ] = sa4.y;
					skinVertexAArray[ offset_skin + 14 ] = sa4.z;
					skinVertexAArray[ offset_skin + 15 ] = 1;

					// vertices B
1303

A
alteredq 已提交
1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328
					sb1 = obj_skinVerticesB[ face.a ];
					sb2 = obj_skinVerticesB[ face.b ];
					sb3 = obj_skinVerticesB[ face.c ];
					sb4 = obj_skinVerticesB[ face.d ];

					skinVertexBArray[ offset_skin ]     = sb1.x;
					skinVertexBArray[ offset_skin + 1 ] = sb1.y;
					skinVertexBArray[ offset_skin + 2 ] = sb1.z;
					skinVertexBArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader

					skinVertexBArray[ offset_skin + 4 ] = sb2.x;
					skinVertexBArray[ offset_skin + 5 ] = sb2.y;
					skinVertexBArray[ offset_skin + 6 ] = sb2.z;
					skinVertexBArray[ offset_skin + 7 ] = 1;

					skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
					skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
					skinVertexBArray[ offset_skin + 10 ] = sb3.z;
					skinVertexBArray[ offset_skin + 11 ] = 1;

					skinVertexBArray[ offset_skin + 12 ]  = sb4.x;
					skinVertexBArray[ offset_skin + 13 ]  = sb4.y;
					skinVertexBArray[ offset_skin + 14 ] = sb4.z;
					skinVertexBArray[ offset_skin + 15 ] = 1;

1329 1330
					offset_skin += 16;

A
alteredq 已提交
1331
				}
1332

1333 1334 1335
				if ( dirtyColors && vertexColorType ) {

					if ( vertexColors.length == 4 && vertexColorType == THREE.VertexColors ) {
1336

1337 1338 1339 1340 1341 1342
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];
						c4 = vertexColors[ 3 ];

					} else {
1343

1344 1345 1346 1347 1348 1349
						c1 = faceColor;
						c2 = faceColor;
						c3 = faceColor;
						c4 = faceColor;

					}
1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361

					colorArray[ offset_color ]     = c1.r;
					colorArray[ offset_color + 1 ] = c1.g;
					colorArray[ offset_color + 2 ] = c1.b;

					colorArray[ offset_color + 3 ] = c2.r;
					colorArray[ offset_color + 4 ] = c2.g;
					colorArray[ offset_color + 5 ] = c2.b;

					colorArray[ offset_color + 6 ] = c3.r;
					colorArray[ offset_color + 7 ] = c3.g;
					colorArray[ offset_color + 8 ] = c3.b;
1362

1363 1364 1365
					colorArray[ offset_color + 9 ]  = c4.r;
					colorArray[ offset_color + 10 ] = c4.g;
					colorArray[ offset_color + 11 ] = c4.b;
1366

1367 1368
					offset_color += 12;

1369 1370
				}

1371
				if ( dirtyTangents && geometry.hasTangents ) {
1372

1373 1374 1375 1376
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
					t4 = vertexTangents[ 3 ];
1377

1378 1379 1380 1381
					tangentArray[ offset_tangent ]     = t1.x;
					tangentArray[ offset_tangent + 1 ] = t1.y;
					tangentArray[ offset_tangent + 2 ] = t1.z;
					tangentArray[ offset_tangent + 3 ] = t1.w;
M
Mr.doob 已提交
1382

1383 1384 1385 1386
					tangentArray[ offset_tangent + 4 ] = t2.x;
					tangentArray[ offset_tangent + 5 ] = t2.y;
					tangentArray[ offset_tangent + 6 ] = t2.z;
					tangentArray[ offset_tangent + 7 ] = t2.w;
M
Mr.doob 已提交
1387

1388 1389 1390 1391
					tangentArray[ offset_tangent + 8 ] = t3.x;
					tangentArray[ offset_tangent + 9 ] = t3.y;
					tangentArray[ offset_tangent + 10 ] = t3.z;
					tangentArray[ offset_tangent + 11 ] = t3.w;
M
Mr.doob 已提交
1392

1393 1394 1395 1396
					tangentArray[ offset_tangent + 12 ] = t4.x;
					tangentArray[ offset_tangent + 13 ] = t4.y;
					tangentArray[ offset_tangent + 14 ] = t4.z;
					tangentArray[ offset_tangent + 15 ] = t4.w;
M
Mr.doob 已提交
1397

1398
					offset_tangent += 16;
M
Mr.doob 已提交
1399

1400
				}
M
Mr.doob 已提交
1401

A
alteredq 已提交
1402
				if( dirtyNormals && normalType ) {
M
Mr.doob 已提交
1403

1404
					if ( vertexNormals.length == 4 && needsSmoothNormals ) {
1405

1406
						for ( i = 0; i < 4; i ++ ) {
1407

1408
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
1409

1410 1411 1412
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
1413

1414
							offset_normal += 3;
M
Mr.doob 已提交
1415

1416
						}
M
Mr.doob 已提交
1417

1418
					} else {
1419

1420
						for ( i = 0; i < 4; i ++ ) {
1421

1422 1423 1424
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1425

1426
							offset_normal += 3;
M
Mr.doob 已提交
1427

1428
						}
M
Mr.doob 已提交
1429 1430

					}
M
Mr.doob 已提交
1431

1432 1433
				}

A
alteredq 已提交
1434
				if ( dirtyUvs && uv !== undefined && uvType ) {
1435

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

1438
						uvi = uv[ i ];
M
Mr.doob 已提交
1439

1440 1441
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1442

1443
						offset_uv += 2;
M
Mr.doob 已提交
1444

M
Mr.doob 已提交
1445
					}
1446 1447

				}
1448

A
alteredq 已提交
1449
				if ( dirtyUvs && uv2 !== undefined && uvType ) {
1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462

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

						uv2i = uv2[ i ];

						uv2Array[ offset_uv2 ]     = uv2i.u;
						uv2Array[ offset_uv2 + 1 ] = uv2i.v;

						offset_uv2 += 2;

					}

				}
M
Mr.doob 已提交
1463

1464
				if ( dirtyElements ) {
M
Mr.doob 已提交
1465

1466
					faceArray[ offset_face ]     = vertexIndex;
1467 1468
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 3;
M
Mr.doob 已提交
1469

1470 1471 1472
					faceArray[ offset_face + 3 ] = vertexIndex + 1;
					faceArray[ offset_face + 4 ] = vertexIndex + 2;
					faceArray[ offset_face + 5 ] = vertexIndex + 3;
M
Mr.doob 已提交
1473

1474
					offset_face += 6;
M
Mr.doob 已提交
1475

1476 1477
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
1478

1479
					lineArray[ offset_line + 2 ] = vertexIndex;
1480
					lineArray[ offset_line + 3 ] = vertexIndex + 3;
M
Mr.doob 已提交
1481

1482 1483
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
1484

1485 1486
					lineArray[ offset_line + 6 ] = vertexIndex + 2;
					lineArray[ offset_line + 7 ] = vertexIndex + 3;
M
Mr.doob 已提交
1487

1488
					offset_line += 8;
M
Mr.doob 已提交
1489

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

1492
				}
M
Mr.doob 已提交
1493

1494
			}
M
Mr.doob 已提交
1495

1496 1497
		}

1498 1499 1500 1501
		if ( obj_edgeFaces ) {

			for ( f = 0, fl = obj_edgeFaces.length; f < fl; f ++ ) {

M
Mikael Emtinger 已提交
1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512
				faceArray[ offset_face ]     = obj_edgeFaces[ f ].a;
				faceArray[ offset_face + 1 ] = obj_edgeFaces[ f ].b;
				faceArray[ offset_face + 2 ] = obj_edgeFaces[ f ].c;

				faceArray[ offset_face + 3 ] = obj_edgeFaces[ f ].a;
				faceArray[ offset_face + 4 ] = obj_edgeFaces[ f ].c;
				faceArray[ offset_face + 5 ] = obj_edgeFaces[ f ].d;

				offset_face += 6;
			}

1513
		}
M
Mikael Emtinger 已提交
1514

1515
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1516

1517
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
1518
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1519

1520
		}
M
Mr.doob 已提交
1521

1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532
		if ( customAttributes ) {
			
			for ( a in customAttributes ) {
				
				customAttribute = customAttributes[ a ];

				if ( customAttribute.dirty ) {

					_gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
					_gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );

1533 1534
					customAttribute.dirty = false;

1535 1536 1537 1538 1539 1540
				}

			}

		}

1541
		if ( dirtyMorphTargets ) {
1542 1543 1544 1545

			for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {

				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ vk ] );
1546
				_gl.bufferData( _gl.ARRAY_BUFFER, morphTargetsArrays[ vk ], hint );
1547

1548 1549 1550
			}
		}

1551
		if ( dirtyColors && offset_color > 0 ) {
1552

1553
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
1554 1555 1556
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}
1557

1558
		if ( dirtyNormals ) {
M
Mr.doob 已提交
1559

1560
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
1561
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
1562

1563 1564
		}

1565
		if ( dirtyTangents && geometry.hasTangents ) {
1566

1567
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
1568
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
M
Mr.doob 已提交
1569

1570
		}
1571

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

1574
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
1575
			_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
M
Mr.doob 已提交
1576

1577
		}
M
Mr.doob 已提交
1578

1579 1580
		if ( dirtyUvs && offset_uv2 > 0 ) {

1581
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
1582 1583 1584 1585
			_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );

		}

1586
		if ( dirtyElements ) {
M
Mr.doob 已提交
1587

1588
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
1589
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
1590

1591
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
1592
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
M
Mr.doob 已提交
1593

1594
		}
1595

1596
		if ( offset_skin > 0 ) {
1597

1598
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
A
alteredq 已提交
1599 1600
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );

1601
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
A
alteredq 已提交
1602 1603
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );

1604
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
A
alteredq 已提交
1605 1606
			_gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );

1607
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
A
alteredq 已提交
1608
			_gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
1609

A
alteredq 已提交
1610
		}
1611 1612

	};
1613

1614
	function setLineBuffers ( geometry, hint ) {
M
Mr.doob 已提交
1615

1616
		var v, c, vertex, offset,
1617 1618 1619 1620
		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,
M
Mr.doob 已提交
1621

1622 1623
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
1624

1625 1626
		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors;
M
Mr.doob 已提交
1627

1628
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1629

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

1632
				vertex = vertices[ v ].position;
M
Mr.doob 已提交
1633

1634
				offset = v * 3;
M
Mr.doob 已提交
1635

1636 1637 1638
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
M
Mr.doob 已提交
1639

1640 1641
			}

1642
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
1643 1644
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

1645
		}
M
Mr.doob 已提交
1646

1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660
		if ( dirtyColors ) {

			for ( c = 0; c < cl; c++ ) {

				color = colors[ c ];

				offset = c * 3;

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

			}

1661
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
1662 1663 1664 1665
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

1666
	};
M
Mr.doob 已提交
1667

1668
	function setRibbonBuffers ( geometry, hint ) {
A
alteredq 已提交
1669 1670

		var v, c, vertex, offset,
1671 1672 1673 1674
		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,
A
alteredq 已提交
1675

1676 1677
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
1678

1679 1680
		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors;
A
alteredq 已提交
1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695

		if ( dirtyVertices ) {

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

				vertex = vertices[ v ].position;

				offset = v * 3;

				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;

			}

1696
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

		}

		if ( dirtyColors ) {

			for ( c = 0; c < cl; c++ ) {

				color = colors[ c ];

				offset = c * 3;

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

			}

1715
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
A
alteredq 已提交
1716 1717 1718 1719 1720
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

	};
1721

1722
	function setParticleBuffers ( geometry, hint, object ) {
1723

A
alteredq 已提交
1724
		var v, c, vertex, offset,
1725 1726
		vertices = geometry.vertices,
		vl = vertices.length,
1727

1728 1729
		colors = geometry.colors,
		cl = colors.length,
1730

1731 1732
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
1733

1734
		sortArray = geometry.__sortArray,
1735

1736 1737 1738
		dirtyVertices = geometry.__dirtyVertices,
		dirtyElements = geometry.__dirtyElements,
		dirtyColors = geometry.__dirtyColors;
1739

1740
		if ( object.sortParticles ) {
1741

1742
			_projScreenMatrix.multiplySelf( object.matrixWorld );
1743

1744 1745 1746
			for ( v = 0; v < vl; v++ ) {

				vertex = vertices[ v ].position;
1747

1748 1749
				_vector3.copy( vertex );
				_projScreenMatrix.multiplyVector3( _vector3 );
1750

1751
				sortArray[ v ] = [ _vector3.z, v ];
1752

1753
			}
1754

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

1757
			for ( v = 0; v < vl; v++ ) {
1758

1759
				vertex = vertices[ sortArray[v][1] ].position;
1760

1761
				offset = v * 3;
1762

1763 1764 1765
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
1766

1767
			}
1768

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

A
alteredq 已提交
1771
				offset = c * 3;
1772

A
alteredq 已提交
1773 1774 1775 1776 1777
				color = colors[ sortArray[c][1] ];

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

1779
			}
1780 1781


1782
		} else {
1783

1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796
			if ( dirtyVertices ) {

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

					vertex = vertices[ v ].position;

					offset = v * 3;

					vertexArray[ offset ]     = vertex.x;
					vertexArray[ offset + 1 ] = vertex.y;
					vertexArray[ offset + 2 ] = vertex.z;

				}
1797 1798

			}
1799

A
alteredq 已提交
1800
			if ( dirtyColors ) {
1801

A
alteredq 已提交
1802 1803 1804 1805 1806 1807 1808 1809 1810 1811
				for ( c = 0; c < cl; c++ ) {

					color = colors[ c ];

					offset = c * 3;

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

1812
				}
1813

A
alteredq 已提交
1814
			}
1815 1816

		}
1817

A
alteredq 已提交
1818
		if ( dirtyVertices || object.sortParticles ) {
1819

1820
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
1821
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
1822

A
alteredq 已提交
1823
		}
1824

A
alteredq 已提交
1825
		if ( dirtyColors || object.sortParticles ) {
1826

1827
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
A
alteredq 已提交
1828
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
1829

A
alteredq 已提交
1830
		}
1831

1832
	};
M
Mr.doob 已提交
1833

1834
	function setMaterialShaders( material, shaders ) {
1835

1836
		material.uniforms = Uniforms.clone( shaders.uniforms );
1837 1838
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
1839

M
Mr.doob 已提交
1840
	};
1841

1842
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
1843

1844
		uniforms.diffuse.value.setRGB( material.color.r, material.color.g, material.color.b );
A
alteredq 已提交
1845 1846
		uniforms.opacity.value = material.opacity;
		uniforms.map.texture = material.map;
1847

1848
		uniforms.lightMap.texture = material.lightMap;
1849

1850
		uniforms.envMap.texture = material.envMap;
A
alteredq 已提交
1851
		uniforms.reflectivity.value = material.reflectivity;
1852
		uniforms.refractionRatio.value = material.refractionRatio;
A
alteredq 已提交
1853
		uniforms.combine.value = material.combine;
1854
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
1855

1856
	};
1857

1858
	function refreshUniformsLine( uniforms, material ) {
1859

1860
		uniforms.diffuse.value.setRGB( material.color.r, material.color.g, material.color.b );
A
alteredq 已提交
1861
		uniforms.opacity.value = material.opacity;
1862 1863

	};
M
Mr.doob 已提交
1864

1865
	function refreshUniformsParticle( uniforms, material ) {
1866

1867
		uniforms.psColor.value.setRGB( material.color.r, material.color.g, material.color.b );
A
alteredq 已提交
1868 1869
		uniforms.opacity.value = material.opacity;
		uniforms.size.value = material.size;
M
Mr.doob 已提交
1870
		uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
A
alteredq 已提交
1871
		uniforms.map.texture = material.map;
1872

A
alteredq 已提交
1873
	};
1874

1875
	function refreshUniformsFog( uniforms, fog ) {
1876

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

A
alteredq 已提交
1879
		if ( fog instanceof THREE.Fog ) {
1880

A
alteredq 已提交
1881 1882
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
1883

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

A
alteredq 已提交
1886
			uniforms.fogDensity.value = fog.density;
1887 1888

		}
1889

1890 1891
	};

1892
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
1893

A
alteredq 已提交
1894 1895 1896 1897 1898
		//uniforms.ambient.value.setHex( material.ambient.hex );
		//uniforms.specular.value.setHex( material.specular.hex );
		uniforms.ambient.value.setRGB( material.ambient.r, material.ambient.g, material.ambient.b );
		uniforms.specular.value.setRGB( material.specular.r, material.specular.g, material.specular.b );
		uniforms.shininess.value = material.shininess;
M
Mr.doob 已提交
1899

1900
	};
M
Mr.doob 已提交
1901 1902


1903
	function refreshUniformsLights( uniforms, lights ) {
M
Mr.doob 已提交
1904

A
alteredq 已提交
1905 1906 1907 1908 1909 1910
		uniforms.enableLighting.value = lights.directional.length + lights.point.length;
		uniforms.ambientLightColor.value = lights.ambient;
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
1911
		uniforms.pointLightDistance.value = lights.point.distances;
M
Mr.doob 已提交
1912

A
alteredq 已提交
1913
	};
M
Mr.doob 已提交
1914

1915
	this.initMaterial = function ( material, lights, fog, object ) {
M
Mr.doob 已提交
1916

M
Mikael Emtinger 已提交
1917
		var u, a, identifiers, i, parameters, maxLightCount, maxBones;
1918

A
alteredq 已提交
1919
		if ( material instanceof THREE.MeshDepthMaterial ) {
1920

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

M
Mikael Emtinger 已提交
1923 1924 1925 1926
		} else if ( material instanceof THREE.ShadowVolumeDynamicMaterial ) {

			setMaterialShaders( material, THREE.ShaderLib[ 'shadowVolumeDynamic' ] );

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

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

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

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

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

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

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

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

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

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

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

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

A
alteredq 已提交
1951
		}
1952

1953
		if ( ! material.program ) {
M
Mr.doob 已提交
1954

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

1958
			maxLightCount = allocateLights( lights, 4 );
1959

1960
			maxBones = allocateBones( object );
M
Mr.doob 已提交
1961

1962 1963 1964 1965 1966 1967 1968 1969
			parameters = {
				map: material.map, envMap: material.envMap, lightMap: material.lightMap, vertexColors: material.vertexColors,
				fog: fog, sizeAttenuation: material.sizeAttenuation,
				skinning: material.skinning,
				morphTargets: material.morphTargets,
				maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
				maxBones: maxBones
			};
M
Mikael Emtinger 已提交
1970

1971
			material.program = buildProgram( material.fragmentShader, material.vertexShader, parameters );
M
Mikael Emtinger 已提交
1972

1973
			// load uniforms
A
alteredq 已提交
1974

1975 1976 1977 1978
			identifiers = [
				'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
				'cameraInverseMatrix', 'boneGlobalMatrices', 'morphTargetInfluences'
			];
M
Mikael Emtinger 已提交
1979

1980

1981
			for ( u in material.uniforms ) {
M
Mr.doob 已提交
1982

1983
				identifiers.push(u);
M
Mikael Emtinger 已提交
1984

1985
			}
1986

1987
			cacheUniformLocations( material.program, identifiers );
1988 1989


1990
			// load attributes
1991

1992 1993 1994 1995
			identifiers = [
				"position", "normal", "uv", "uv2", "tangent", "color",
				"skinVertexA", "skinVertexB", "skinIndex", "skinWeight"
			];
1996

1997
			for ( i = 0; i < this.maxMorphTargets; i++ ) {
1998

1999
				identifiers.push( "morphTarget" + i );
2000

2001
			}
2002

2003
			for ( a in material.attributes ) {
2004

2005
				identifiers.push( a );
2006

2007
			}
2008 2009 2010 2011 2012 2013 2014

			cacheAttributeLocations( material.program, identifiers );

			var attributes = material.program.attributes;

			_gl.enableVertexAttribArray( attributes.position );

2015 2016 2017
			if ( attributes.color >= 0 ) _gl.enableVertexAttribArray( attributes.color );
			if ( attributes.normal >= 0 ) _gl.enableVertexAttribArray( attributes.normal );
			if ( attributes.tangent >= 0 ) _gl.enableVertexAttribArray( attributes.tangent );
2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029

			if ( material.skinning &&
				 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
				 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {

				_gl.enableVertexAttribArray( attributes.skinVertexA );
				_gl.enableVertexAttribArray( attributes.skinVertexB );
				_gl.enableVertexAttribArray( attributes.skinIndex );
				_gl.enableVertexAttribArray( attributes.skinWeight );

			}

2030 2031 2032 2033 2034 2035 2036
			for ( a in material.attributes ) {

				if( attributes[ a ] >= 0 ) _gl.enableVertexAttribArray( attributes[ a ] );

			}


2037 2038 2039 2040
			if ( material.morphTargets ) {

				material.numSupportedMorphTargets = 0;

2041

2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084
				if ( attributes.morphTarget0 >= 0 ) {

					_gl.enableVertexAttribArray( attributes.morphTarget0 );
					material.numSupportedMorphTargets ++;

				}

				if ( attributes.morphTarget1 >= 0 ) {

					_gl.enableVertexAttribArray( attributes.morphTarget1 );
					material.numSupportedMorphTargets ++;

				}

				if ( attributes.morphTarget2 >= 0 ) {

					_gl.enableVertexAttribArray( attributes.morphTarget2 );
					material.numSupportedMorphTargets ++;
				}

				if ( attributes.morphTarget3 >= 0 ) {

					_gl.enableVertexAttribArray( attributes.morphTarget3 );
					material.numSupportedMorphTargets ++;
				}

				if ( attributes.morphTarget4 >= 0 ) {

					_gl.enableVertexAttribArray( attributes.morphTarget4 );
					material.numSupportedMorphTargets ++;

				}

				if ( attributes.morphTarget5 >= 0 ) {

					_gl.enableVertexAttribArray( attributes.morphTarget5 );
					material.numSupportedMorphTargets ++;
				}

				if ( attributes.morphTarget6 >= 0 ) {

					_gl.enableVertexAttribArray( attributes.morphTarget6 );
					material.numSupportedMorphTargets ++;
2085

2086
				}
2087

2088
				if ( attributes.morphTarget7 >= 0 ) {
2089

2090 2091 2092 2093 2094 2095 2096 2097 2098 2099
					_gl.enableVertexAttribArray( attributes.morphTarget7 );
					material.numSupportedMorphTargets ++;

				}

				object.__webglMorphTargetInfluences = new Float32Array( this.maxMorphTargets );

				for ( var i = 0, il = this.maxMorphTargets; i < il; i ++ ) {

					object.__webglMorphTargetInfluences[ i ] = 0;
2100 2101 2102 2103 2104

				}

			}

2105
		}
M
Mr.doob 已提交
2106

2107 2108
		material.__webglProgram = true;

2109
	};
2110

2111
	function setProgram( camera, lights, fog, material, object ) {
2112

2113 2114 2115 2116 2117
		if ( ! material.__webglProgram ) {

			_this.initMaterial( material, lights, fog, object );

		}
M
Mr.doob 已提交
2118

2119
		var program = material.program,
A
alteredq 已提交
2120 2121
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
2122

2123
		if ( program != _currentProgram ) {
M
Mr.doob 已提交
2124

M
Mr.doob 已提交
2125
			_gl.useProgram( program );
2126
			_currentProgram = program;
2127

M
Mr.doob 已提交
2128
		}
2129

2130 2131
		_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );

A
alteredq 已提交
2132
		// refresh uniforms common to several materials
2133 2134

		if ( fog && (
A
alteredq 已提交
2135 2136
			 material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
2137
			 material instanceof THREE.MeshPhongMaterial ||
A
alteredq 已提交
2138
			 material instanceof THREE.LineBasicMaterial ||
2139 2140
			 material instanceof THREE.ParticleBasicMaterial ||
			 material.fog )
A
alteredq 已提交
2141
			) {
2142

A
alteredq 已提交
2143
			refreshUniformsFog( m_uniforms, fog );
2144 2145

		}
M
Mr.doob 已提交
2146

M
Mr.doob 已提交
2147
		if ( material instanceof THREE.MeshPhongMaterial ||
2148 2149
			 material instanceof THREE.MeshLambertMaterial ||
			 material.lights ) {
2150

A
alteredq 已提交
2151
			setupLights( program, lights );
A
alteredq 已提交
2152
			refreshUniformsLights( m_uniforms, _lights );
M
Mr.doob 已提交
2153 2154 2155

		}

2156 2157 2158
		if ( material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
			 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
2159

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

A
alteredq 已提交
2162
		}
M
Mr.doob 已提交
2163

A
alteredq 已提交
2164
		// refresh single material specific uniforms
2165

2166
		if ( material instanceof THREE.LineBasicMaterial ) {
M
Mr.doob 已提交
2167

A
alteredq 已提交
2168
			refreshUniformsLine( m_uniforms, material );
2169

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

A
alteredq 已提交
2172
			refreshUniformsParticle( m_uniforms, material );
2173

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

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

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

2180 2181
			m_uniforms.mNear.value = camera.near;
			m_uniforms.mFar.value = camera.far;
A
alteredq 已提交
2182
			m_uniforms.opacity.value = material.opacity;
2183

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

A
alteredq 已提交
2186
			m_uniforms.opacity.value = material.opacity;
2187
		}
2188

A
alteredq 已提交
2189
		// load common uniforms
2190

A
alteredq 已提交
2191 2192
		loadUniformsGeneric( program, m_uniforms );
		loadUniformsMatrices( p_uniforms, object );
2193

A
alteredq 已提交
2194 2195
		// load material specific uniforms
		// (shader material also gets them for the sake of genericity)
2196

A
alteredq 已提交
2197 2198
		if ( material instanceof THREE.MeshShaderMaterial ||
			 material instanceof THREE.MeshPhongMaterial ||
2199
			 material.envMap ) {
2200

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

2203
		}
2204

A
alteredq 已提交
2205
		if ( material instanceof THREE.MeshShaderMaterial ||
2206
			 material.envMap ||
2207
			 material.skinning ) {
2208

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

A
alteredq 已提交
2211
		}
2212

A
alteredq 已提交
2213 2214
		if ( material instanceof THREE.MeshPhongMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
A
alteredq 已提交
2215
			 material instanceof THREE.MeshShaderMaterial ||
2216 2217
			 material.skinning ) {

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

A
alteredq 已提交
2220
		}
2221

2222 2223
		if ( material instanceof THREE.ShadowVolumeDynamicMaterial ) {

M
Mikael Emtinger 已提交
2224
			var dirLight = m_uniforms.directionalLightDirection.value;
2225

M
Mikael Emtinger 已提交
2226 2227 2228
			dirLight[ 0 ] = -lights.position.x;
			dirLight[ 1 ] = -lights.position.y;
			dirLight[ 2 ] = -lights.position.z;
2229

M
Mikael Emtinger 已提交
2230 2231 2232 2233 2234 2235
			_gl.uniform3fv( p_uniforms.directionalLightDirection, dirLight );
			_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
			_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
		}


2236
		if ( material.skinning ) {
2237

2238
			loadUniformsSkinning( p_uniforms, object );
2239

A
alteredq 已提交
2240
		}
2241

A
alteredq 已提交
2242
		return program;
2243

A
alteredq 已提交
2244
	};
2245

2246
	function renderBuffer ( camera, lights, fog, material, geometryGroup, object ) {
A
alteredq 已提交
2247

2248 2249
		if ( material.opacity == 0 ) return;

2250
		var program, attributes, linewidth, primitives, a, attribute;
A
alteredq 已提交
2251

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

2254
		attributes = program.attributes;
M
Mr.doob 已提交
2255

2256
		// vertices
M
Mr.doob 已提交
2257

2258
		if ( !material.morphTargets ) {
2259 2260

			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
2261
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
2262

2263
		} else {
2264

M
Mikael Emtinger 已提交
2265
			setupMorphTargets( material, geometryGroup, object );
2266

2267 2268
		}

2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289

		// custom attributes

		if ( geometryGroup.__webglCustomAttributes ) {
			
			for( a in geometryGroup.__webglCustomAttributes ) {
				
				if( attributes[ a ] >= 0 ) {
					
					attribute = geometryGroup.__webglCustomAttributes[ a ];
					
					_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
					_gl.vertexAttribPointer( attributes[ a ], attribute.size, _gl.FLOAT, false, 0, 0 );
					
				}
				
			}
			
		}


A
alteredq 已提交
2290 2291 2292 2293
		// colors

		if ( attributes.color >= 0 ) {

2294
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
2295
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
2296 2297 2298

		}

2299
		// normals
M
Mr.doob 已提交
2300

2301
		if ( attributes.normal >= 0 ) {
2302

2303
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
2304
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
2305

2306
		}
2307

2308 2309 2310
		// tangents

		if ( attributes.tangent >= 0 ) {
2311

2312
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
2313
			_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
2314

2315
		}
2316

2317
		// uvs
M
Mr.doob 已提交
2318

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

2321
			if ( geometryGroup.__webglUVBuffer ) {
2322

2323
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
2324
				_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
2325

2326
				_gl.enableVertexAttribArray( attributes.uv );
2327

2328
			} else {
2329

2330
				_gl.disableVertexAttribArray( attributes.uv );
M
Mr.doob 已提交
2331

2332
			}
2333 2334 2335

		}

2336 2337
		if ( attributes.uv2 >= 0 ) {

2338
			if ( geometryGroup.__webglUV2Buffer ) {
2339

2340
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352
				_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );

				_gl.enableVertexAttribArray( attributes.uv2 );

			} else {

				_gl.disableVertexAttribArray( attributes.uv2 );

			}

		}

2353
		if ( material.skinning &&
2354
			 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
A
alteredq 已提交
2355
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
2356

2357
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
A
alteredq 已提交
2358 2359
			_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );

2360
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
A
alteredq 已提交
2361 2362
			_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );

2363
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
A
alteredq 已提交
2364 2365
			_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );

2366
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
A
alteredq 已提交
2367
			_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
2368

A
alteredq 已提交
2369
		}
2370

2371
		// render mesh
M
Mr.doob 已提交
2372

2373
		if ( object instanceof THREE.Mesh ) {
2374

2375
			// wireframe
2376

2377
			if ( material.wireframe ) {
M
Mr.doob 已提交
2378

2379
				_gl.lineWidth( material.wireframeLinewidth );
2380 2381
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
2382

2383
			// triangles
2384

2385
			} else {
2386

2387 2388 2389
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );

2390
			}
2391

2392
		// render lines
2393

2394
		} else if ( object instanceof THREE.Line ) {
2395

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

2398
			_gl.lineWidth( material.linewidth );
2399
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
2400

2401
		// render particles
2402

2403
		} else if ( object instanceof THREE.ParticleSystem ) {
2404

2405
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
2406

A
alteredq 已提交
2407
		// render ribbon
2408

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

2411
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
2412

2413 2414 2415 2416
		}

	};

M
Mikael Emtinger 已提交
2417

M
Mikael Emtinger 已提交
2418
	function setupMorphTargets( material, geometryGroup, object ) {
2419

M
Mikael Emtinger 已提交
2420
		// set base
2421

M
Mikael Emtinger 已提交
2422
		var attributes = material.program.attributes;
2423

M
Mikael Emtinger 已提交
2424
		if(  object.morphTargetBase !== -1 ) {
2425 2426

			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] );
M
Mikael Emtinger 已提交
2427
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
2428

M
Mikael Emtinger 已提交
2429
		} else {
2430 2431

			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
M
Mikael Emtinger 已提交
2432
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
2433

M
Mikael Emtinger 已提交
2434
		}
2435

M
Mikael Emtinger 已提交
2436 2437 2438
		if( object.morphTargetForcedOrder.length ) {

			// set forced order
2439

M
Mikael Emtinger 已提交
2440 2441 2442
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;
2443 2444 2445 2446

			while ( m < material.numSupportedMorphTargets && m < order.length ) {

				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ order[ m ] ] );
M
Mikael Emtinger 已提交
2447 2448
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );

2449 2450 2451 2452
				object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ]];

				m ++;
			}
2453

M
Mikael Emtinger 已提交
2454
		} else {
2455

M
Mikael Emtinger 已提交
2456
			// find most influencing
2457

M
Mikael Emtinger 已提交
2458
			var used = [];
2459
			var candidateInfluence = - 1;
M
Mikael Emtinger 已提交
2460 2461 2462 2463
			var candidate = 0;
			var influences = object.morphTargetInfluences;
			var i, il = influences.length;
			var m = 0;
2464 2465 2466

			if ( object.morphTargetBase !== -1 ) {

M
Mikael Emtinger 已提交
2467
				used[ object.morphTargetBase ] = true;
2468

M
Mikael Emtinger 已提交
2469
			}
2470 2471 2472 2473 2474 2475 2476

			while ( m < material.numSupportedMorphTargets ) {

				for ( i = 0; i < il; i++ ) {

					if ( !used[ i ] && influences[ i ] > candidateInfluence ) {

M
Mikael Emtinger 已提交
2477 2478 2479 2480
						candidate = i;
						candidateInfluence = influences[ candidate ];
					}
				}
2481 2482

				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
M
Mikael Emtinger 已提交
2483
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
2484 2485 2486

				object.__webglMorphTargetInfluences[ m ] = candidateInfluence;

M
Mikael Emtinger 已提交
2487 2488
				used[ candidate ] = 1;
				candidateInfluence = -1;
2489
				m ++;
M
Mikael Emtinger 已提交
2490 2491 2492 2493
			}
		}

		// load updated influences uniform
2494

2495
		_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
M
Mikael Emtinger 已提交
2496 2497 2498
	}


2499
	function renderBufferImmediate ( object, program ) {
2500

2501 2502
		if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
2503

A
alteredq 已提交
2504
		if ( object.hasPos ) {
2505

2506
		  _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglVertexBuffer );
A
alteredq 已提交
2507 2508 2509
		  _gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
		  _gl.enableVertexAttribArray( program.attributes.position );
		  _gl.vertexAttribPointer( program.attributes.position, 3, _gl.FLOAT, false, 0, 0 );
2510

A
alteredq 已提交
2511
		}
2512

A
alteredq 已提交
2513
		if ( object.hasNormal ) {
2514

2515
		  _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
A
alteredq 已提交
2516 2517 2518
		  _gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );
		  _gl.enableVertexAttribArray( program.attributes.normal );
		  _gl.vertexAttribPointer( program.attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
2519

A
alteredq 已提交
2520
		}
2521

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

A
alteredq 已提交
2524
		object.count = 0;
2525

A
alteredq 已提交
2526
	};
2527

2528
	function setObjectFaces ( object ) {
2529

2530
		if ( _oldDoubleSided != object.doubleSided ) {
2531

2532
			if( object.doubleSided ) {
2533

2534
				_gl.disable( _gl.CULL_FACE );
2535

2536
			} else {
2537

A
alteredq 已提交
2538
				_gl.enable( _gl.CULL_FACE );
2539

A
alteredq 已提交
2540
			}
2541

2542
			_oldDoubleSided = object.doubleSided;
2543

2544
		}
2545

2546
		if ( _oldFlipSided != object.flipSided ) {
2547

2548 2549 2550 2551
			if( object.flipSided ) {

				_gl.frontFace( _gl.CW );

2552
			} else {
2553 2554 2555 2556

				_gl.frontFace( _gl.CCW );

			}
2557

2558
			_oldFlipSided = object.flipSided;
2559 2560

		}
2561

2562
	};
2563

2564
	function setDepthTest ( test ) {
2565

A
alteredq 已提交
2566 2567 2568
		if ( _oldDepth != test ) {

			if( test ) {
2569

A
alteredq 已提交
2570
				_gl.enable( _gl.DEPTH_TEST );
2571

A
alteredq 已提交
2572
			} else {
2573

A
alteredq 已提交
2574
				_gl.disable( _gl.DEPTH_TEST );
2575

A
alteredq 已提交
2576
			}
2577

A
alteredq 已提交
2578 2579 2580
			_oldDepth = test;

		}
2581

A
alteredq 已提交
2582
	};
2583

2584
	function computeFrustum ( m ) {
2585 2586 2587 2588 2589 2590 2591 2592 2593

		_frustum[ 0 ].set( m.n41 - m.n11, m.n42 - m.n12, m.n43 - m.n13, m.n44 - m.n14 );
		_frustum[ 1 ].set( m.n41 + m.n11, m.n42 + m.n12, m.n43 + m.n13, m.n44 + m.n14 );
		_frustum[ 2 ].set( m.n41 + m.n21, m.n42 + m.n22, m.n43 + m.n23, m.n44 + m.n24 );
		_frustum[ 3 ].set( m.n41 - m.n21, m.n42 - m.n22, m.n43 - m.n23, m.n44 - m.n24 );
		_frustum[ 4 ].set( m.n41 - m.n31, m.n42 - m.n32, m.n43 - m.n33, m.n44 - m.n34 );
		_frustum[ 5 ].set( m.n41 + m.n31, m.n42 + m.n32, m.n43 + m.n33, m.n44 + m.n34 );

		var i, plane;
2594

A
alteredq 已提交
2595
		for ( i = 0; i < 6; i ++ ) {
2596 2597 2598 2599 2600 2601 2602

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

		}

	};
2603

2604
	function isInFrustum ( object ) {
2605

2606
		var distance, matrix = object.matrixWorld,
2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618
		radius = - object.geometry.boundingSphere.radius * Math.max( object.scale.x, Math.max( object.scale.y, object.scale.z ) );

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

			distance = _frustum[ i ].x * matrix.n14 + _frustum[ i ].y * matrix.n24 + _frustum[ i ].z * matrix.n34 + _frustum[ i ].w;
			if ( distance <= radius ) return false;

		}

		return true;

	};
2619

2620
	function addToFixedArray ( where, what ) {
2621

2622 2623
		where.list[ where.count ] = what;
		where.count += 1;
2624

2625
	};
2626

2627
	function unrollImmediateBufferMaterials ( globject ) {
2628

2629 2630 2631 2632 2633 2634 2635
		var i, l, m, ml, material,
			object = globject.object,
			opaque = globject.opaque,
			transparent = globject.transparent;

		transparent.count = 0;
		opaque.count = 0;
2636

2637 2638 2639
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

			material = object.materials[ m ];
2640
			material.transparent ? addToFixedArray( transparent, material ) : addToFixedArray( opaque, material );
2641

2642
		}
2643

2644
	};
2645

2646
	function unrollBufferMaterials ( globject ) {
2647

2648 2649 2650 2651 2652 2653 2654 2655
		var i, l, m, ml, material, meshMaterial,
			object = globject.object,
			buffer = globject.buffer,
			opaque = globject.opaque,
			transparent = globject.transparent;

		transparent.count = 0;
		opaque.count = 0;
2656

2657 2658 2659 2660 2661 2662 2663 2664 2665
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

			meshMaterial = object.materials[ m ];

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

				for ( i = 0, l = buffer.materials.length; i < l; i++ ) {

					material = buffer.materials[ i ];
2666
					if ( material ) material.transparent ? addToFixedArray( transparent, material ) : addToFixedArray( opaque, material );
2667 2668 2669 2670 2671 2672

				}

			} else {

				material = meshMaterial;
2673
				if ( material ) material.transparent ? addToFixedArray( transparent, material ) : addToFixedArray( opaque, material );
2674

2675 2676 2677
			}

		}
2678

2679
	};
2680 2681


2682
	function painterSort ( a, b ) {
2683

2684
		return b.z - a.z;
2685 2686

	};
2687

2688
	this.render = function ( scene, camera, renderTarget, forceClear ) {
2689

A
alteredq 已提交
2690
		var i, program, opaque, transparent, material,
2691
			o, ol, oil, webglObject, object, buffer,
A
alteredq 已提交
2692
			lights = scene.lights,
N
Nicholas Kinsey 已提交
2693
			fog = scene.fog;
2694

M
Mr.doob 已提交
2695
		camera.matrixAutoUpdate && camera.updateMatrix();
2696

2697
		scene.update( undefined, false, camera );
M
Mr.doob 已提交
2698

M
Mr.doob 已提交
2699
		camera.matrixWorldInverse.flattenToArray( _viewMatrixArray );
2700
		camera.projectionMatrix.flattenToArray( _projectionMatrixArray );
M
Mr.doob 已提交
2701

M
Mr.doob 已提交
2702
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
2703
		computeFrustum( _projScreenMatrix );
2704

A
alteredq 已提交
2705
		this.initWebGLObjects( scene );
M
Mr.doob 已提交
2706

A
alteredq 已提交
2707
		setRenderTarget( renderTarget );
M
Mr.doob 已提交
2708

A
alteredq 已提交
2709
		if ( this.autoClear || forceClear ) {
M
Mr.doob 已提交
2710

2711
			this.clear();
M
Mr.doob 已提交
2712

2713 2714
		}

2715
		// set matrices
2716

2717
		ol = scene.__webglObjects.length;
2718

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

2721 2722
			webglObject = scene.__webglObjects[ o ];
			object = webglObject.object;
M
Mr.doob 已提交
2723

2724
			if ( object.visible ) {
2725 2726

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

2728
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
2729

2730
					setupMatrices( object, camera );
2731

2732
					unrollBufferMaterials( webglObject );
2733

2734
					webglObject.render = true;
2735

2736
					if ( this.sortObjects ) {
2737

2738 2739 2740
						_vector3.copy( object.position );
						_projScreenMatrix.multiplyVector3( _vector3 );

2741
						webglObject.z = _vector3.z;
2742

2743
					}
2744

2745
				} else {
2746

2747
					webglObject.render = false;
2748

2749
				}
2750

2751
			} else {
2752

2753
				webglObject.render = false;
2754

2755
			}
2756

2757
		}
2758

2759
		if ( this.sortObjects ) {
2760

2761
			scene.__webglObjects.sort( painterSort );
2762

2763
		}
2764

2765
		oil = scene.__webglObjectsImmediate.length;
2766

2767
		for ( o = 0; o < oil; o++ ) {
2768

2769 2770
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2771

2772
			if ( object.visible ) {
2773 2774 2775

				if( object.matrixAutoUpdate ) {

2776
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
2777

A
alteredq 已提交
2778
				}
2779

2780
				setupMatrices( object, camera );
2781

2782
				unrollImmediateBufferMaterials( webglObject );
2783

2784
			}
2785

2786
		}
A
alteredq 已提交
2787

2788 2789
		// opaque pass

2790
		setBlending( THREE.NormalBlending );
2791

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

2794
			webglObject = scene.__webglObjects[ o ];
2795

2796
			if ( webglObject.render ) {
2797

2798 2799 2800
				object = webglObject.object;
				buffer = webglObject.buffer;
				opaque = webglObject.opaque;
2801

2802
				setObjectFaces( object );
2803

2804
				for ( i = 0; i < opaque.count; i ++ ) {
2805

2806
					material = opaque.list[ i ];
2807

2808
					setDepthTest( material.depthTest );
A
alteredq 已提交
2809
					renderBuffer( camera, lights, fog, material, buffer, object );
2810

2811
				}
2812 2813 2814 2815 2816

			}

		}

A
alteredq 已提交
2817
		// opaque pass (immediate simulator)
2818

2819
		for ( o = 0; o < oil; o++ ) {
2820

2821 2822
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2823

A
alteredq 已提交
2824
			if ( object.visible ) {
2825

2826
				opaque = webglObject.opaque;
2827

2828
				setObjectFaces( object );
2829

2830
				for( i = 0; i < opaque.count; i++ ) {
2831

2832
					material = opaque.list[ i ];
2833

2834
					setDepthTest( material.depthTest );
2835

A
alteredq 已提交
2836
					program = setProgram( camera, lights, fog, material, object );
2837
					object.render( function( object ) { renderBufferImmediate( object, program ); } );
2838

2839
				}
2840

A
alteredq 已提交
2841
			}
2842

A
alteredq 已提交
2843 2844
		}

2845 2846
		// transparent pass

2847
		for ( o = 0; o < ol; o ++ ) {
2848

2849
			webglObject = scene.__webglObjects[ o ];
2850

2851
			if ( webglObject.render ) {
2852

2853 2854 2855
				object = webglObject.object;
				buffer = webglObject.buffer;
				transparent = webglObject.transparent;
2856

2857
				setObjectFaces( object );
2858

2859
				for ( i = 0; i < transparent.count; i ++ ) {
2860

2861
					material = transparent.list[ i ];
2862

2863
					setBlending( material.blending );
2864
					setDepthTest( material.depthTest );
2865

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

2868
				}
2869

2870
			}
M
Mr.doob 已提交
2871

M
Mr.doob 已提交
2872
		}
M
Mr.doob 已提交
2873

2874
		// transparent pass (immediate simulator)
2875

2876
		for ( o = 0; o < oil; o++ ) {
2877

2878 2879
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2880

2881
			if ( object.visible ) {
2882

2883
				transparent = webglObject.transparent;
2884

2885
				setObjectFaces( object );
2886

2887
				for ( i = 0; i < transparent.count; i ++ ) {
2888

2889
					material = transparent.list[ i ];
2890

2891
					setBlending( material.blending );
2892
					setDepthTest( material.depthTest );
2893

A
alteredq 已提交
2894
					program = setProgram( camera, lights, fog, material, object );
2895
					object.render( function( object ) { renderBufferImmediate( object, program ); } );
2896

2897
				}
2898

2899
			}
2900

2901
		}
2902

M
Mikael Emtinger 已提交
2903
		// render stencil shadows
M
Mikael Emtinger 已提交
2904

2905
		if ( stencil && scene.__webglShadowVolumes.length && scene.lights.length ) {
M
Mikael Emtinger 已提交
2906 2907

			renderStencilShadows( scene );
2908

M
Mikael Emtinger 已提交
2909 2910
		}

2911
		// render lens flares
2912 2913 2914

		if ( scene.__webglLensFlares.length ) {

2915
			renderLensFlares( scene, camera );
2916

2917 2918
		}

M
Mikael Emtinger 已提交
2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941

		// Generate mipmap if we're using any kind of mipmap filtering

		if ( renderTarget && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {

			updateRenderTargetMipmap( renderTarget );

		}

	};



	/*
	 * Stencil Shadows
	 * method: we're rendering the world in light, then the shadow
	 *         volumes into the stencil and last a big darkening 
	 *         quad over the whole thing. This is not how "you're
	 *	       supposed to" do stencil shadows but is much faster
	 * 
	 */

	function renderStencilShadows( scene ) {
2942

M
Mikael Emtinger 已提交
2943 2944 2945 2946 2947 2948 2949
		// setup stencil

		_gl.enable( _gl.POLYGON_OFFSET_FILL );
		_gl.polygonOffset( 0.1, 1.0 );
		_gl.enable( _gl.STENCIL_TEST );
		_gl.depthMask( false );
		_gl.colorMask( false, false, false, false );
2950

M
Mikael Emtinger 已提交
2951 2952 2953 2954
		_gl.stencilFunc( _gl.ALWAYS, 1, 0xFF );
		_gl.stencilOpSeparate( _gl.BACK,  _gl.KEEP, _gl.INCR, _gl.KEEP );
		_gl.stencilOpSeparate( _gl.FRONT, _gl.KEEP, _gl.DECR, _gl.KEEP );

2955

M
Mikael Emtinger 已提交
2956
		// loop through all directional lights
2957

M
Mikael Emtinger 已提交
2958 2959
		var l, ll = scene.lights.length;
		var p;
M
Mikael Emtinger 已提交
2960
		var light, lights = scene.lights;
2961
		var dirLight = [];
M
Mikael Emtinger 已提交
2962
		var object, geometryGroup, material;
2963
		var program;
M
Mikael Emtinger 已提交
2964
		var p_uniforms;
2965 2966
		var m_uniforms;
		var attributes;
M
Mikael Emtinger 已提交
2967
		var o, ol = scene.__webglShadowVolumes.length;
2968 2969 2970

		for ( l = 0; l < ll; l++ ) {

M
Mikael Emtinger 已提交
2971
			light = scene.lights[ l ];
2972 2973

			if ( light instanceof THREE.DirectionalLight ) {
M
Mikael Emtinger 已提交
2974 2975 2976 2977 2978 2979

				dirLight[ 0 ] = -light.position.x;
				dirLight[ 1 ] = -light.position.y;
				dirLight[ 2 ] = -light.position.z;

				// render all volumes
2980 2981 2982

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

M
Mikael Emtinger 已提交
2983 2984 2985
					object        = scene.__webglShadowVolumes[ o ].object;
					geometryGroup = scene.__webglShadowVolumes[ o ].buffer;
					material      = object.materials[ 0 ];
2986

M
Mikael Emtinger 已提交
2987
					if ( !material.program ) _this.initMaterial( material, lights, undefined, object );
2988

M
Mikael Emtinger 已提交
2989 2990
					program = material.program,
		  			p_uniforms = program.uniforms,
2991 2992
					m_uniforms = material.uniforms,
					attributes = program.attributes;
2993

2994
					if ( _currentProgram !== program ) {
2995

M
Mikael Emtinger 已提交
2996
						_gl.useProgram( program );
M
Mikael Emtinger 已提交
2997
						_currentProgram = program;
2998

M
Mikael Emtinger 已提交
2999 3000 3001 3002
						_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );
						_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
						_gl.uniform3fv( p_uniforms.directionalLightDirection, dirLight );
					}
3003 3004


M
Mikael Emtinger 已提交
3005 3006
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
					_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
3007 3008


M
Mikael Emtinger 已提交
3009
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
M
Mikael Emtinger 已提交
3010
					_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
3011

M
Mikael Emtinger 已提交
3012
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
M
Mikael Emtinger 已提交
3013
					_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
3014

M
Mikael Emtinger 已提交
3015
					_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
3016

M
Mikael Emtinger 已提交
3017
					_gl.cullFace( _gl.FRONT );
M
Mikael Emtinger 已提交
3018
					_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3019

M
Mikael Emtinger 已提交
3020
					_gl.cullFace( _gl.BACK );
M
Mikael Emtinger 已提交
3021
					_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3022

M
Mikael Emtinger 已提交
3023
				}
M
Mikael Emtinger 已提交
3024

M
Mikael Emtinger 已提交
3025
			}
M
Mikael Emtinger 已提交
3026

M
Mikael Emtinger 已提交
3027 3028
		}

3029

M
Mikael Emtinger 已提交
3030
		// setup color+stencil
M
Mikael Emtinger 已提交
3031

M
Mikael Emtinger 已提交
3032 3033 3034 3035
		_gl.disable( _gl.POLYGON_OFFSET_FILL );
		_gl.colorMask( true, true, true, true );
		_gl.stencilFunc( _gl.NOTEQUAL, 0, 0xFF );
		_gl.stencilOp( _gl.KEEP, _gl.KEEP, _gl.KEEP );
3036
		_gl.disable( _gl.DEPTH_TEST );
M
Mikael Emtinger 已提交
3037 3038


3039
		// draw darkening polygon
M
Mr.doob 已提交
3040

M
Mikael Emtinger 已提交
3041
		_oldBlending = "";
M
Mikael Emtinger 已提交
3042
		_currentProgram = _stencilShadow.program;
M
Mr.doob 已提交
3043

M
Mikael Emtinger 已提交
3044 3045 3046
		_gl.useProgram( _stencilShadow.program );
		_gl.uniformMatrix4fv( _stencilShadow.projectionLocation, false, _projectionMatrixArray );
		_gl.uniform1f( _stencilShadow.darknessLocation, _stencilShadow.darkness );
3047

M
Mikael Emtinger 已提交
3048 3049 3050
		_gl.bindBuffer( _gl.ARRAY_BUFFER, _stencilShadow.vertexBuffer );
		_gl.vertexAttribPointer( _stencilShadow.vertexLocation, 3, _gl.FLOAT, false, 0, 0 );
		_gl.enableVertexAttribArray( _stencilShadow.vertexLocation );
M
Mr.doob 已提交
3051

M
Mikael Emtinger 已提交
3052 3053
		_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
		_gl.blendEquation( _gl.FUNC_ADD );
3054

M
Mikael Emtinger 已提交
3055
		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _stencilShadow.elementBuffer );
M
Mikael Emtinger 已提交
3056 3057 3058 3059 3060
		_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );


		// disable stencil

3061 3062 3063 3064
		_gl.disable( _gl.STENCIL_TEST );
		_gl.enable( _gl.DEPTH_TEST );
		_gl.depthMask( _currentDepthMask );

M
Mikael Emtinger 已提交
3065
	}
3066

3067 3068 3069 3070 3071 3072 3073 3074 3075 3076
	/*
	 * Render lens flares
	 * Method: renders 16x16 0xff00ff-colored points scattered over the light source area, 
	 *         reads these back and calculates occlusion.  
	 *         Then LensFlare.updateLensFlares() is called to re-position and 
	 *         update transparency of flares. Then they are rendered.
	 * 
	 */

	function renderLensFlares( scene, camera ) {
3077

3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099
		var object, objectZ, geometryGroup, material;
		var o, ol = scene.__webglLensFlares.length;
		var f, fl, flare;
		var tempPosition = new THREE.Vector3();
		var invAspect = _viewportHeight / _viewportWidth;
		var halfViewportWidth = _viewportWidth * 0.5;
		var halfViewportHeight = _viewportHeight * 0.5;
		var size = 16 / _viewportHeight;
		var scale = [ size * invAspect, size ];
		var screenPosition = [ 1, 1, 0 ];
		var screenPositionPixels = [ 1, 1 ];
		var sampleX, sampleY, readBackPixels = _lensFlare.readBackPixels;
		var sampleMidX = 7 * 4;
		var sampleMidY = 7 * 16 * 4;
		var sampleIndex, visibility;
		var uniforms = _lensFlare.uniforms;
		var attributes = _lensFlare.attributes;


		// set lensflare program and reset blending

		_gl.useProgram( _lensFlare.program );
M
Mikael Emtinger 已提交
3100
		_currentProgram = _lensFlare.program;
3101 3102 3103 3104 3105 3106 3107 3108
		_oldBlending = "";


		// loop through all lens flares to update their occlusion and positions
		// setup gl and common used attribs/unforms

		_gl.uniform1i( uniforms.map, 0 );
		_gl.activeTexture( _gl.TEXTURE0 );
3109

3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125
		_gl.uniform1f( uniforms.opacity, 1 );
		_gl.uniform1f( uniforms.rotation, 0 );
		_gl.uniform2fv( uniforms.scale, scale );

		_gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer );
		_gl.vertexAttribPointer( attributes.vertex, 2, _gl.FLOAT, false, 2 * 8, 0 );
		_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 2 * 8, 8 );

		_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );

		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.elementBuffer );

		_gl.disable( _gl.CULL_FACE );
		_gl.depthMask( false );


3126 3127
		for ( o = 0; o < ol; o ++ ) {

3128
			// calc object screen position
3129

3130
			object = scene.__webglLensFlares[ o ].object;
3131

3132
			tempPosition.set( object.matrixWorld.n14, object.matrixWorld.n24, object.matrixWorld.n34 );
3133

3134 3135 3136
			camera.matrixWorldInverse.multiplyVector3( tempPosition );
			objectZ = tempPosition.z;
			camera.projectionMatrix.multiplyVector3( tempPosition );
3137 3138


3139
			// setup arrays for gl programs
3140

3141 3142 3143
			screenPosition[ 0 ] = tempPosition.x;
			screenPosition[ 1 ] = tempPosition.y;
			screenPosition[ 2 ] = tempPosition.z;
3144

3145 3146
			screenPositionPixels[ 0 ] = screenPosition[ 0 ] * halfViewportWidth + halfViewportWidth;
			screenPositionPixels[ 1 ] = screenPosition[ 1 ] * halfViewportHeight + halfViewportHeight;
3147

3148 3149

			// save current RGB to temp texture
3150

3151 3152
			_gl.copyTexSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16 );

3153

3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166
			// render pink quad

			_gl.uniform3fv( uniforms.screenPosition, screenPosition );
			_gl.uniform1i( uniforms.renderPink, 1 );

			_gl.enable( _gl.DEPTH_TEST );

			_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );


			// read back

			try {
3167

3168
				_gl.readPixels( screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16, _gl.RGBA, _gl.UNSIGNED_BYTE, _lensFlare.readBackPixels );
3169 3170 3171

			} catch( error ) {

3172 3173 3174
				console.log( "WebGLRenderer.renderLensFlare: readPixels failed!" );
			}

3175 3176
			if ( _gl.getError() ) {

3177 3178 3179 3180 3181 3182
				console.log( "WebGLRenderer.renderLensFlare: readPixels failed!" );
			}


			// sample read back pixels

3183
			sampleDistance = parseInt( 5 * ( 1 - Math.max( 0, Math.min( -objectZ, camera.far )) / camera.far ), 10 ) + 2;
3184 3185 3186 3187 3188 3189 3190 3191
			sampleX = sampleDistance * 4;
			sampleY = sampleDistance * 4 * 16;

			visibility = 0;

			sampleIndex = ( sampleMidX - sampleX ) + ( sampleMidY - sampleY );	// upper left
			if( _lensFlare.readBackPixels[ sampleIndex + 0 ] === 255 && 
				_lensFlare.readBackPixels[ sampleIndex + 1 ] === 0 &&
3192
				_lensFlare.readBackPixels[ sampleIndex + 2 ] === 255 ) visibility += 0.2;
3193 3194 3195 3196

			sampleIndex = ( sampleMidX + sampleX ) + ( sampleMidY - sampleY );	// upper right
			if( readBackPixels[ sampleIndex + 0 ] === 255 && 
				readBackPixels[ sampleIndex + 1 ] === 0 &&
3197
				readBackPixels[ sampleIndex + 2 ] === 255 ) visibility += 0.2;
3198 3199 3200 3201

			sampleIndex = ( sampleMidX + sampleX ) + ( sampleMidY + sampleY );	// lower right
			if( readBackPixels[ sampleIndex + 0 ] === 255 && 
				readBackPixels[ sampleIndex + 1 ] === 0 &&
3202
				readBackPixels[ sampleIndex + 2 ] === 255 ) visibility += 0.2;
3203 3204 3205 3206

			sampleIndex = ( sampleMidX - sampleX ) + ( sampleMidY + sampleY );	// lower left
			if( readBackPixels[ sampleIndex + 0 ] === 255 && 
				readBackPixels[ sampleIndex + 1 ] === 0 &&
3207
				readBackPixels[ sampleIndex + 2 ] === 255 ) visibility += 0.2;
3208 3209 3210 3211

			sampleIndex = sampleMidX + sampleMidY;								// center
			if( readBackPixels[ sampleIndex + 0 ] === 255 && 
				readBackPixels[ sampleIndex + 1 ] === 0 &&
3212
				readBackPixels[ sampleIndex + 2 ] === 255 ) visibility += 0.2;
3213 3214 3215 3216 3217 3218


			object.positionScreen.x = screenPosition[ 0 ];
			object.positionScreen.y = screenPosition[ 1 ];
			object.positionScreen.z = screenPosition[ 2 ];

3219 3220
			if ( object.customUpdateCallback ) {

3221
				object.customUpdateCallback( visibility, object );
3222

3223
			} else {
3224

3225
				object.updateLensFlares( visibility );
3226

3227 3228 3229 3230
			}


			// restore graphics
3231

3232 3233 3234 3235
			_gl.uniform1i( uniforms.renderPink, 0 );
			_gl.disable( _gl.DEPTH_TEST );
			_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
		}
3236 3237


3238 3239
		// loop through all lens flares and draw their flares
		// setup gl
3240 3241 3242

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

3243 3244
			object = scene.__webglLensFlares[ o ].object;

3245 3246
			for ( f = 0, fl = object.lensFlares.length; f < fl; f ++ ) {

3247
				flare = object.lensFlares[ f ];
3248 3249

				if ( flare.opacity > 0.001 && flare.scale > 0.001 ) {
3250 3251 3252 3253

					screenPosition[ 0 ] = flare.x;
					screenPosition[ 1 ] = flare.y;
					screenPosition[ 2 ] = flare.z;
3254

3255 3256 3257
					size = flare.size * flare.scale / _viewportHeight;
					scale[ 0 ] = size * invAspect;
					scale[ 1 ] = size;
3258

3259 3260 3261 3262
					_gl.uniform3fv( uniforms.screenPosition, screenPosition );
					_gl.uniform1f( uniforms.rotation, flare.rotation );
					_gl.uniform2fv( uniforms.scale, scale );
					_gl.uniform1f( uniforms.opacity, flare.opacity );
3263

3264 3265
					setBlending( flare.blending );
					setTexture( flare.texture, 0 );
3266

3267
					// todo: only draw if loaded
3268

3269
					_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
3270

3271
				}
3272

3273
			}
M
Mr.doob 已提交
3274

3275 3276 3277
		}

		// restore gl
3278

3279 3280
		_gl.enable( _gl.CULL_FACE );
		_gl.enable( _gl.DEPTH_TEST );
3281
		_gl.depthMask( _currentDepthMask );
3282

3283
	}
3284

M
Mr.doob 已提交
3285

3286
	function setupMatrices ( object, camera ) {
3287

3288 3289
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
		THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
3290

3291
	}
3292

A
alteredq 已提交
3293
	this.initWebGLObjects = function ( scene ) {
3294

3295
		if ( !scene.__webglObjects ) {
3296

3297 3298
			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
M
Mikael Emtinger 已提交
3299
			scene.__webglShadowVolumes = [];
M
Mikael Emtinger 已提交
3300
			scene.__webglLensFlares = [];
3301 3302
		}

M
Mr.doob 已提交
3303
		while ( scene.__objectsAdded.length ) {
3304

M
Mr.doob 已提交
3305 3306
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
3307 3308 3309

		}

M
Mr.doob 已提交
3310
		while ( scene.__objectsRemoved.length ) {
3311

M
Mr.doob 已提交
3312 3313
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
3314 3315

		}
3316

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

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

M
Mr.doob 已提交
3321
			updateObject( scene.__webglObjects[ o ].object, scene );
A
alteredq 已提交
3322 3323

		}
3324

M
Mikael Emtinger 已提交
3325 3326 3327 3328 3329
		for ( var o = 0, ol = scene.__webglShadowVolumes.length; o < ol; o ++ ) {

			updateObject( scene.__webglShadowVolumes[ o ].object, scene );

		}
3330

M
Mikael Emtinger 已提交
3331 3332 3333 3334 3335
		for ( var o = 0, ol = scene.__webglLensFlares.length; o < ol; o ++ ) {

			updateObject( scene.__webglLensFlares[ o ].object, scene );

		}
A
alteredq 已提交
3336

3337
	};
3338

3339
	function addObject ( object, scene ) {
3340

3341
		var g, geometry, geometryGroup;
M
Mr.doob 已提交
3342

3343
		if ( object._modelViewMatrix == undefined ) {
3344

3345
			object._modelViewMatrix = new THREE.Matrix4();
3346

3347 3348 3349
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
3350

3351
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3352

3353
		}
A
alteredq 已提交
3354

3355
		if ( object instanceof THREE.Mesh ) {
A
alteredq 已提交
3356

3357 3358 3359 3360 3361 3362 3363 3364
			geometry = object.geometry;

			if ( geometry.geometryGroups == undefined ) {

				sortFacesByMaterial( geometry );

			}

3365
			// create separate VBOs per geometry chunk
A
alteredq 已提交
3366

3367
			for ( g in geometry.geometryGroups ) {
A
alteredq 已提交
3368

3369
				geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
3370

3371
				// initialise VBO on the first access
M
Mr.doob 已提交
3372

3373
				if ( ! geometryGroup.__webglVertexBuffer ) {
M
Mr.doob 已提交
3374

3375 3376
					createMeshBuffers( geometryGroup );
					initMeshBuffers( geometryGroup, object );
A
alteredq 已提交
3377

3378
					geometry.__dirtyVertices = true;
3379
					geometry.__dirtyMorphTargets = true;
3380 3381 3382 3383 3384
					geometry.__dirtyElements = true;
					geometry.__dirtyUvs = true;
					geometry.__dirtyNormals = true;
					geometry.__dirtyTangents = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
3385

3386 3387
					

3388
				}
3389

3390
				// create separate wrapper per each use of VBO
3391

3392 3393
				if ( object instanceof THREE.ShadowVolume ) {

M
Mikael Emtinger 已提交
3394
					addBuffer( scene.__webglShadowVolumes, geometryGroup, object );
3395

M
Mikael Emtinger 已提交
3396
				} else {
3397

M
Mikael Emtinger 已提交
3398
					addBuffer( scene.__webglObjects, geometryGroup, object );
3399

M
Mikael Emtinger 已提交
3400
				}
3401

3402
			}
M
Mr.doob 已提交
3403

M
Mikael Emtinger 已提交
3404
		} else if ( object instanceof THREE.LensFlare ) {
3405

M
Mikael Emtinger 已提交
3406
			addBuffer( scene.__webglLensFlares, undefined, object );
3407

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

3410 3411
			geometry = object.geometry;

3412
			if( ! geometry.__webglVertexBuffer ) {
A
alteredq 已提交
3413 3414 3415 3416 3417 3418 3419 3420 3421

				createRibbonBuffers( geometry );
				initRibbonBuffers( geometry );

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

			}

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

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

3426 3427
			geometry = object.geometry;

3428
			if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
3429

3430 3431
				createLineBuffers( geometry );
				initLineBuffers( geometry );
M
Mr.doob 已提交
3432

3433 3434
				geometry.__dirtyVertices = true;
				geometry.__dirtyColors = true;
M
Mr.doob 已提交
3435

3436
			}
M
Mr.doob 已提交
3437

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

A
alteredq 已提交
3440 3441 3442 3443
		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

3444
			if ( ! geometry.__webglVertexBuffer ) {
A
alteredq 已提交
3445 3446 3447 3448 3449 3450

				createParticleBuffers( geometry );
				initParticleBuffers( geometry );

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

3452
			}
3453

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

A
alteredq 已提交
3456 3457 3458 3459 3460 3461 3462 3463 3464 3465
		} else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes ) {

			addBufferImmediate( scene.__webglObjectsImmediate, object );

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

		}*/

	};

3466
	function updateObject ( object, scene ) {
A
alteredq 已提交
3467

3468
		var g, geometry, geometryGroup, a, customAttributeDirty;
A
alteredq 已提交
3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479

		if ( object instanceof THREE.Mesh ) {

			geometry = object.geometry;

			// check all geometry groups

			for ( g in geometry.geometryGroups ) {

				geometryGroup = geometry.geometryGroups[ g ];

3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491
				customAttributeDirty = false;

				for( a in geometryGroup.__webglCustomAttributes ) {
					
					if( geometryGroup.__webglCustomAttributes[ a ].dirty ) {
						
						customAttributeDirty = true;
						break;
					}
				
				}

3492
				if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
A
alteredq 已提交
3493
					geometry.__dirtyUvs || geometry.__dirtyNormals ||
3494
					geometry.__dirtyColors || geometry.__dirtyTangents || customAttributeDirty ) {
A
alteredq 已提交
3495 3496 3497 3498 3499 3500 3501

					setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW );

				}

			}

3502
			geometry.__dirtyVertices = false;
3503
			geometry.__dirtyMorphTargets = false;
A
alteredq 已提交
3504 3505 3506 3507
			geometry.__dirtyElements = false;
			geometry.__dirtyUvs = false;
			geometry.__dirtyNormals = false;
			geometry.__dirtyTangents = false;
3508
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
3509

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

3512 3513
			geometry = object.geometry;

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

A
alteredq 已提交
3516
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
3517

A
alteredq 已提交
3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529
			}

			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

		} else if ( object instanceof THREE.Line ) {

			geometry = object.geometry;

			if( geometry.__dirtyVertices ||  geometry.__dirtyColors ) {

				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
3530

3531
			}
3532

A
alteredq 已提交
3533 3534 3535 3536 3537 3538 3539
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

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

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

3544
			}
M
Mr.doob 已提交
3545

3546 3547
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
3548

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

A
alteredq 已提交
3551
			// it updates itself in render callback
3552 3553

		} else if ( object instanceof THREE.Particle ) {
3554 3555

		}*/
3556

3557
	};
3558

3559
	function removeObject ( object, scene ) {
M
Mr.doob 已提交
3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576

		var o, ol, zobject;

		for ( o = scene.__webglObjects.length - 1; o >= 0; o-- ) {

			zobject = scene.__webglObjects[ o ].object;

			if ( object == zobject ) {

				scene.__webglObjects.splice( o, 1 );

			}

		}

	};

3577
	function sortFacesByMaterial ( geometry ) {
3578 3579 3580 3581 3582 3583 3584

		// TODO
		// Should optimize by grouping faces with ColorFill / ColorStroke materials
		// which could then use vertex color attributes instead of each being
		// in its separate VBO

		var i, l, f, fl, face, material, materials, vertices, mhash, ghash, hash_map = {};
3585
		var numMorphTargets = geometry.morphTargets !== undefined ? geometry.morphTargets.length : 0;
3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627

		geometry.geometryGroups = {};

		function materialHash( material ) {

			var hash_array = [];

			for ( i = 0, l = material.length; i < l; i++ ) {

				if ( material[ i ] == undefined ) {

					hash_array.push( "undefined" );

				} else {

					hash_array.push( material[ i ].id );

				}

			}

			return hash_array.join( '_' );

		}

		for ( f = 0, fl = geometry.faces.length; f < fl; f++ ) {

			face = geometry.faces[ f ];
			materials = face.materials;

			mhash = materialHash( materials );

			if ( hash_map[ mhash ] == undefined ) {

				hash_map[ mhash ] = { 'hash': mhash, 'counter': 0 };

			}

			ghash = hash_map[ mhash ].hash + '_' + hash_map[ mhash ].counter;

			if ( geometry.geometryGroups[ ghash ] == undefined ) {

3628
				geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640

			}

			vertices = face instanceof THREE.Face3 ? 3 : 4;

			if ( geometry.geometryGroups[ ghash ].vertices + vertices > 65535 ) {

				hash_map[ mhash ].counter += 1;
				ghash = hash_map[ mhash ].hash + '_' + hash_map[ mhash ].counter;

				if ( geometry.geometryGroups[ ghash ] == undefined ) {

3641
					geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653

				}

			}

			geometry.geometryGroups[ ghash ].faces.push( f );
			geometry.geometryGroups[ ghash ].vertices += vertices;

		}

	};

3654
	function addBuffer ( objlist, buffer, object ) {
3655

3656 3657 3658 3659 3660
		objlist.push( {
			buffer: buffer, object: object,
			opaque: { list: [], count: 0 },
			transparent: { list: [], count: 0 }
		} );
M
Mr.doob 已提交
3661

3662
	};
3663

3664
	function addBufferImmediate ( objlist, object ) {
3665

3666 3667 3668 3669 3670
		objlist.push( {
			object: object,
			opaque: { list: [], count: 0 },
			transparent: { list: [], count: 0 }
		} );
3671

3672
	};
3673

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

3676
		if ( cullFace ) {
M
Mr.doob 已提交
3677

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

3680
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
3681

3682
			} else {
M
Mr.doob 已提交
3683

3684
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
3685

3686
			}
M
Mr.doob 已提交
3687

3688
			if( cullFace == "back" ) {
M
Mr.doob 已提交
3689

3690
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
3691

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

3694
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
3695

3696
			} else {
M
Mr.doob 已提交
3697

3698
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
3699

3700
			}
M
Mr.doob 已提交
3701

3702
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
3703

3704
		} else {
M
Mr.doob 已提交
3705

3706
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
3707

3708 3709 3710
		}

	};
N
Nicolas Garcia Belmonte 已提交
3711

3712
	this.supportsVertexTextures = function () {
3713

3714
		return maxVertexTextures() > 0;
3715

3716
	};
3717

3718
	function maxVertexTextures () {
3719

3720 3721 3722
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
3723

M
Mikael Emtinger 已提交
3724
	function initGL ( antialias, clearColor, clearAlpha, stencil ) {
N
Nicolas Garcia Belmonte 已提交
3725 3726 3727

		try {

M
Mikael Emtinger 已提交
3728
			if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { antialias: antialias, stencil: stencil } ) ) ) {
N
Nicolas Garcia Belmonte 已提交
3729

3730
				throw 'Error creating WebGL context.';
N
Nicolas Garcia Belmonte 已提交
3731

3732 3733 3734
			}

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

3736
			console.error( e );
N
Nicolas Garcia Belmonte 已提交
3737 3738 3739 3740 3741 3742 3743 3744 3745

		}

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

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

3746 3747
		_gl.frontFace( _gl.CCW );
		_gl.cullFace( _gl.BACK );
3748
		_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
3749

N
Nicolas Garcia Belmonte 已提交
3750
		_gl.enable( _gl.BLEND );
3751 3752 3753
		_gl.blendEquation( _gl.FUNC_ADD );
		_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA );

3754
		_gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
3755

3756 3757
		// _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, true );

A
alteredq 已提交
3758
		_cullEnabled = true;
N
Nicolas Garcia Belmonte 已提交
3759

3760
	};
M
Mr.doob 已提交
3761

3762
	function buildProgram ( fragmentShader, vertexShader, parameters ) {
3763

M
Mr.doob 已提交
3764
		var program = _gl.createProgram(),
M
Mr.doob 已提交
3765

M
Mr.doob 已提交
3766 3767 3768 3769
		prefix_fragment = [
			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",
M
Mr.doob 已提交
3770

3771 3772
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
3773

3774 3775
			parameters.fog ? "#define USE_FOG" : "",
			parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "",
3776

3777
			parameters.map ? "#define USE_MAP" : "",
3778 3779 3780
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
3781

3782
			"uniform mat4 viewMatrix;",
3783
			"uniform vec3 cameraPosition;",
M
Mr.doob 已提交
3784 3785
			""
		].join("\n"),
3786

M
Mr.doob 已提交
3787
		prefix_vertex = [
3788
			maxVertexTextures() > 0 ? "#define VERTEX_TEXTURES" : "",
3789

3790 3791 3792
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

3793 3794
			"#define MAX_BONES " + parameters.maxBones,

3795
			parameters.map ? "#define USE_MAP" : "",
3796 3797 3798
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
3799
			parameters.skinning ? "#define USE_SKINNING" : "",
3800
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
3801

3802

3803 3804
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
3805 3806 3807
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
3808 3809
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
3810
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
3811 3812 3813

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
3814 3815 3816
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
3817
			"attribute vec2 uv2;",
3818

3819
			"#ifdef USE_COLOR",
3820

3821
				"attribute vec3 color;",
3822

3823 3824
			"#endif",

3825
			"#ifdef USE_MORPHTARGETS",
3826

3827 3828 3829 3830 3831 3832 3833 3834
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
				"attribute vec3 morphTarget4;",
				"attribute vec3 morphTarget5;",
				"attribute vec3 morphTarget6;",
				"attribute vec3 morphTarget7;",
3835

3836 3837 3838
			"#endif",

			"#ifdef USE_SKINNING",
3839

3840 3841 3842 3843
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
3844

3845
			"#endif",
3846

M
Mr.doob 已提交
3847 3848
			""
		].join("\n");
3849

3850 3851
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
3852

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

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

3857
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
3858

N
Nicolas Garcia Belmonte 已提交
3859
		}
3860

3861 3862
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
3863

M
Mr.doob 已提交
3864
		program.uniforms = {};
3865
		program.attributes = {};
M
Mr.doob 已提交
3866

M
Mr.doob 已提交
3867
		return program;
M
Mr.doob 已提交
3868

M
Mr.doob 已提交
3869
	};
M
Mr.doob 已提交
3870

3871
	function loadUniformsSkinning ( uniforms, object ) {
3872

M
Mr.doob 已提交
3873
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray );
A
alteredq 已提交
3874
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
3875

3876
	};
3877

3878

3879
	function loadUniformsMatrices ( uniforms, object ) {
3880

A
alteredq 已提交
3881 3882 3883 3884
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
		_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );

	};
3885

3886
	function loadUniformsGeneric ( program, uniforms ) {
M
Mr.doob 已提交
3887

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

M
Mr.doob 已提交
3890
		for( u in uniforms ) {
M
Mr.doob 已提交
3891

3892 3893
			location = program.uniforms[u];
			if ( !location ) continue;
M
Mr.doob 已提交
3894

3895
			uniform = uniforms[u];
M
Mr.doob 已提交
3896

3897 3898
			type = uniform.type;
			value = uniform.value;
M
Mr.doob 已提交
3899

M
Mr.doob 已提交
3900
			if( type == "i" ) {
M
Mr.doob 已提交
3901

M
Mr.doob 已提交
3902
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
3903

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

M
Mr.doob 已提交
3906
				_gl.uniform1f( location, value );
3907

A
alteredq 已提交
3908 3909 3910
			} else if( type == "fv1" ) {

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

3912 3913 3914 3915
			} else if( type == "fv" ) {

				_gl.uniform3fv( location, value );

3916 3917 3918 3919
			} else if( type == "v2" ) {

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

3920 3921 3922
			} else if( type == "v3" ) {

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

3924 3925 3926 3927
			} else if( type == "v4" ) {

				_gl.uniform4f( location, value.x, value.y, value.z, value.w );

3928 3929 3930
			} else if( type == "c" ) {

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

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

M
Mr.doob 已提交
3934
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
3935

3936
				texture = uniform.texture;
M
Mr.doob 已提交
3937

3938
				if ( !texture ) continue;
M
Mr.doob 已提交
3939

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

3942
					setCubeTexture( texture, value );
M
Mr.doob 已提交
3943

3944
				} else {
M
Mr.doob 已提交
3945

3946
					setTexture( texture, value );
M
Mr.doob 已提交
3947

3948
				}
M
Mr.doob 已提交
3949

3950
			}
M
Mr.doob 已提交
3951

3952
		}
M
Mr.doob 已提交
3953

3954
	};
M
Mr.doob 已提交
3955

3956
	function setBlending ( blending ) {
A
alteredq 已提交
3957 3958

		if ( blending != _oldBlending ) {
3959

A
alteredq 已提交
3960 3961 3962 3963 3964
			switch ( blending ) {

				case THREE.AdditiveBlending:

					_gl.blendEquation( _gl.FUNC_ADD );
3965
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
A
alteredq 已提交
3966 3967 3968 3969 3970

					break;

				case THREE.SubtractiveBlending:

3971 3972 3973 3974
					// TODO: Find blendFuncSeparate() combination

					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
A
alteredq 已提交
3975 3976 3977

					break;

3978 3979 3980
				case THREE.MultiplyBlending:

					// TODO: Find blendFuncSeparate() combination
A
alteredq 已提交
3981 3982

					_gl.blendEquation( _gl.FUNC_ADD );
3983
					_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
A
alteredq 已提交
3984 3985 3986 3987 3988

					break;

				default:

3989 3990
					_gl.blendEquationSeparate( _gl.FUNC_ADD, _gl.FUNC_ADD );
					_gl.blendFuncSeparate( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA, _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
A
alteredq 已提交
3991 3992

					break;
3993

A
alteredq 已提交
3994
			}
3995

A
alteredq 已提交
3996
			_oldBlending = blending;
3997

A
alteredq 已提交
3998 3999 4000
		}

	};
4001

4002
	function setTextureParameters ( textureType, texture, image ) {
4003

4004
		if ( isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ) ) {
M
Mr.doob 已提交
4005

4006 4007
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
4008

4009 4010
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
4011

4012
			_gl.generateMipmap( textureType );
M
Mr.doob 已提交
4013

4014
		} else {
M
Mr.doob 已提交
4015

4016 4017
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
4018

4019 4020
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
4021

4022
		}
M
Mr.doob 已提交
4023

4024
	};
4025

4026
	function setTexture ( texture, slot ) {
4027

4028
		if ( texture.needsUpdate ) {
A
alteredq 已提交
4029

4030
			if ( !texture.__webglInit ) {
M
Mr.doob 已提交
4031

4032
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
4033

4034
				_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
4035
				_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
4036

4037
				texture.__webglInit = true;
M
Mr.doob 已提交
4038

A
alteredq 已提交
4039
			} else {
M
Mr.doob 已提交
4040

4041
				_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
A
alteredq 已提交
4042
				_gl.texSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
4043 4044 4045

			}

4046 4047
			setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );
			_gl.bindTexture( _gl.TEXTURE_2D, null );
4048

A
alteredq 已提交
4049
			texture.needsUpdate = false;
4050 4051 4052 4053

		}

		_gl.activeTexture( _gl.TEXTURE0 + slot );
4054
		_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
M
Mr.doob 已提交
4055

4056
	};
M
Mr.doob 已提交
4057

4058
	function setCubeTexture ( texture, slot ) {
4059 4060 4061 4062 4063

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

			if ( texture.needsUpdate ) {

4064 4065 4066
				if ( !texture.__webglInit ) {

					texture.image.__webglTextureCube = _gl.createTexture();
4067

4068
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4069

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

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

4074
					}
4075 4076

					texture.__webglInit = true;
4077 4078 4079

				} else {

4080
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4081

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

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

4086
					}
4087 4088 4089

				}

4090
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[0] );
4091 4092 4093
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

				texture.needsUpdate = false;
4094

4095 4096 4097
			}

			_gl.activeTexture( _gl.TEXTURE0 + slot );
4098
			_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4099 4100 4101 4102 4103

		}

	};

4104
	function setRenderTarget ( renderTexture ) {
4105

4106
		if ( renderTexture && !renderTexture.__webglFramebuffer ) {
M
Mr.doob 已提交
4107

4108 4109 4110
			renderTexture.__webglFramebuffer = _gl.createFramebuffer();
			renderTexture.__webglRenderbuffer = _gl.createRenderbuffer();
			renderTexture.__webglTexture = _gl.createTexture();
4111 4112

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

4114
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
4115 4116 4117
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTexture.width, renderTexture.height );

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

4119
			_gl.bindTexture( _gl.TEXTURE_2D, renderTexture.__webglTexture );
4120 4121 4122 4123
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, paramThreeToGL( renderTexture.wrapS ) );
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, paramThreeToGL( renderTexture.wrapT ) );
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( renderTexture.magFilter ) );
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( renderTexture.minFilter ) );
4124
			_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTexture.format ), renderTexture.width, renderTexture.height, 0, paramThreeToGL( renderTexture.format ), paramThreeToGL( renderTexture.type ), null );
4125 4126

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

4128 4129 4130
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTexture.__webglFramebuffer );
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, renderTexture.__webglTexture, 0 );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
4131 4132

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

4134 4135 4136
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
4137

4138 4139
		}

4140
		var framebuffer, width, height;
M
Mr.doob 已提交
4141

4142
		if ( renderTexture ) {
M
Mr.doob 已提交
4143

4144
			framebuffer = renderTexture.__webglFramebuffer;
4145 4146
			width = renderTexture.width;
			height = renderTexture.height;
M
Mr.doob 已提交
4147

4148
		} else {
M
Mr.doob 已提交
4149

4150
			framebuffer = null;
4151 4152
			width = _viewportWidth;
			height = _viewportHeight;
M
Mr.doob 已提交
4153

4154
		}
M
Mr.doob 已提交
4155

4156
		if( framebuffer != _currentFramebuffer ) {
M
Mr.doob 已提交
4157

4158
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
4159
			_gl.viewport( _viewportX, _viewportY, width, height );
M
Mr.doob 已提交
4160

4161
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
4162

4163
		}
4164

4165
	};
M
Mr.doob 已提交
4166

4167
	function updateRenderTargetMipmap ( renderTarget ) {
M
Mr.doob 已提交
4168

4169
		_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
4170 4171
		_gl.generateMipmap( _gl.TEXTURE_2D );
		_gl.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
4172 4173

	};
4174

4175
	function cacheUniformLocations ( program, identifiers ) {
M
Mr.doob 已提交
4176

M
Mr.doob 已提交
4177
		var i, l, id;
M
Mr.doob 已提交
4178

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

4181 4182
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
4183

M
Mr.doob 已提交
4184
		}
M
Mr.doob 已提交
4185

M
Mr.doob 已提交
4186
	};
M
Mr.doob 已提交
4187

4188
	function cacheAttributeLocations ( program, identifiers ) {
4189

4190
		var i, l, id;
M
Mr.doob 已提交
4191

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

4194 4195
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
4196

4197
		}
M
Mr.doob 已提交
4198

M
Mr.doob 已提交
4199
	};
M
Mr.doob 已提交
4200

4201
	function getShader ( type, string ) {
N
Nicolas Garcia Belmonte 已提交
4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219

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

4220
			console.error( _gl.getShaderInfoLog( shader ) );
4221
			console.error( string );
N
Nicolas Garcia Belmonte 已提交
4222 4223 4224 4225 4226
			return null;

		}

		return shader;
M
Mr.doob 已提交
4227

4228
	};
N
Nicolas Garcia Belmonte 已提交
4229

4230
	// fallback filters for non-power-of-2 textures
4231

4232
	function filterFallback ( f ) {
4233

4234 4235 4236 4237 4238 4239 4240 4241
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mikael Emtinger 已提交
4242 4243 4244 4245
			case THREE.LinearMipMapLinearFilter: 
			default:
				
				return _gl.LINEAR; break;
4246 4247 4248 4249 4250

		}
		
	};
	
4251
	function paramThreeToGL ( p ) {
M
Mr.doob 已提交
4252

4253
		switch ( p ) {
M
Mr.doob 已提交
4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266

			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;

4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280
			case THREE.ByteType: return _gl.BYTE; break;
			case THREE.UnsignedByteType: return _gl.UNSIGNED_BYTE; break;
			case THREE.ShortType: return _gl.SHORT; break;
			case THREE.UnsignedShortType: return _gl.UNSIGNED_SHORT; break;
			case THREE.IntType: return _gl.INT; break;
			case THREE.UnsignedShortType: return _gl.UNSIGNED_INT; break;
			case THREE.FloatType: return _gl.FLOAT; break;

			case THREE.AlphaFormat: return _gl.ALPHA; break;
			case THREE.RGBFormat: return _gl.RGB; break;
			case THREE.RGBAFormat: return _gl.RGBA; break;
			case THREE.LuminanceFormat: return _gl.LUMINANCE; break;
			case THREE.LuminanceAlphaFormat: return _gl.LUMINANCE_ALPHA; break;

4281
		}
M
Mr.doob 已提交
4282

4283
		return 0;
M
Mr.doob 已提交
4284

4285 4286
	};

4287
	function isPowerOfTwo ( value ) {
4288 4289 4290 4291 4292

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

	};

4293
	function materialNeedsSmoothNormals ( material ) {
4294 4295 4296

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

4297
	};
M
Mr.doob 已提交
4298

4299
	function bufferNeedsSmoothNormals ( geometryGroup, object ) {
M
Mr.doob 已提交
4300

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

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

M
Mr.doob 已提交
4305
			meshMaterial = object.materials[ m ];
4306 4307 4308

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

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

4311
					if ( materialNeedsSmoothNormals( geometryGroup.materials[ i ] ) ) {
4312

4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333
						needsSmoothNormals = true;
						break;

					}

				}

			} else {

				if ( materialNeedsSmoothNormals( meshMaterial ) ) {

					needsSmoothNormals = true;
					break;

				}

			}

			if ( needsSmoothNormals ) break;

		}
M
Mr.doob 已提交
4334

4335
		return needsSmoothNormals;
M
Mr.doob 已提交
4336

4337
	};
M
Mr.doob 已提交
4338

4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375
	function unrollGroupMaterials( geometryGroup, object ) {
		
		var m, ml, i, il,
			material, meshMaterial,
			materials = [];
		
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

			meshMaterial = object.materials[ m ];

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

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

					material = geometryGroup.materials[ i ];

					if ( material ) {
						
						materials.push( material );

					}

				}

			} else {

				material = meshMaterial;

				if ( material ) {

					materials.push( material );

				}

			}

		}
4376

4377 4378 4379
		return materials;

	};
4380

4381
	function bufferGuessVertexColorType ( materials, geometryGroup, object ) {
4382

4383
		var i, m, ml = materials.length;
4384

4385
		// use vertexColor type from the first material in unrolled materials
4386

4387
		for ( i = 0; i < ml; i++ ) {
4388

4389
			m = materials[ i ];
4390

4391
			if ( m.vertexColors ) {
4392

4393 4394 4395
				return m.vertexColors;

			}
4396

4397
		}
4398

4399
		return false;
4400

4401 4402 4403
	};

	function bufferGuessNormalType ( materials, geometryGroup, object ) {
4404

4405
		var i, m, ml = materials.length;
4406

4407
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
4408

4409
		for ( i = 0; i < ml; i++ ) {
4410

4411
			m = materials[ i ];
4412

A
alteredq 已提交
4413
			if ( ( m instanceof THREE.MeshBasicMaterial && !m.envMap ) || m instanceof THREE.MeshDepthMaterial ) continue;
4414

4415
			if ( materialNeedsSmoothNormals( m ) ) {
4416

4417 4418 4419 4420 4421 4422 4423 4424 4425
				return THREE.SmoothShading;

			} else {

				return THREE.FlatShading;

			}

		}
4426

4427
		return false;
4428

4429 4430 4431
	};

	function bufferGuessUVType ( materials, geometryGroup, object ) {
4432

4433
		var i, m, ml = materials.length;
4434

4435
		// material must use some texture to require uvs
4436

4437
		for ( i = 0; i < ml; i++ ) {
4438

4439
			m = materials[ i ];
4440

A
alteredq 已提交
4441
			if ( m.map || m.lightMap || m instanceof THREE.MeshShaderMaterial ) {
4442

4443
				return true;
4444

4445
			}
4446

4447
		}
4448

4449
		return false;
4450

4451
	};
4452

4453
	function allocateBones ( object ) {
4454

4455 4456 4457 4458 4459 4460 4461
		// default for when object is not specified
		// ( for example when prebuilding shader
		//   to be used with multiple objects )
		//
		// 	- leave some extra space for other uniforms
		//  - limit here is ANGLE's 254 max uniform vectors
		//    (up to 54 should be safe)
4462

4463
		var maxBones = 50;
4464

4465
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
4466

4467 4468 4469 4470 4471
			maxBones = object.bones.length;

		}

		return maxBones;
4472

4473
	};
4474

4475
	function allocateLights ( lights, maxLights ) {
4476

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

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

4482
			light = lights[ l ];
4483

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

4487
		}
4488

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

4491 4492
			maxDirLights = dirLights;
			maxPointLights = pointLights;
4493

4494
		} else {
4495

4496 4497
			maxDirLights = Math.ceil( maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = maxLights - maxDirLights;
4498 4499 4500

		}

4501
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
4502 4503

	};
M
Mr.doob 已提交
4504

A
alteredq 已提交
4505
	/* DEBUG
4506
	function getGLParams() {
M
Mr.doob 已提交
4507

4508
		var params  = {
M
Mr.doob 已提交
4509

4510 4511
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
4512

4513 4514 4515
			'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 已提交
4516

4517 4518 4519
			'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 已提交
4520

4521 4522
		return params;
	};
M
Mr.doob 已提交
4523

4524
	function dumpObject( obj ) {
M
Mr.doob 已提交
4525

4526 4527
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
4528

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

4531
		}
M
Mr.doob 已提交
4532

4533 4534
		return str;
	}
A
alteredq 已提交
4535
	*/
4536
};
4537